mirror of https://github.com/knative/pkg.git
Create a kmeta package for libraries acting on ObjectMeta. (#67)
This bootstraps this package with a useful collection of label methods for managing sub-resources. I'd initially written this as a way of managing versioned DaemonSet resources as part of WarmImage ([see here](62cad8045a/pkg/reconciler/warmimage/resources/meta.go (L28)
)).
I am upstreaming this here because I want to take advantage of it in Build for managing Image cache subresources of [Cluster]BuildTemplate resources.
This commit is contained in:
parent
8fc80deb20
commit
5f353e5de8
|
@ -0,0 +1,5 @@
|
|||
# The OWNERS file is used by prow to automatically merge approved PRs.
|
||||
|
||||
approvers:
|
||||
- mattmoor
|
||||
- jonjohnsonjr
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Copyright 2018 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package kmeta provides Knative utilities for operating on Kubernetes
|
||||
// resources' ObjectMeta.
|
||||
package kmeta
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2018 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kmeta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
)
|
||||
|
||||
// The methods in this file are used for managing subresources in cases where
|
||||
// a controller instantiates different resources for each version of itself.
|
||||
//
|
||||
// For example, if an A might instantiate N B's at version 1 and M B's at
|
||||
// version 2 then it can use MakeVersionLabels to decorate each subresource
|
||||
// with the appropriate labels for the version at which it was instantiated.
|
||||
//
|
||||
// During reconciliation, MakeVersionLabelSelector can be used with the
|
||||
// informer listers to access the appropriate subresources for the current
|
||||
// version of the parent resource.
|
||||
//
|
||||
// Likewise during reconciliation, MakeOldVersionLabelSelector can be used
|
||||
// with the API client's DeleteCollection method to clean up subresources
|
||||
// for older versions of the resource.
|
||||
|
||||
// MakeVersionLabels constructs a set of labels to apply to subresources
|
||||
// instantiated at this version of the parent resource, so that we can
|
||||
// efficiently select them.
|
||||
func MakeVersionLabels(om metav1.ObjectMeta) labels.Set {
|
||||
return map[string]string{
|
||||
"controller": string(om.UID),
|
||||
"version": om.ResourceVersion,
|
||||
}
|
||||
}
|
||||
|
||||
// MakeVersionLabelSelector constructs a selector for subresources
|
||||
// instantiated at this version of the parent resource. This keys
|
||||
// off of the labels populated by MakeVersionLabels.
|
||||
func MakeVersionLabelSelector(om metav1.ObjectMeta) labels.Selector {
|
||||
return labels.SelectorFromSet(MakeVersionLabels(om))
|
||||
}
|
||||
|
||||
// MakeOldVersionLabelSelector constructs a selector for subresources
|
||||
// instantiated at an older version of the parent resource. This keys
|
||||
// off of the labels populated by MakeVersionLabels.
|
||||
func MakeOldVersionLabelSelector(om metav1.ObjectMeta) labels.Selector {
|
||||
return labels.NewSelector().Add(
|
||||
mustNewRequirement("controller", selection.Equals, []string{string(om.UID)}),
|
||||
mustNewRequirement("version", selection.NotEquals, []string{om.ResourceVersion}),
|
||||
)
|
||||
}
|
||||
|
||||
// mustNewRequirement panics if there are any errors constructing our selectors.
|
||||
func mustNewRequirement(key string, op selection.Operator, vals []string) labels.Requirement {
|
||||
r, err := labels.NewRequirement(key, op, vals)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("mustNewRequirement(%v, %v, %v) = %v", key, op, vals, err))
|
||||
}
|
||||
return *r
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Copyright 2018 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kmeta
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestMakeVersionLabels(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
om metav1.ObjectMeta
|
||||
s string
|
||||
}{{
|
||||
name: "simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "1234",
|
||||
ResourceVersion: "abcd",
|
||||
},
|
||||
s: "controller=1234,version=abcd",
|
||||
}, {
|
||||
name: "another simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "abcd",
|
||||
ResourceVersion: "1234",
|
||||
},
|
||||
s: "controller=abcd,version=1234",
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ls := MakeVersionLabels(test.om)
|
||||
if want, got := test.s, ls.String(); got != want {
|
||||
t.Errorf("MakeVersionLabels() = %v, wanted %v", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeVersionLabelSelector(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
om metav1.ObjectMeta
|
||||
s string
|
||||
}{{
|
||||
name: "simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "1234",
|
||||
ResourceVersion: "abcd",
|
||||
},
|
||||
s: "controller=1234,version=abcd",
|
||||
}, {
|
||||
name: "another simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "abcd",
|
||||
ResourceVersion: "1234",
|
||||
},
|
||||
s: "controller=abcd,version=1234",
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ls := MakeVersionLabelSelector(test.om)
|
||||
if want, got := test.s, ls.String(); got != want {
|
||||
t.Errorf("MakeVersionLabelSelector() = %v, wanted %v", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeOldVersionLabelSelector(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
om metav1.ObjectMeta
|
||||
s string
|
||||
}{{
|
||||
name: "simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "1234",
|
||||
ResourceVersion: "abcd",
|
||||
},
|
||||
s: "controller=1234,version!=abcd",
|
||||
}, {
|
||||
name: "another simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "abcd",
|
||||
ResourceVersion: "1234",
|
||||
},
|
||||
s: "controller=abcd,version!=1234",
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ls := MakeOldVersionLabelSelector(test.om)
|
||||
if want, got := test.s, ls.String(); got != want {
|
||||
t.Errorf("MakeOldVersionLabelSelector() = %v, wanted %v", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue