Files
open-cluster-management/test/integration/cloudevents/source/handler.go
2024-01-18 03:09:13 +00:00

78 lines
2.4 KiB
Go

package source
import (
"fmt"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/klog/v2"
workv1lister "open-cluster-management.io/api/client/work/listers/work/v1"
workv1 "open-cluster-management.io/api/work/v1"
"open-cluster-management.io/sdk-go/pkg/cloudevents/generic"
"open-cluster-management.io/sdk-go/pkg/cloudevents/generic/types"
"open-cluster-management.io/sdk-go/pkg/cloudevents/work/watcher"
)
const ManifestWorkFinalizer = "cluster.open-cluster-management.io/manifest-work-cleanup"
func newManifestWorkStatusHandler(lister workv1lister.ManifestWorkLister, watcher *watcher.ManifestWorkWatcher) generic.ResourceHandler[*workv1.ManifestWork] {
return func(action types.ResourceAction, work *workv1.ManifestWork) error {
switch action {
case types.StatusModified:
works, err := lister.ManifestWorks(work.Namespace).List(labels.Everything())
if err != nil {
return err
}
var lastWork *workv1.ManifestWork
for _, w := range works {
if w.UID == work.UID {
lastWork = w
break
}
}
if lastWork == nil {
return fmt.Errorf("failed to find last work with id %s", work.UID)
}
if work.Generation < lastWork.Generation {
klog.Infof("The work %s generation %d is less than cached generation %d, ignore",
work.UID, work.Generation, lastWork.Generation)
return nil
}
// no status change
if equality.Semantic.DeepEqual(lastWork.Status, work.Status) {
return nil
}
// restore the fields that are maintained by local agent
work.Name = lastWork.Name
work.Namespace = lastWork.Namespace
work.Labels = lastWork.Labels
work.Annotations = lastWork.Annotations
work.DeletionTimestamp = lastWork.DeletionTimestamp
work.Spec = lastWork.Spec
if meta.IsStatusConditionTrue(work.Status.Conditions, ManifestsDeleted) {
work.Finalizers = []string{}
klog.Infof("delete work %s/%s in the source", work.Namespace, work.Name)
watcher.Receive(watch.Event{Type: watch.Deleted, Object: work})
return nil
}
// the work is handled by agent, we make sure the finalizer here
work.Finalizers = []string{ManifestWorkFinalizer}
watcher.Receive(watch.Event{Type: watch.Modified, Object: work})
default:
return fmt.Errorf("unsupported resource action %s", action)
}
return nil
}
}