mirror of https://github.com/knative/pkg.git
Add Generation variants of kmeta/labels.go (#117)
Unlike `ResourceVersion`, which changes whenever the resource changes at all (including `/status` which can be high churn), `Generation` only changes when the `/spec` of a CRD changes (for CRDs starting in 1.11, right now they are locked at `generation: 1`). These methods are useful for interacting with K8s resource now, and will be useful for CRDs soon. Fixes: https://github.com/knative/pkg/issues/116
This commit is contained in:
parent
1f153817b2
commit
1a50a39daf
|
|
@ -26,6 +26,13 @@ import (
|
|||
|
||||
// The methods in this file are used for managing subresources in cases where
|
||||
// a controller instantiates different resources for each version of itself.
|
||||
// There are two sets of methods available here:
|
||||
// * `*VersionLabel*`: these methods act on `metadata.resourceVersion` and
|
||||
// create new labels for EVERY change to the resource (incl. `/status`).
|
||||
// * `*GenerationLabel*`: these methods act on `metadata.generation` and
|
||||
// create new labels for changes to the resource's "spec" (typically, but
|
||||
// some K8s resources change `metadata.generation` for annotations as well
|
||||
// e.g. Deployment).
|
||||
//
|
||||
// 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
|
||||
|
|
@ -66,6 +73,37 @@ func MakeOldVersionLabelSelector(om metav1.ObjectMetaAccessor) labels.Selector {
|
|||
)
|
||||
}
|
||||
|
||||
// MakeGenerationLabels 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 MakeGenerationLabels(om metav1.ObjectMetaAccessor) labels.Set {
|
||||
return map[string]string{
|
||||
"controller": string(om.GetObjectMeta().GetUID()),
|
||||
"generation": genStr(om),
|
||||
}
|
||||
}
|
||||
|
||||
// MakeGenerationLabelSelector constructs a selector for subresources
|
||||
// instantiated at this version of the parent resource. This keys
|
||||
// off of the labels populated by MakeGenerationLabels.
|
||||
func MakeGenerationLabelSelector(om metav1.ObjectMetaAccessor) labels.Selector {
|
||||
return labels.SelectorFromSet(MakeGenerationLabels(om))
|
||||
}
|
||||
|
||||
// MakeOldGenerationLabelSelector constructs a selector for subresources
|
||||
// instantiated at an older version of the parent resource. This keys
|
||||
// off of the labels populated by MakeGenerationLabels.
|
||||
func MakeOldGenerationLabelSelector(om metav1.ObjectMetaAccessor) labels.Selector {
|
||||
return labels.NewSelector().Add(
|
||||
mustNewRequirement("controller", selection.Equals, []string{string(om.GetObjectMeta().GetUID())}),
|
||||
mustNewRequirement("generation", selection.NotEquals, []string{genStr(om)}),
|
||||
)
|
||||
}
|
||||
|
||||
func genStr(om metav1.ObjectMetaAccessor) string {
|
||||
return fmt.Sprintf("%05d", om.GetObjectMeta().GetGeneration())
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
|
|
|||
|
|
@ -114,3 +114,96 @@ func TestMakeOldVersionLabelSelector(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeGenerationLabels(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
om metav1.ObjectMeta
|
||||
s string
|
||||
}{{
|
||||
name: "simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "1234",
|
||||
Generation: 5,
|
||||
},
|
||||
s: "controller=1234,generation=00005",
|
||||
}, {
|
||||
name: "another simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "abcd",
|
||||
Generation: 5432,
|
||||
},
|
||||
s: "controller=abcd,generation=05432",
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ls := MakeGenerationLabels(&test.om)
|
||||
if want, got := test.s, ls.String(); got != want {
|
||||
t.Errorf("MakeGenerationLabels() = %v, wanted %v", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeGenerationLabelSelector(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
om metav1.ObjectMeta
|
||||
s string
|
||||
}{{
|
||||
name: "simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "1234",
|
||||
Generation: 5,
|
||||
},
|
||||
s: "controller=1234,generation=00005",
|
||||
}, {
|
||||
name: "another simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "abcd",
|
||||
Generation: 5432,
|
||||
},
|
||||
s: "controller=abcd,generation=05432",
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ls := MakeGenerationLabelSelector(&test.om)
|
||||
if want, got := test.s, ls.String(); got != want {
|
||||
t.Errorf("MakeGenerationLabelSelector() = %v, wanted %v", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeOldGenerationLabelSelector(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
om metav1.ObjectMeta
|
||||
s string
|
||||
}{{
|
||||
name: "simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "1234",
|
||||
Generation: 5,
|
||||
},
|
||||
s: "controller=1234,generation!=00005",
|
||||
}, {
|
||||
name: "another simple translation",
|
||||
om: metav1.ObjectMeta{
|
||||
UID: "abcd",
|
||||
Generation: 5432,
|
||||
},
|
||||
s: "controller=abcd,generation!=05432",
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ls := MakeOldGenerationLabelSelector(&test.om)
|
||||
if want, got := test.s, ls.String(); got != want {
|
||||
t.Errorf("MakeOldGenerationLabelSelector() = %v, wanted %v", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue