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
|
// The methods in this file are used for managing subresources in cases where
|
||||||
// a controller instantiates different resources for each version of itself.
|
// 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
|
// 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
|
// 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.
|
// mustNewRequirement panics if there are any errors constructing our selectors.
|
||||||
func mustNewRequirement(key string, op selection.Operator, vals []string) labels.Requirement {
|
func mustNewRequirement(key string, op selection.Operator, vals []string) labels.Requirement {
|
||||||
r, err := labels.NewRequirement(key, op, vals)
|
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