Add default namespace labels to all namespaces for selectors (#96968)
* namespace by name default labelling Co-authored-by: Jordan Liggitt <jordan@liggitt.net> Co-authored-by: Abhishek Raut <rauta@vmware.com> * Make some logic improvement into default namespace label * Fix unit tests * minor change to trigger the CI * Correct some tests and validation behaviors * Add Canonicalize normalization and improve validation * Remove label validation that should be dealt by strategy * Update defaults_test.go add fuzzer ns spec * remove the finalizer thingy * Fix integration test * Add namespace canonicalize unit test * Improve validation code and code comments * move validation of labels to validateupdate * spacex will save us all * add comment to testget * readablility of canonicalize * Added namespace finalize and status update validation * comment about ungenerated names * correcting a missing line on storage_test * Update the namespace validation unit test * Add more missing unit test changes * Let's just blast the value. Also documenting the workflow here * Remove unnecessary validations Co-authored-by: Jordan Liggitt <jordan@liggitt.net> Co-authored-by: Abhishek Raut <rauta@vmware.com> Co-authored-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com>
This commit is contained in:
@@ -472,6 +472,16 @@ var Funcs = func(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||
func(s *core.NamespaceSpec, c fuzz.Continue) {
|
||||
s.Finalizers = []core.FinalizerName{core.FinalizerKubernetes}
|
||||
},
|
||||
func(s *core.Namespace, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(s) // fuzz self without calling this function again
|
||||
// Match name --> label defaulting
|
||||
if len(s.Name) > 0 {
|
||||
if s.Labels == nil {
|
||||
s.Labels = map[string]string{}
|
||||
}
|
||||
s.Labels["kubernetes.io/metadata.name"] = s.Name
|
||||
}
|
||||
},
|
||||
func(s *core.NamespaceStatus, c fuzz.Continue) {
|
||||
s.Phase = core.NamespaceActive
|
||||
},
|
||||
|
@@ -323,6 +323,26 @@ func SetDefaults_HTTPGetAction(obj *v1.HTTPGetAction) {
|
||||
obj.Scheme = v1.URISchemeHTTP
|
||||
}
|
||||
}
|
||||
|
||||
// SetDefaults_Namespace adds a default label for all namespaces
|
||||
func SetDefaults_Namespace(obj *v1.Namespace) {
|
||||
// TODO, remove the feature gate in 1.22
|
||||
// we can't SetDefaults for nameless namespaces (generateName).
|
||||
// This code needs to be kept in sync with the implementation that exists
|
||||
// in Namespace Canonicalize strategy (pkg/registry/core/namespace)
|
||||
|
||||
// note that this can result in many calls to feature enablement in some cases, but
|
||||
// we assume that there's no real cost there.
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.NamespaceDefaultLabelName) {
|
||||
if len(obj.Name) > 0 {
|
||||
if obj.Labels == nil {
|
||||
obj.Labels = map[string]string{}
|
||||
}
|
||||
obj.Labels[v1.LabelMetadataName] = obj.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_NamespaceStatus(obj *v1.NamespaceStatus) {
|
||||
if obj.Phase == "" {
|
||||
obj.Phase = v1.NamespaceActive
|
||||
|
@@ -1416,6 +1416,40 @@ func TestSetDefaultNamespace(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultNamespaceLabels(t *testing.T) {
|
||||
// Although this is defaulted to true, it's still worth to enable the feature gate during the test
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NamespaceDefaultLabelName, true)()
|
||||
|
||||
theNs := "default-ns-labels-are-great"
|
||||
s := &v1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: theNs,
|
||||
},
|
||||
}
|
||||
obj2 := roundTrip(t, runtime.Object(s))
|
||||
s2 := obj2.(*v1.Namespace)
|
||||
|
||||
if s2.ObjectMeta.Labels[v1.LabelMetadataName] != theNs {
|
||||
t.Errorf("Expected default namespace label value of %v, but got %v", theNs, s2.ObjectMeta.Labels[v1.LabelMetadataName])
|
||||
}
|
||||
|
||||
// And let's disable the FG and check if it still defaults creating the labels
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NamespaceDefaultLabelName, false)()
|
||||
|
||||
theNs = "default-ns-labels-are-not-that-great"
|
||||
s = &v1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: theNs,
|
||||
},
|
||||
}
|
||||
obj2 = roundTrip(t, runtime.Object(s))
|
||||
s2 = obj2.(*v1.Namespace)
|
||||
|
||||
if _, ok := s2.ObjectMeta.Labels[v1.LabelMetadataName]; ok {
|
||||
t.Errorf("Default namespace shouldn't exist here, as the feature gate is disabled %v", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultPodSpecHostNetwork(t *testing.T) {
|
||||
portNum := int32(8080)
|
||||
s := v1.PodSpec{}
|
||||
|
1
pkg/apis/core/v1/zz_generated.defaults.go
generated
1
pkg/apis/core/v1/zz_generated.defaults.go
generated
@@ -158,6 +158,7 @@ func SetObjectDefaults_LimitRangeList(in *v1.LimitRangeList) {
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Namespace(in *v1.Namespace) {
|
||||
SetDefaults_Namespace(in)
|
||||
SetDefaults_NamespaceStatus(&in.Status)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user