mirror of
https://github.com/open-cluster-management-io/ocm.git
synced 2026-08-23 22:26:49 +00:00
Scorecard supply-chain security / Scorecard analysis (push) Failing after 25s
Post / images (amd64, placement) (push) Failing after 47s
Post / images (amd64, registration) (push) Failing after 44s
Post / images (amd64, registration-operator) (push) Failing after 44s
Post / images (amd64, work) (push) Failing after 43s
Post / images (arm64, addon-manager) (push) Failing after 42s
Post / images (arm64, placement) (push) Failing after 41s
Post / images (arm64, registration) (push) Failing after 43s
Post / images (arm64, registration-operator) (push) Failing after 41s
Post / images (arm64, work) (push) Failing after 41s
Post / images (amd64, addon-manager) (push) Failing after 7m45s
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 38m55s
Close stale issues and PRs / stale (push) Successful in 50s
* sync clusterprofile based on managedclusterset and managedclustersetbinding Co-authored-by: Claude <claude@anthropic.com> Signed-off-by: Morven Cao <lcao@redhat.com> * Refactor ClusterProfile controller into two separate controllers. Signed-off-by: Morven Cao <lcao@redhat.com> * address comments. Signed-off-by: Morven Cao <lcao@redhat.com> * fix lint issues. Signed-off-by: Morven Cao <lcao@redhat.com> * address comments. Signed-off-by: Morven Cao <lcao@redhat.com> * address comments. Signed-off-by: Morven Cao <lcao@redhat.com> --------- Signed-off-by: Morven Cao <lcao@redhat.com>
192 lines
6.0 KiB
Go
192 lines
6.0 KiB
Go
package managedclustersetbinding
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/apimachinery/pkg/api/meta"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
|
"k8s.io/client-go/tools/cache"
|
|
"k8s.io/client-go/util/workqueue"
|
|
"k8s.io/klog/v2"
|
|
|
|
clientset "open-cluster-management.io/api/client/cluster/clientset/versioned"
|
|
clusterinformerv1beta2 "open-cluster-management.io/api/client/cluster/informers/externalversions/cluster/v1beta2"
|
|
clusterlisterv1beta2 "open-cluster-management.io/api/client/cluster/listers/cluster/v1beta2"
|
|
clusterv1beta2 "open-cluster-management.io/api/cluster/v1beta2"
|
|
"open-cluster-management.io/sdk-go/pkg/basecontroller/factory"
|
|
"open-cluster-management.io/sdk-go/pkg/patcher"
|
|
|
|
"open-cluster-management.io/ocm/pkg/common/queue"
|
|
)
|
|
|
|
const (
|
|
// ByClusterSetIndex is the indexer name for ManagedClusterSetBinding by ClusterSet
|
|
ByClusterSetIndex = "by-clusterset"
|
|
)
|
|
|
|
const byClusterSet = ByClusterSetIndex // Use exported constant internally
|
|
|
|
// managedClusterSetController reconciles instances of ManagedClusterSet on the hub.
|
|
type managedClusterSetBindingController struct {
|
|
clusterClient clientset.Interface
|
|
clusterSetBindingLister clusterlisterv1beta2.ManagedClusterSetBindingLister
|
|
clusterSetLister clusterlisterv1beta2.ManagedClusterSetLister
|
|
clusterSetBindingIndexers cache.Indexer
|
|
queue workqueue.TypedRateLimitingInterface[string]
|
|
}
|
|
|
|
func NewManagedClusterSetBindingController(
|
|
clusterClient clientset.Interface,
|
|
clusterSetInformer clusterinformerv1beta2.ManagedClusterSetInformer,
|
|
clusterSetBindingInformer clusterinformerv1beta2.ManagedClusterSetBindingInformer) factory.Controller {
|
|
|
|
controllerName := "managed-clusterset-binding-controller"
|
|
syncCtx := factory.NewSyncContext(controllerName)
|
|
|
|
err := clusterSetBindingInformer.Informer().AddIndexers(cache.Indexers{
|
|
byClusterSet: indexByClusterset,
|
|
})
|
|
|
|
if err != nil {
|
|
utilruntime.HandleError(err)
|
|
}
|
|
|
|
c := &managedClusterSetBindingController{
|
|
clusterClient: clusterClient,
|
|
clusterSetLister: clusterSetInformer.Lister(),
|
|
clusterSetBindingLister: clusterSetBindingInformer.Lister(),
|
|
clusterSetBindingIndexers: clusterSetBindingInformer.Informer().GetIndexer(),
|
|
queue: syncCtx.Queue(),
|
|
}
|
|
|
|
_, err = clusterSetInformer.Informer().AddEventHandler(
|
|
cache.ResourceEventHandlerFuncs{
|
|
AddFunc: c.enqueueBindingsByClusterSet,
|
|
UpdateFunc: func(oldObj, newObj interface{}) {
|
|
c.enqueueBindingsByClusterSet(newObj)
|
|
},
|
|
DeleteFunc: c.enqueueBindingsByClusterSet,
|
|
},
|
|
)
|
|
if err != nil {
|
|
utilruntime.HandleError(err)
|
|
}
|
|
|
|
return factory.New().
|
|
WithSyncContext(syncCtx).
|
|
WithInformersQueueKeysFunc(queue.QueueKeyByMetaNamespaceName, clusterSetBindingInformer.Informer()).
|
|
WithBareInformers(clusterSetInformer.Informer()).
|
|
WithSync(c.sync).
|
|
ToController("ManagedClusterSetController")
|
|
}
|
|
|
|
func indexByClusterset(obj interface{}) ([]string, error) {
|
|
binding, ok := obj.(*clusterv1beta2.ManagedClusterSetBinding)
|
|
if !ok {
|
|
return []string{}, fmt.Errorf("obj is supposed to be a ManagedClusterSetBinding, but is %T", obj)
|
|
}
|
|
|
|
return []string{binding.Spec.ClusterSet}, nil
|
|
}
|
|
|
|
func (c *managedClusterSetBindingController) getClusterBindingsByClusterSet(name string) ([]*clusterv1beta2.ManagedClusterSetBinding, error) {
|
|
objs, err := c.clusterSetBindingIndexers.ByIndex(byClusterSet, name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bindings := make([]*clusterv1beta2.ManagedClusterSetBinding, len(objs))
|
|
for _, obj := range objs {
|
|
binding := obj.(*clusterv1beta2.ManagedClusterSetBinding)
|
|
bindings = append(bindings, binding)
|
|
}
|
|
|
|
return bindings, nil
|
|
}
|
|
|
|
func (c *managedClusterSetBindingController) enqueueBindingsByClusterSet(obj interface{}) {
|
|
name, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
|
|
if err != nil {
|
|
utilruntime.HandleError(fmt.Errorf("error to get accessor of object: %v", obj))
|
|
return
|
|
}
|
|
|
|
bindings, err := c.getClusterBindingsByClusterSet(name)
|
|
if err != nil {
|
|
utilruntime.HandleError(fmt.Errorf("error to get bindings of object: %v", obj))
|
|
return
|
|
}
|
|
|
|
for _, binding := range bindings {
|
|
// TODO(qiujian16) it is weird that index can return nil. Needs more investigation.
|
|
if binding == nil {
|
|
continue
|
|
}
|
|
key, _ := cache.MetaNamespaceKeyFunc(binding)
|
|
c.queue.Add(key)
|
|
}
|
|
}
|
|
|
|
func (c *managedClusterSetBindingController) sync(ctx context.Context, syncCtx factory.SyncContext, key string) error {
|
|
logger := klog.FromContext(ctx).WithValues("key", key)
|
|
if len(key) == 0 {
|
|
return nil
|
|
}
|
|
|
|
logger.V(4).Info("Reconciling ManagedClusterSetBinding")
|
|
|
|
bindingNamespace, bindingName, err := cache.SplitMetaNamespaceKey(key)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
patcher := patcher.NewPatcher[
|
|
*clusterv1beta2.ManagedClusterSetBinding, clusterv1beta2.ManagedClusterSetBindingSpec, clusterv1beta2.ManagedClusterSetBindingStatus](
|
|
c.clusterClient.ClusterV1beta2().ManagedClusterSetBindings(bindingNamespace))
|
|
|
|
if len(bindingNamespace) == 0 {
|
|
return nil
|
|
}
|
|
|
|
binding, err := c.clusterSetBindingLister.ManagedClusterSetBindings(bindingNamespace).Get(bindingName)
|
|
switch {
|
|
case errors.IsNotFound(err):
|
|
return nil
|
|
case err != nil:
|
|
return err
|
|
}
|
|
|
|
_, err = c.clusterSetLister.Get(binding.Spec.ClusterSet)
|
|
|
|
bindingCopy := binding.DeepCopy()
|
|
switch {
|
|
case errors.IsNotFound(err):
|
|
meta.SetStatusCondition(&bindingCopy.Status.Conditions, metav1.Condition{
|
|
Type: clusterv1beta2.ClusterSetBindingBoundType,
|
|
Status: metav1.ConditionFalse,
|
|
Reason: "ClusterSetNotFound",
|
|
})
|
|
if _, err := patcher.PatchStatus(ctx, bindingCopy, bindingCopy.Status, binding.Status); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
case err != nil:
|
|
return err
|
|
}
|
|
|
|
meta.SetStatusCondition(&bindingCopy.Status.Conditions, metav1.Condition{
|
|
Type: clusterv1beta2.ClusterSetBindingBoundType,
|
|
Status: metav1.ConditionTrue,
|
|
Reason: "ClusterSetBound",
|
|
})
|
|
|
|
if _, err := patcher.PatchStatus(ctx, bindingCopy, bindingCopy.Status, binding.Status); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|