From 7e54b1c149538932928fcdc199d497efdb6dbad6 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Sat, 15 Aug 2020 06:04:49 -0400 Subject: [PATCH] Add RuntimeClassName feature flag Allow users to set runtimeClassName on services via the runtimeclassname feature flag. Issue #5306 --- config/core/configmaps/features.yaml | 6 ++- pkg/apis/config/features.go | 41 ++++++++++--------- pkg/apis/config/features_test.go | 61 ++++++++++++++++++++-------- pkg/apis/serving/fieldmask.go | 4 +- 4 files changed, 75 insertions(+), 37 deletions(-) diff --git a/config/core/configmaps/features.yaml b/config/core/configmaps/features.yaml index c01121a1e4eb..287a4be8c3e5 100644 --- a/config/core/configmaps/features.yaml +++ b/config/core/configmaps/features.yaml @@ -20,7 +20,7 @@ metadata: labels: serving.knative.dev/release: devel annotations: - knative.dev/example-checksum: "983ddf13" + knative.dev/example-checksum: "c0b41539" data: _example: | ################################ @@ -62,6 +62,10 @@ data: # attaching the following metadata annotation: "features.knative.dev/podspec-dryrun":"enabled". kubernetes.podspec-dryrun: "allowed" + # When set to "enabled" or "allowed" this feature allows end-users to set + # the Pod's RuntimeClassName. + kubernetes.podspec-runtimeclassname: "disabled" + # This feature allows end-users to set a subset of fields on the Pod's SecurityContext # in addition to expanding the allowable fields within a Container's SecurityContext. # diff --git a/pkg/apis/config/features.go b/pkg/apis/config/features.go index 10bde135f6d2..4174ff112790 100644 --- a/pkg/apis/config/features.go +++ b/pkg/apis/config/features.go @@ -40,15 +40,16 @@ const ( func defaultFeaturesConfig() *Features { return &Features{ - MultiContainer: Enabled, - PodSpecAffinity: Disabled, - PodSpecFieldRef: Disabled, - PodSpecDryRun: Allowed, - PodSpecNodeSelector: Disabled, - PodSpecSecurityContext: Disabled, - PodSpecTolerations: Disabled, - ResponsiveRevisionGC: Disabled, - TagHeaderBasedRouting: Disabled, + MultiContainer: Enabled, + PodSpecAffinity: Disabled, + PodSpecDryRun: Allowed, + PodSpecFieldRef: Disabled, + PodSpecNodeSelector: Disabled, + PodSpecRuntimeClassName: Disabled, + PodSpecSecurityContext: Disabled, + PodSpecTolerations: Disabled, + ResponsiveRevisionGC: Disabled, + TagHeaderBasedRouting: Disabled, } } @@ -59,9 +60,10 @@ func NewFeaturesConfigFromMap(data map[string]string) (*Features, error) { if err := cm.Parse(data, asFlag("multi-container", &nc.MultiContainer), asFlag("kubernetes.podspec-affinity", &nc.PodSpecAffinity), - asFlag("kubernetes.podspec-fieldref", &nc.PodSpecFieldRef), asFlag("kubernetes.podspec-dryrun", &nc.PodSpecDryRun), + asFlag("kubernetes.podspec-fieldref", &nc.PodSpecFieldRef), asFlag("kubernetes.podspec-nodeselector", &nc.PodSpecNodeSelector), + asFlag("kubernetes.podspec-runtimeclassname", &nc.PodSpecRuntimeClassName), asFlag("kubernetes.podspec-securitycontext", &nc.PodSpecSecurityContext), asFlag("kubernetes.podspec-tolerations", &nc.PodSpecTolerations), asFlag("responsive-revision-gc", &nc.ResponsiveRevisionGC), @@ -78,15 +80,16 @@ func NewFeaturesConfigFromConfigMap(config *corev1.ConfigMap) (*Features, error) // Features specifies which features are allowed by the webhook. type Features struct { - MultiContainer Flag - PodSpecAffinity Flag - PodSpecFieldRef Flag - PodSpecDryRun Flag - PodSpecNodeSelector Flag - PodSpecTolerations Flag - PodSpecSecurityContext Flag - ResponsiveRevisionGC Flag - TagHeaderBasedRouting Flag + MultiContainer Flag + PodSpecAffinity Flag + PodSpecDryRun Flag + PodSpecFieldRef Flag + PodSpecNodeSelector Flag + PodSpecRuntimeClassName Flag + PodSpecSecurityContext Flag + PodSpecTolerations Flag + ResponsiveRevisionGC Flag + TagHeaderBasedRouting Flag } // asFlag parses the value at key as a Flag into the target, if it exists. diff --git a/pkg/apis/config/features_test.go b/pkg/apis/config/features_test.go index f43e059d58f6..587040546262 100644 --- a/pkg/apis/config/features_test.go +++ b/pkg/apis/config/features_test.go @@ -59,24 +59,26 @@ func TestFeaturesConfiguration(t *testing.T) { name: "features Enabled", wantErr: false, wantFeatures: defaultWith(&Features{ - MultiContainer: Enabled, - PodSpecAffinity: Enabled, - PodSpecDryRun: Enabled, - PodSpecNodeSelector: Enabled, - PodSpecSecurityContext: Enabled, - PodSpecTolerations: Enabled, - ResponsiveRevisionGC: Enabled, - TagHeaderBasedRouting: Enabled, + MultiContainer: Enabled, + PodSpecAffinity: Enabled, + PodSpecDryRun: Enabled, + PodSpecNodeSelector: Enabled, + PodSpecRuntimeClassName: Enabled, + PodSpecSecurityContext: Enabled, + PodSpecTolerations: Enabled, + ResponsiveRevisionGC: Enabled, + TagHeaderBasedRouting: Enabled, }), data: map[string]string{ - "multi-container": "Enabled", - "kubernetes.podspec-affinity": "Enabled", - "kubernetes.podspec-dryrun": "Enabled", - "kubernetes.podspec-nodeselector": "Enabled", - "kubernetes.podspec-securitycontext": "Enabled", - "kubernetes.podspec-tolerations": "Enabled", - "responsive-revision-gc": "Enabled", - "tag-header-based-routing": "Enabled", + "multi-container": "Enabled", + "kubernetes.podspec-affinity": "Enabled", + "kubernetes.podspec-dryrun": "Enabled", + "kubernetes.podspec-nodeselector": "Enabled", + "kubernetes.podspec-runtimeclassname": "Enabled", + "kubernetes.podspec-securitycontext": "Enabled", + "kubernetes.podspec-tolerations": "Enabled", + "responsive-revision-gc": "Enabled", + "tag-header-based-routing": "Enabled", }, }, { name: "multi-container Allowed", @@ -186,6 +188,33 @@ func TestFeaturesConfiguration(t *testing.T) { data: map[string]string{ "kubernetes.podspec-nodeselector": "Disabled", }, + }, { + name: "kubernetes.podspec-runtimeclassname Allowed", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecRuntimeClassName: Allowed, + }), + data: map[string]string{ + "kubernetes.podspec-runtimeclassname": "Allowed", + }, + }, { + name: "kubernetes.podspec-runtimeclassname Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecRuntimeClassName: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-runtimeclassname": "Enabled", + }, + }, { + name: "kubernetes.podspec-runtimeclassname Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecRuntimeClassName: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-runtimeclassname": "Disabled", + }, }, { name: "kubernetes.podspec-tolerations Allowed", wantErr: false, diff --git a/pkg/apis/serving/fieldmask.go b/pkg/apis/serving/fieldmask.go index aa3ee98b1abe..f345031f55f6 100644 --- a/pkg/apis/serving/fieldmask.go +++ b/pkg/apis/serving/fieldmask.go @@ -161,6 +161,9 @@ func PodSpecMask(ctx context.Context, in *corev1.PodSpec) *corev1.PodSpec { if cfg.Features.PodSpecNodeSelector != config.Disabled { out.NodeSelector = in.NodeSelector } + if cfg.Features.PodSpecRuntimeClassName != config.Disabled { + out.RuntimeClassName = in.RuntimeClassName + } if cfg.Features.PodSpecTolerations != config.Disabled { out.Tolerations = in.Tolerations } @@ -189,7 +192,6 @@ func PodSpecMask(ctx context.Context, in *corev1.PodSpec) *corev1.PodSpec { out.Priority = nil out.DNSConfig = nil out.ReadinessGates = nil - out.RuntimeClassName = nil return out }