-
Notifications
You must be signed in to change notification settings - Fork 96
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Zhiwei Yin <[email protected]>
- Loading branch information
1 parent
3fc013f
commit d8eb6a2
Showing
37 changed files
with
2,013 additions
and
504 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
package gc | ||
|
||
import ( | ||
"context" | ||
"time" | ||
|
||
"github.com/openshift/library-go/pkg/controller/factory" | ||
"github.com/openshift/library-go/pkg/operator/events" | ||
operatorhelpers "github.com/openshift/library-go/pkg/operator/v1helpers" | ||
"k8s.io/apimachinery/pkg/api/errors" | ||
"k8s.io/apimachinery/pkg/api/meta" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/runtime/schema" | ||
utilerrors "k8s.io/apimachinery/pkg/util/errors" | ||
corev1informers "k8s.io/client-go/informers/core/v1" | ||
"k8s.io/client-go/kubernetes" | ||
rbacv1listers "k8s.io/client-go/listers/rbac/v1" | ||
"k8s.io/client-go/metadata" | ||
|
||
addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" | ||
clientset "open-cluster-management.io/api/client/cluster/clientset/versioned" | ||
informerv1 "open-cluster-management.io/api/client/cluster/informers/externalversions/cluster/v1" | ||
clusterv1listers "open-cluster-management.io/api/client/cluster/listers/cluster/v1" | ||
worklister "open-cluster-management.io/api/client/work/listers/work/v1" | ||
clusterv1 "open-cluster-management.io/api/cluster/v1" | ||
|
||
"open-cluster-management.io/ocm/pkg/common/patcher" | ||
"open-cluster-management.io/ocm/pkg/common/queue" | ||
) | ||
|
||
type gcReconcileOp int | ||
|
||
const ( | ||
gcReconcileRequeue gcReconcileOp = iota | ||
gcReconcileStop | ||
gcReconcileContinue | ||
) | ||
|
||
const ( | ||
// TODO: this condition definition should be moved to api repo | ||
ManagedClusterConditionDeleting string = "ManagedClusterIsDeleting" | ||
) | ||
|
||
var ( | ||
addonGvr = schema.GroupVersionResource{Group: "addon.open-cluster-management.io", Version: "v1alpha1", Resource: "managedclusteraddons"} | ||
workGvr = schema.GroupVersionResource{Group: "work.open-cluster-management.io", Version: "v1", Resource: "manifestworks"} | ||
) | ||
|
||
// gcReconciler is an interface for reconcile cleanup logic after cluster is deleted. | ||
// clusterName is from the queueKey, cluster may be nil. | ||
type gcReconciler interface { | ||
reconcile(ctx context.Context, clusterName string, cluster *clusterv1.ManagedCluster) (gcReconcileOp, error) | ||
} | ||
|
||
type GCController struct { | ||
clusterLister clusterv1listers.ManagedClusterLister | ||
clusterPatcher patcher.Patcher[*clusterv1.ManagedCluster, clusterv1.ManagedClusterSpec, clusterv1.ManagedClusterStatus] | ||
gcReconcilers []gcReconciler | ||
} | ||
|
||
// NewGCController ensures the related resources are cleaned up after cluster is deleted | ||
func NewGCController( | ||
clusterRoleLister rbacv1listers.ClusterRoleLister, | ||
clusterRoleBindingLister rbacv1listers.ClusterRoleBindingLister, | ||
roleBindingLister rbacv1listers.RoleBindingLister, | ||
namespaceInformer corev1informers.NamespaceInformer, | ||
clusterInformer informerv1.ManagedClusterInformer, | ||
manifestWorkLister worklister.ManifestWorkLister, | ||
clusterClient clientset.Interface, | ||
kubeClient kubernetes.Interface, | ||
metadataClient metadata.Interface, | ||
eventRecorder events.Recorder, | ||
) factory.Controller { | ||
clusterPatcher := patcher.NewPatcher[ | ||
*clusterv1.ManagedCluster, clusterv1.ManagedClusterSpec, clusterv1.ManagedClusterStatus]( | ||
clusterClient.ClusterV1().ManagedClusters()) | ||
controller := &GCController{ | ||
clusterLister: clusterInformer.Lister(), | ||
clusterPatcher: clusterPatcher, | ||
gcReconcilers: []gcReconciler{ | ||
// currently only support to gc addons and works, need consider to add rbac to registration if gc other resources. | ||
newGCResourcesController(metadataClient, []resourceFilter{ | ||
{addonGvr, ""}, {workGvr, getGCWorkLabelSelector()}}, eventRecorder), | ||
newGCClusterRbacController(kubeClient, clusterPatcher, clusterInformer, clusterRoleLister, | ||
clusterRoleBindingLister, roleBindingLister, manifestWorkLister, eventRecorder), | ||
newGCClusterRoleController(clusterRoleLister, clusterInformer.Lister(), manifestWorkLister, kubeClient.RbacV1(), eventRecorder), | ||
}, | ||
} | ||
|
||
return factory.New(). | ||
WithInformersQueueKeysFunc(queue.QueueKeyByMetaName, clusterInformer.Informer(), namespaceInformer.Informer()). | ||
WithSync(controller.sync).ToController("GCController", eventRecorder) | ||
} | ||
|
||
func (r *GCController) sync(ctx context.Context, controllerContext factory.SyncContext) error { | ||
clusterName := controllerContext.QueueKey() | ||
if clusterName == "" || clusterName == factory.DefaultQueueKey { | ||
return nil | ||
} | ||
|
||
cluster, err := r.clusterLister.Get(clusterName) | ||
if err != nil && !errors.IsNotFound(err) { | ||
return err | ||
} | ||
|
||
var errs []error | ||
// the reconcilers should reconcile in order. | ||
for index := 0; index < len(r.gcReconcilers); index++ { | ||
op, err := r.gcReconcilers[index].reconcile(ctx, clusterName, cluster) | ||
switch op { | ||
case gcReconcileRequeue: | ||
controllerContext.Queue().AddAfter(clusterName, 10*time.Second) | ||
return nil | ||
case gcReconcileStop: | ||
return err | ||
} | ||
|
||
if err != nil { | ||
errs = append(errs, err) | ||
} | ||
} | ||
if len(errs) == 0 { | ||
return nil | ||
} | ||
|
||
if cluster == nil { | ||
return utilerrors.NewAggregate(errs) | ||
} | ||
|
||
if cluster.DeletionTimestamp.IsZero() { | ||
return utilerrors.NewAggregate(errs) | ||
} | ||
|
||
newCluster := cluster.DeepCopy() | ||
applyErrors := operatorhelpers.NewMultiLineAggregate(errs) | ||
meta.SetStatusCondition(&newCluster.Status.Conditions, metav1.Condition{ | ||
Type: ManagedClusterConditionDeleting, | ||
Status: metav1.ConditionFalse, | ||
Reason: "Error", | ||
Message: applyErrors.Error(), | ||
}) | ||
|
||
if _, err := r.clusterPatcher.PatchStatus(ctx, newCluster, newCluster.Status, cluster.Status); err != nil { | ||
return err | ||
} | ||
|
||
return utilerrors.NewAggregate(errs) | ||
} | ||
|
||
// getGCWorkLabelSelector only filter the works which are not created by addon | ||
func getGCWorkLabelSelector() string { | ||
selector := &metav1.LabelSelector{ | ||
MatchExpressions: []metav1.LabelSelectorRequirement{ | ||
{ | ||
Key: addonv1alpha1.AddonLabelKey, | ||
Operator: metav1.LabelSelectorOpDoesNotExist, | ||
}, | ||
}, | ||
} | ||
return metav1.FormatLabelSelector(selector) | ||
} |
Oops, something went wrong.