Skip to content

Commit

Permalink
Handle List kind in watch
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Hickey <martin.hickey@ie.ibm.com>
  • Loading branch information
hickeyma committed Mar 18, 2021
1 parent a37320e commit 9644086
Showing 1 changed file with 52 additions and 22 deletions.
74 changes: 52 additions & 22 deletions internal/helm/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import (
"helm.sh/helm/v3/pkg/releaseutil"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"

"sigs.k8s.io/controller-runtime/pkg/controller"
crthandler "sigs.k8s.io/controller-runtime/pkg/handler"
logf "sigs.k8s.io/controller-runtime/pkg/log"
Expand Down Expand Up @@ -113,37 +115,65 @@ func watchDependentResources(mgr manager.Manager, r *HelmOperatorReconciler, c c
if gvk.Empty() {
continue
}
m.RLock()
_, ok := watches[gvk]
m.RUnlock()
if ok {
continue
}

restMapper := mgr.GetRESTMapper()
useOwnerRef, err := k8sutil.SupportsOwnerReference(restMapper, owner, &u)
if err != nil {
return err
}
var setWatchOnResource = func(dependent runtime.Object) error {
unstructuredObj := dependent.(*unstructured.Unstructured)
gvkDependent := unstructuredObj.GroupVersionKind()
if gvkDependent.Empty() {
return nil
}

if useOwnerRef { // Setup watch using owner references.
err = c.Watch(&source.Kind{Type: &u}, &crthandler.EnqueueRequestForOwner{OwnerType: owner},
predicate.DependentPredicate{})
m.RLock()
_, ok := watches[gvkDependent]
m.RUnlock()
if ok {
return nil
}

restMapper := mgr.GetRESTMapper()
useOwnerRef, err := k8sutil.SupportsOwnerReference(restMapper, owner, dependent)
if err != nil {
return err
}
} else { // Setup watch using annotations.
err = c.Watch(&source.Kind{Type: &u}, &libhandler.EnqueueRequestForAnnotation{Type: gvk.GroupKind()},
predicate.DependentPredicate{})

if useOwnerRef { // Setup watch using owner references.
err = c.Watch(&source.Kind{Type: unstructuredObj}, &crthandler.EnqueueRequestForOwner{OwnerType: owner},
predicate.DependentPredicate{})
if err != nil {
return err
}
} else { // Setup watch using annotations.
err = c.Watch(&source.Kind{Type: unstructuredObj}, &libhandler.EnqueueRequestForAnnotation{Type: gvkDependent.GroupKind()},
predicate.DependentPredicate{})
if err != nil {
return err
}
}
m.Lock()
watches[gvkDependent] = struct{}{}
m.Unlock()
log.Info("Watching dependent resource", "ownerApiVersion", r.GVK.GroupVersion(),
"ownerKind", r.GVK.Kind, "apiVersion", gvkDependent.GroupVersion(), "kind", gvkDependent.Kind)
return nil
}

// List is not actually a resource and therefore cannot have a
// watch on it. The watch will be on the kinds listed in the list
// and will therefore need to be handled individually.
if gvk.Kind == "List" {
u.EachListItem(func(obj runtime.Object) error {
err := setWatchOnResource(obj)
if err != nil {
return err
}
return nil
})
} else {
err := setWatchOnResource(&u)
if err != nil {
return err
}
}
m.Lock()
watches[gvk] = struct{}{}
m.Unlock()
log.Info("Watching dependent resource", "ownerApiVersion", r.GVK.GroupVersion(),
"ownerKind", r.GVK.Kind, "apiVersion", gvk.GroupVersion(), "kind", gvk.Kind)
}
return nil
}
Expand Down

0 comments on commit 9644086

Please sign in to comment.