diff --git a/go/fn/object.go b/go/fn/object.go index ce13816ed..eb60f9354 100644 --- a/go/fn/object.go +++ b/go/fn/object.go @@ -679,19 +679,19 @@ func (o *KubeObject) SetAnnotation(k, v string) { } } -// Annotations returns all annotations. +// GetAnnotations returns all annotations. func (o *KubeObject) GetAnnotations() map[string]string { v, _, _ := o.obj.GetNestedStringMap("metadata", "annotations") return v } -// Annotation returns one annotation with key k. +// GetAnnotation returns one annotation with key k. func (o *KubeObject) GetAnnotation(k string) string { v, _, _ := o.obj.GetNestedString("metadata", "annotations", k) return v } -// HasAnnotations returns whether the KubeObject has the provided annotations +// HasAnnotations returns whether the KubeObject has all the given annotations. func (o *KubeObject) HasAnnotations(annotations map[string]string) bool { kubeObjectLabels := o.GetAnnotations() for k, v := range annotations { @@ -734,7 +734,7 @@ func (o *KubeObject) GetLabels() map[string]string { return v } -// HasLabels returns whether the KubeObject has the provided labels +// HasLabels returns whether the KubeObject has all the given labels func (o *KubeObject) HasLabels(labels map[string]string) bool { kubeObjectLabels := o.GetLabels() for k, v := range labels { @@ -792,8 +792,8 @@ func (o KubeObjects) String() string { return strings.Join(elems, "\n---\n") } -// Select will return the subset of objects in KubeObjects such that f(object) returns 'true'. -func (o KubeObjects) Select(f func(o *KubeObject) bool) KubeObjects { +// Where will return the subset of objects in KubeObjects such that f(object) returns 'true'. +func (o KubeObjects) Where(f func(o *KubeObject) bool) KubeObjects { var result KubeObjects for _, obj := range o { if f(obj) { @@ -803,86 +803,56 @@ func (o KubeObjects) Select(f func(o *KubeObject) bool) KubeObjects { return result } -// SelectByGvk will return the subset of objects that matches the provided GVK. -func (o KubeObjects) SelectByGvk(apiVersion, kind string) KubeObjects { - return o.Select(func(o *KubeObject) bool { - return o.IsGVK(apiVersion, kind) - }) +// WhereNot will return the subset of objects in KubeObjects such that f(object) returns 'false'. +func (o KubeObjects) WhereNot(f func(o *KubeObject) bool) KubeObjects { + var result KubeObjects + for _, obj := range o { + if !f(obj) { + result = append(result, obj) + } + } + return result } -// ExcludeByGvk will return the subset of objects that do not match the provided GVK. -func (o KubeObjects) ExcludeByGvk(apiVersion, kind string) KubeObjects { - return o.Select(func(o *KubeObject) bool { - return !o.IsGVK(apiVersion, kind) - }) +// IsGVK returns a function that checks if a KubeObject has a certain GVK. +func IsGVK(apiVersion, kind string) func(*KubeObject) bool { + return func(o *KubeObject) bool { + return o.IsGVK(apiVersion, kind) + } } -// SelectByName will return the subset of objects that matches the provided name. -func (o KubeObjects) SelectByName(name string) KubeObjects { - return o.Select(func(o *KubeObject) bool { +// IsName returns a function that checks if a KubeObject has a certain name. +func IsName(name string) func(*KubeObject) bool { + return func(o *KubeObject) bool { return o.GetName() == name - }) -} - -// ExcludeByName will return the subset of objects that do not match the provided name. -func (o KubeObjects) ExcludeByName(name string) KubeObjects { - return o.Select(func(o *KubeObject) bool { - return o.GetName() != name - }) + } } -// SelectByNamespace will return the subset of objects that matches the provided namespace. -func (o KubeObjects) SelectByNamespace(namespace string) KubeObjects { - return o.Select(func(o *KubeObject) bool { +// IsNamespace returns a function that checks if a KubeObject has a certain namespace. +func IsNamespace(namespace string) func(*KubeObject) bool { + return func(o *KubeObject) bool { return o.GetNamespace() == namespace - }) -} - -// ExcludeByNamespace will return the subset of objects that do not match the provided namespace. -func (o KubeObjects) ExcludeByNamespace(namespace string) KubeObjects { - return o.Select(func(o *KubeObject) bool { - return o.GetNamespace() != namespace - }) + } } -// SelectByLabels will return the subset of objects that matches the provided labels. -func (o KubeObjects) SelectByLabels(labels map[string]string) KubeObjects { - return o.Select(func(o *KubeObject) bool { +// HasLabels returns a function that checks if a KubeObject has all the given labels. +func HasLabels(labels map[string]string) func(*KubeObject) bool { + return func(o *KubeObject) bool { return o.HasLabels(labels) - }) -} - -// ExcludeByLabels will return the subset of objects that do not match the provided labels. -func (o KubeObjects) ExcludeByLabels(labels map[string]string) KubeObjects { - return o.Select(func(o *KubeObject) bool { - return !o.HasLabels(labels) - }) + } } -// SelectByAnnotations will return the subset of objects that matches the provided labels. -func (o KubeObjects) SelectByAnnotations(annotations map[string]string) KubeObjects { - return o.Select(func(o *KubeObject) bool { +// HasAnnotations returns a function that checks if a KubeObject has all the given annotations. +func HasAnnotations(annotations map[string]string) func(*KubeObject) bool { + return func(o *KubeObject) bool { return o.HasAnnotations(annotations) - }) -} - -// ExcludeByAnnotations will return the subset of objects that do not match the provided labels. -func (o KubeObjects) ExcludeByAnnotations(annotations map[string]string) KubeObjects { - return o.Select(func(o *KubeObject) bool { - return !o.HasAnnotations(annotations) - }) -} - -// SelectMetaResources will return the subset of objects that are meta resources. Currently, this -// is just the Kptfile. -func (o KubeObjects) SelectMetaResources() KubeObjects { - return o.SelectByGvk("kpt.dev/v1", "Kptfile") + } } -// ExcludeMetaResources will return the subset of objects that are not meta resources. Currently, this -// is just the Kptfile. -func (o KubeObjects) ExcludeMetaResources() KubeObjects { - return o.ExcludeByGvk("kpt.dev/v1", "Kptfile") +// IsMetaResource returns a function that checks if a KubeObject is a meta resource. For now +// this just includes the Kptfile +func IsMetaResource() func(*KubeObject) bool { + return IsGVK("kpt.dev/v1", "Kptfile") } func (o *KubeObject) IsEmpty() bool { diff --git a/go/fn/object_test.go b/go/fn/object_test.go index d7b0faf61..7c484fb51 100644 --- a/go/fn/object_test.go +++ b/go/fn/object_test.go @@ -309,15 +309,25 @@ metadata: foo: baz annotations: foo: bar +` + kptfile := ` +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: example-2 + annotations: + bar: foo ` d, err := ParseKubeObject([]byte(deployment)) assert.NoError(t, err) s, err := ParseKubeObject([]byte(service)) assert.NoError(t, err) - input := KubeObjects{d, s} + k, err := ParseKubeObject([]byte(kptfile)) + assert.NoError(t, err) + input := KubeObjects{d, s, k} // select all resources with labels foo=baz - items := input.SelectByLabels(map[string]string{"foo": "baz"}) + items := input.Where(HasLabels(map[string]string{"foo": "baz"})) assert.Equal(t, items.String(), `apiVersion: apps/v1 kind: Deployment metadata: @@ -340,7 +350,7 @@ metadata: foo: bar`) // select all deployments - items = input.SelectByGvk("apps/v1", "Deployment") + items = input.Where(IsGVK("apps/v1", "Deployment")) assert.Equal(t, items.String(), `apiVersion: apps/v1 kind: Deployment metadata: @@ -352,8 +362,8 @@ metadata: annotations: bar: foo`) - // exclude all services - items = input.ExcludeByGvk("apps/v1", "Service") + // exclude all services and meta resources + items = input.WhereNot(IsGVK("apps/v1", "Service")).WhereNot(IsMetaResource()) assert.Equal(t, items.String(), `apiVersion: apps/v1 kind: Deployment metadata: @@ -366,7 +376,7 @@ metadata: bar: foo`) // include resources with the label abc: def - items = input.SelectByLabels(map[string]string{"abc": "def"}) + items = input.Where(HasLabels(map[string]string{"abc": "def"})) assert.Equal(t, items.String(), `apiVersion: apps/v1 kind: Deployment metadata: @@ -379,7 +389,7 @@ metadata: bar: foo`) // exclude all resources with the annotation foo=bar - items = input.ExcludeByAnnotations(map[string]string{"foo": "bar"}) + items = input.WhereNot(HasAnnotations(map[string]string{"foo": "bar"})) assert.Equal(t, items.String(), `apiVersion: apps/v1 kind: Deployment metadata: @@ -388,11 +398,18 @@ metadata: labels: abc: def foo: baz + annotations: + bar: foo +--- +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: example-2 annotations: bar: foo`) // include resources named 'example' that are Not in namespace default - items = input.SelectByName("example").ExcludeByNamespace("default") + items = input.Where(IsName("example")).WhereNot(IsNamespace("default")) assert.Equal(t, items.String(), `apiVersion: apps/v1 kind: Service metadata: @@ -404,7 +421,7 @@ metadata: foo: bar`) // add the label "g=h" to all resources with annotation "bar=foo" - items = input.SelectByAnnotations(map[string]string{"bar": "foo"}) + items = input.Where(HasAnnotations(map[string]string{"bar": "foo"})) for _, obj := range items { obj.SetLabel("g", "h") } @@ -428,5 +445,14 @@ metadata: labels: foo: baz annotations: - foo: bar`) + foo: bar +--- +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: example-2 + annotations: + bar: foo + labels: + g: h`) }