From e93f1d7870c00ad13bd23d276b4b47540c463a98 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 24 Sep 2018 08:59:16 -0700 Subject: [PATCH] Add changeset package changeset is an easy way to track parent/child relationships and trigger parent updates if child changes --- pkg/changeset/changeset.go | 71 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 pkg/changeset/changeset.go diff --git a/pkg/changeset/changeset.go b/pkg/changeset/changeset.go new file mode 100644 index 00000000..a8789a0a --- /dev/null +++ b/pkg/changeset/changeset.go @@ -0,0 +1,71 @@ +package changeset + +import ( + "strings" + + "github.com/rancher/norman/controller" + "k8s.io/apimachinery/pkg/runtime" +) + +type Key struct { + Namespace string + Name string +} + +type ControllerProvider interface { + Generic() controller.GenericController +} + +type Enqueuer func(namespace, name string) + +type Resolver func(namespace, name string, obj runtime.Object) ([]Key, error) + +func Watch(name string, resolve Resolver, enq Enqueuer, controllers ...ControllerProvider) { + for _, c := range controllers { + watch(name, enq, resolve, c.Generic()) + } +} + +func watch(name string, enq Enqueuer, resolve Resolver, genericController controller.GenericController) { + genericController.AddHandler(name, func(key string) error { + obj, exists, err := genericController.Informer().GetStore().GetByKey(key) + if err != nil { + return err + } + + if !exists { + obj = nil + } + + var ( + ns string + name string + ) + + parts := strings.SplitN(key, "/", 2) + if len(parts) == 2 { + ns = parts[0] + name = parts[1] + } else { + name = parts[0] + } + + ro, ok := obj.(runtime.Object) + if !ok { + return nil + } + + keys, err := resolve(ns, name, ro) + if err != nil { + return err + } + + for _, key := range keys { + if key.Name != "" { + enq(key.Namespace, key.Name) + } + } + + return nil + }) +}