Files
open-cluster-management/pkg/addon/manager.go
Yang Le f6dec25bdf
Some checks failed
Scorecard supply-chain security / Scorecard analysis (push) Failing after 5m33s
Post / images (amd64, addon-manager) (push) Failing after 5m56s
Post / images (amd64, placement) (push) Failing after 55s
Post / images (amd64, registration-operator) (push) Failing after 46s
Post / images (amd64, work) (push) Failing after 44s
Post / images (arm64, addon-manager) (push) Failing after 46s
Post / images (arm64, placement) (push) Failing after 44s
Post / images (arm64, registration) (push) Failing after 47s
Post / images (arm64, registration-operator) (push) Failing after 45s
Post / images (amd64, registration) (push) Failing after 5m37s
Post / images (arm64, work) (push) Failing after 46s
Post / image manifest (addon-manager) (push) Has been skipped
Post / image manifest (placement) (push) Has been skipped
Post / image manifest (registration) (push) Has been skipped
Post / image manifest (registration-operator) (push) Has been skipped
Post / image manifest (work) (push) Has been skipped
Post / trigger clusteradm e2e (push) Has been skipped
Post / coverage (push) Failing after 41m15s
Close stale issues and PRs / stale (push) Successful in 7s
add contoller to support token infrastructure (#1340)
Signed-off-by: Yang Le <yangle@redhat.com>
2026-01-27 13:06:21 +00:00

241 lines
8.6 KiB
Go

package addon
import (
"context"
"os"
"time"
"github.com/openshift/library-go/pkg/controller/controllercmd"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/dynamic/dynamicinformer"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
"k8s.io/klog/v2"
"open-cluster-management.io/addon-framework/pkg/index"
"open-cluster-management.io/addon-framework/pkg/utils"
addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
addonv1alpha1client "open-cluster-management.io/api/client/addon/clientset/versioned"
addoninformers "open-cluster-management.io/api/client/addon/informers/externalversions"
clusterclientset "open-cluster-management.io/api/client/cluster/clientset/versioned"
clusterinformers "open-cluster-management.io/api/client/cluster/informers/externalversions"
workv1client "open-cluster-management.io/api/client/work/clientset/versioned"
workv1informers "open-cluster-management.io/api/client/work/informers/externalversions"
"open-cluster-management.io/ocm/pkg/addon/controllers/addonconfiguration"
"open-cluster-management.io/ocm/pkg/addon/controllers/addonmanagement"
"open-cluster-management.io/ocm/pkg/addon/controllers/addonowner"
"open-cluster-management.io/ocm/pkg/addon/controllers/addonprogressing"
"open-cluster-management.io/ocm/pkg/addon/controllers/addontemplate"
"open-cluster-management.io/ocm/pkg/addon/controllers/addontokeninfra"
"open-cluster-management.io/ocm/pkg/addon/controllers/cmainstallprogression"
addonindex "open-cluster-management.io/ocm/pkg/addon/index"
)
func RunManager(ctx context.Context, controllerContext *controllercmd.ControllerContext) error {
// setting up contextual logger
logger := klog.NewKlogr()
podName := os.Getenv("POD_NAME")
if podName != "" {
logger = logger.WithValues("podName", podName)
}
ctx = klog.NewContext(ctx, logger)
kubeConfig := controllerContext.KubeConfig
hubKubeClient, err := kubernetes.NewForConfig(kubeConfig)
if err != nil {
return err
}
hubClusterClient, err := clusterclientset.NewForConfig(kubeConfig)
if err != nil {
return err
}
addonClient, err := addonv1alpha1client.NewForConfig(kubeConfig)
if err != nil {
return err
}
workClient, err := workv1client.NewForConfig(kubeConfig)
if err != nil {
return err
}
dynamicClient, err := dynamic.NewForConfig(kubeConfig)
if err != nil {
return err
}
clusterInformerFactory := clusterinformers.NewSharedInformerFactory(hubClusterClient, 30*time.Minute)
addonInformerFactory := addoninformers.NewSharedInformerFactory(addonClient, 10*time.Minute)
workInformers := workv1informers.NewSharedInformerFactoryWithOptions(workClient, 10*time.Minute,
workv1informers.WithTweakListOptions(func(listOptions *metav1.ListOptions) {
selector := &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: addonv1alpha1.AddonLabelKey,
Operator: metav1.LabelSelectorOpExists,
},
},
}
listOptions.LabelSelector = metav1.FormatLabelSelector(selector)
}),
)
dynamicInformers := dynamicinformer.NewDynamicSharedInformerFactory(dynamicClient, 10*time.Minute)
// Create filtered informers for token infrastructure resources
tokenInfraInformers := informers.NewSharedInformerFactoryWithOptions(hubKubeClient, 10*time.Minute,
informers.WithTweakListOptions(func(listOptions *metav1.ListOptions) {
selector := &metav1.LabelSelector{
MatchLabels: map[string]string{
"addon.open-cluster-management.io/token-infrastructure": "true",
},
}
listOptions.LabelSelector = metav1.FormatLabelSelector(selector)
}),
)
return RunControllerManagerWithInformers(
ctx, controllerContext,
hubKubeClient,
addonClient,
workClient,
clusterInformerFactory,
addonInformerFactory,
workInformers,
dynamicInformers,
tokenInfraInformers,
)
}
func RunControllerManagerWithInformers(
ctx context.Context,
controllerContext *controllercmd.ControllerContext,
hubKubeClient kubernetes.Interface,
hubAddOnClient addonv1alpha1client.Interface,
hubWorkClient workv1client.Interface,
clusterInformers clusterinformers.SharedInformerFactory,
addonInformers addoninformers.SharedInformerFactory,
workinformers workv1informers.SharedInformerFactory,
dynamicInformers dynamicinformer.DynamicSharedInformerFactory,
tokenInfraInformers informers.SharedInformerFactory,
) error {
// addonDeployController
err := workinformers.Work().V1().ManifestWorks().Informer().AddIndexers(
cache.Indexers{
index.ManifestWorkByAddon: index.IndexManifestWorkByAddon,
index.ManifestWorkByHostedAddon: index.IndexManifestWorkByHostedAddon,
index.ManifestWorkHookByHostedAddon: index.IndexManifestWorkHookByHostedAddon,
},
)
if err != nil {
return err
}
err = addonInformers.Addon().V1alpha1().ManagedClusterAddOns().Informer().AddIndexers(
cache.Indexers{
addonindex.ManagedClusterAddonByName: addonindex.IndexManagedClusterAddonByName, // addonConfigurationController, addonManagementController
index.ManagedClusterAddonByNamespace: index.IndexManagedClusterAddonByNamespace, // agentDeployController
index.AddonByConfig: index.IndexAddonByConfig, // addonConfigController
},
)
if err != nil {
return err
}
// managementAddonConfigController
err = addonInformers.Addon().V1alpha1().ClusterManagementAddOns().Informer().AddIndexers(
cache.Indexers{
addonindex.ClusterManagementAddonByPlacement: addonindex.IndexClusterManagementAddonByPlacement, // addonConfigurationController, addonManagementController
index.ClusterManagementAddonByConfig: index.IndexClusterManagementAddonByConfig, // cmaConfigController
})
if err != nil {
return err
}
addonManagementController := addonmanagement.NewAddonManagementController(
hubAddOnClient,
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
addonInformers.Addon().V1alpha1().ClusterManagementAddOns(),
clusterInformers.Cluster().V1beta1().Placements(),
clusterInformers.Cluster().V1beta1().PlacementDecisions(),
utils.ManagedByAddonManager,
)
addonConfigurationController := addonconfiguration.NewAddonConfigurationController(
hubAddOnClient,
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
addonInformers.Addon().V1alpha1().ClusterManagementAddOns(),
clusterInformers.Cluster().V1beta1().Placements(),
clusterInformers.Cluster().V1beta1().PlacementDecisions(),
utils.ManagedByAddonManager,
)
addonOwnerController := addonowner.NewAddonOwnerController(
hubAddOnClient,
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
addonInformers.Addon().V1alpha1().ClusterManagementAddOns(),
utils.ManagedByAddonManager,
)
addonProgressingController := addonprogressing.NewAddonProgressingController(
hubAddOnClient,
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
addonInformers.Addon().V1alpha1().ClusterManagementAddOns(),
workinformers.Work().V1().ManifestWorks(),
utils.ManagedByAddonManager,
)
mgmtAddonInstallProgressionController := cmainstallprogression.NewCMAInstallProgressionController(
hubAddOnClient,
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
addonInformers.Addon().V1alpha1().ClusterManagementAddOns(),
utils.ManagedByAddonManager,
)
addonTemplateController := addontemplate.NewAddonTemplateController(
controllerContext.KubeConfig,
hubKubeClient,
hubAddOnClient,
hubWorkClient,
addonInformers,
clusterInformers,
// can share the same dynamic informers for different template type addons since
// these addons only support addontemplate and addondeploymentconfig
dynamicInformers,
workinformers,
)
tokenInfrastructureController := addontokeninfra.NewTokenInfrastructureController(
hubKubeClient,
hubAddOnClient,
addonInformers.Addon().V1alpha1().ManagedClusterAddOns(),
tokenInfraInformers.Core().V1().ServiceAccounts(),
tokenInfraInformers.Rbac().V1().Roles(),
tokenInfraInformers.Rbac().V1().RoleBindings(),
)
go addonManagementController.Run(ctx, 2)
go addonConfigurationController.Run(ctx, 2)
go addonOwnerController.Run(ctx, 2)
go addonProgressingController.Run(ctx, 2)
go mgmtAddonInstallProgressionController.Run(ctx, 2)
// There should be only one instance of addonTemplateController running, since the addonTemplateController will
// start a goroutine for each template-type addon it watches.
go addonTemplateController.Run(ctx, 1)
go tokenInfrastructureController.Run(ctx, 1)
clusterInformers.Start(ctx.Done())
addonInformers.Start(ctx.Done())
workinformers.Start(ctx.Done())
dynamicInformers.Start(ctx.Done())
tokenInfraInformers.Start(ctx.Done())
<-ctx.Done()
return nil
}