Merge pull request #111229 from ravisantoshgudimetla/promote-podOS-GA

Promote pod OS  to GA
This commit is contained in:
Kubernetes Prow Robot 2022-07-19 10:12:19 -07:00 committed by GitHub
commit 4885f4d750
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 89 additions and 358 deletions

View File

@ -7860,7 +7860,7 @@
},
"os": {
"$ref": "#/definitions/io.k8s.api.core.v1.PodOS",
"description": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is a beta field and requires the IdentifyPodOS feature"
"description": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup"
},
"overhead": {
"additionalProperties": {

View File

@ -5083,7 +5083,7 @@
"$ref": "#/components/schemas/io.k8s.api.core.v1.PodOS"
}
],
"description": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is a beta field and requires the IdentifyPodOS feature"
"description": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup"
},
"overhead": {
"additionalProperties": {

View File

@ -3506,7 +3506,7 @@
"$ref": "#/components/schemas/io.k8s.api.core.v1.PodOS"
}
],
"description": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is a beta field and requires the IdentifyPodOS feature"
"description": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup"
},
"overhead": {
"additionalProperties": {

View File

@ -2585,7 +2585,7 @@
"$ref": "#/components/schemas/io.k8s.api.core.v1.PodOS"
}
],
"description": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is a beta field and requires the IdentifyPodOS feature"
"description": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup"
},
"overhead": {
"additionalProperties": {

View File

@ -418,8 +418,6 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po
AllowWindowsHostProcessField: utilfeature.DefaultFeatureGate.Enabled(features.WindowsHostProcessContainers),
// Allow pod spec with expanded DNS configuration
AllowExpandedDNSConfig: utilfeature.DefaultFeatureGate.Enabled(features.ExpandedDNSConfig) || haveSameExpandedDNSConfig(podSpec, oldPodSpec),
// Allow pod spec to use OS field
AllowOSField: utilfeature.DefaultFeatureGate.Enabled(features.IdentifyPodOS),
}
if oldPodSpec != nil {
@ -435,9 +433,6 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po
// if old spec has Windows Host Process fields set, we must allow it
opts.AllowWindowsHostProcessField = opts.AllowWindowsHostProcessField || setsWindowsHostProcess(oldPodSpec)
// if old spec has OS field set, we must allow it
opts.AllowOSField = opts.AllowOSField || oldPodSpec.OS != nil
// if old spec used non-integer multiple of huge page unit size, we must allow it
opts.AllowIndivisibleHugePagesValues = usesIndivisibleHugePagesValues(oldPodSpec)
@ -556,10 +551,6 @@ func dropDisabledFields(
dropDisabledCSIVolumeSourceAlphaFields(podSpec, oldPodSpec)
if !utilfeature.DefaultFeatureGate.Enabled(features.IdentifyPodOS) && !podOSInUse(oldPodSpec) {
podSpec.OS = nil
}
dropDisabledTopologySpreadConstraintsFields(podSpec, oldPodSpec)
dropDisabledNodeInclusionPolicyFields(podSpec, oldPodSpec)
}
@ -591,17 +582,6 @@ func minDomainsInUse(podSpec *api.PodSpec) bool {
return false
}
// podOSInUse returns true if the pod spec is non-nil and has OS field set
func podOSInUse(podSpec *api.PodSpec) bool {
if podSpec == nil {
return false
}
if podSpec.OS != nil {
return true
}
return false
}
// dropDisabledProcMountField removes disabled fields from PodSpec related
// to ProcMount only if it is not already used by the old spec
func dropDisabledProcMountField(podSpec, oldPodSpec *api.PodSpec) {

View File

@ -1687,88 +1687,6 @@ func TestDropDisabledTopologySpreadConstraintsFields(t *testing.T) {
}
}
func TestDropOSField(t *testing.T) {
podWithOSField := func() *api.Pod {
osField := api.PodOS{Name: "linux"}
return &api.Pod{
Spec: api.PodSpec{
OS: &osField,
},
}
}
podWithoutOSField := func() *api.Pod { return &api.Pod{} }
podInfo := []struct {
description string
hasPodOSField bool
pod func() *api.Pod
}{
{
description: "has PodOS field",
hasPodOSField: true,
pod: podWithOSField,
},
{
description: "does not have PodOS field",
hasPodOSField: false,
pod: podWithoutOSField,
},
{
description: "is nil",
hasPodOSField: false,
pod: func() *api.Pod { return nil },
},
}
for _, enabled := range []bool{true, false} {
for _, oldPodInfo := range podInfo {
for _, newPodInfo := range podInfo {
oldPodHasOsField, oldPod := oldPodInfo.hasPodOSField, oldPodInfo.pod()
newPodHasOSField, newPod := newPodInfo.hasPodOSField, newPodInfo.pod()
if newPod == nil {
continue
}
t.Run(fmt.Sprintf("feature enabled=%v, old pod %v, new pod %v", enabled, oldPodInfo.description, newPodInfo.description), func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IdentifyPodOS, enabled)()
var oldPodSpec *api.PodSpec
if oldPod != nil {
oldPodSpec = &oldPod.Spec
}
dropDisabledFields(&newPod.Spec, nil, oldPodSpec, nil)
// old pod should never be changed
if !reflect.DeepEqual(oldPod, oldPodInfo.pod()) {
t.Errorf("old pod changed: %v", cmp.Diff(oldPod, oldPodInfo.pod()))
}
switch {
case enabled || oldPodHasOsField:
// new pod should not be changed if the feature is enabled, or if the old pod had subpaths
if !reflect.DeepEqual(newPod, newPodInfo.pod()) {
t.Errorf("new pod changed: %v", cmp.Diff(newPod, newPodInfo.pod()))
}
case newPodHasOSField:
// new pod should be changed
if reflect.DeepEqual(newPod, newPodInfo.pod()) {
t.Errorf("new pod was not changed")
}
// new pod should not have OSfield
if !reflect.DeepEqual(newPod, podWithoutOSField()) {
t.Errorf("new pod has OS field: %v", cmp.Diff(newPod, podWithoutOSField()))
}
default:
// new pod should not need to be changed
if !reflect.DeepEqual(newPod, newPodInfo.pod()) {
t.Errorf("new pod changed: %v", cmp.Diff(newPod, newPodInfo.pod()))
}
}
})
}
}
}
}
func TestDropNodeInclusionPolicyFields(t *testing.T) {
ignore := api.NodeInclusionPolicyIgnore
honor := api.NodeInclusionPolicyHonor

View File

@ -2992,7 +2992,6 @@ type PodSpec struct {
// - spec.containers[*].securityContext.runAsUser
// - spec.containers[*].securityContext.runAsGroup
// +optional
// This is a beta field and requires the IdentifyPodOS feature
OS *PodOS
}

View File

@ -3413,8 +3413,6 @@ type PodValidationOptions struct {
AllowWindowsHostProcessField bool
// Allow more DNSSearchPaths and longer DNSSearchListChars
AllowExpandedDNSConfig bool
// Allow OSField to be set in the pod spec
AllowOSField bool
}
// validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set,
@ -6362,9 +6360,6 @@ func validateOS(podSpec *core.PodSpec, fldPath *field.Path, opts PodValidationOp
if os == nil {
return allErrs
}
if !opts.AllowOSField {
return append(allErrs, field.Forbidden(fldPath, "cannot be set when IdentifyPodOS feature is not enabled"))
}
if len(os.Name) == 0 {
return append(allErrs, field.Required(fldPath.Child("name"), "cannot be empty"))
}

View File

@ -6928,40 +6928,24 @@ func TestValidateWindowsPodSecurityContext(t *testing.T) {
validWindowsSC := &core.PodSecurityContext{WindowsOptions: &core.WindowsSecurityContextOptions{RunAsUserName: utilpointer.String("dummy")}}
invalidWindowsSC := &core.PodSecurityContext{SELinuxOptions: &core.SELinuxOptions{Role: "dummyRole"}}
cases := map[string]struct {
podSec *core.PodSpec
expectErr bool
errorType field.ErrorType
errorDetail string
featureEnabled bool
podSec *core.PodSpec
expectErr bool
errorType field.ErrorType
errorDetail string
}{
"valid SC, windows, no error": {
podSec: &core.PodSpec{SecurityContext: validWindowsSC},
expectErr: false,
featureEnabled: true,
podSec: &core.PodSpec{SecurityContext: validWindowsSC},
expectErr: false,
},
"invalid SC, windows, error": {
podSec: &core.PodSpec{SecurityContext: invalidWindowsSC},
errorType: "FieldValueForbidden",
errorDetail: "cannot be set for a windows pod",
expectErr: true,
featureEnabled: true,
},
"valid SC, windows, no error, no IdentifyPodOS featuregate": {
podSec: &core.PodSpec{SecurityContext: validWindowsSC},
expectErr: false,
featureEnabled: false,
},
"invalid SC, windows, error, no IdentifyPodOS featuregate": {
podSec: &core.PodSpec{SecurityContext: invalidWindowsSC},
errorType: "FieldValueForbidden",
errorDetail: "cannot be set for a windows pod",
expectErr: true,
featureEnabled: false,
podSec: &core.PodSpec{SecurityContext: invalidWindowsSC},
errorType: "FieldValueForbidden",
errorDetail: "cannot be set for a windows pod",
expectErr: true,
},
}
for k, v := range cases {
t.Run(k, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IdentifyPodOS, v.featureEnabled)()
errs := validateWindows(v.podSec, field.NewPath("field"))
if v.expectErr && len(errs) > 0 {
if errs[0].Type != v.errorType || !strings.Contains(errs[0].Detail, v.errorDetail) {
@ -6993,40 +6977,24 @@ func TestValidateLinuxPodSecurityContext(t *testing.T) {
}
cases := map[string]struct {
podSpec *core.PodSpec
expectErr bool
errorType field.ErrorType
errorDetail string
featureEnabled bool
podSpec *core.PodSpec
expectErr bool
errorType field.ErrorType
errorDetail string
}{
"valid SC, linux, no error": {
podSpec: &core.PodSpec{SecurityContext: validLinuxSC},
expectErr: false,
featureEnabled: true,
podSpec: &core.PodSpec{SecurityContext: validLinuxSC},
expectErr: false,
},
"invalid SC, linux, error": {
podSpec: &core.PodSpec{SecurityContext: invalidLinuxSC},
errorType: "FieldValueForbidden",
errorDetail: "windows options cannot be set for a linux pod",
expectErr: true,
featureEnabled: true,
},
"valid SC, linux, no error, no IdentifyPodOS featuregate": {
podSpec: &core.PodSpec{SecurityContext: validLinuxSC},
expectErr: false,
featureEnabled: false,
},
"invalid SC, linux, error, no IdentifyPodOS featuregate": {
podSpec: &core.PodSpec{SecurityContext: invalidLinuxSC},
errorType: "FieldValueForbidden",
errorDetail: "windows options cannot be set for a linux pod",
expectErr: true,
featureEnabled: false,
podSpec: &core.PodSpec{SecurityContext: invalidLinuxSC},
errorType: "FieldValueForbidden",
errorDetail: "windows options cannot be set for a linux pod",
expectErr: true,
},
}
for k, v := range cases {
t.Run(k, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IdentifyPodOS, v.featureEnabled)()
errs := validateLinux(v.podSpec, field.NewPath("field"))
if v.expectErr && len(errs) > 0 {
if errs[0].Type != v.errorType || !strings.Contains(errs[0].Detail, v.errorDetail) {
@ -10041,11 +10009,10 @@ func TestValidatePodUpdate(t *testing.T) {
)
tests := []struct {
new core.Pod
old core.Pod
err string
test string
enablePodOS bool
new core.Pod
old core.Pod
err string
test string
}{
{new: core.Pod{}, old: core.Pod{}, err: "", test: "nothing"},
{
@ -10869,9 +10836,8 @@ func TestValidatePodUpdate(t *testing.T) {
SecurityContext: &core.PodSecurityContext{SELinuxOptions: &core.SELinuxOptions{Role: "dummy"}},
},
},
err: "Forbidden: pod updates may not change fields other than `spec.containers[*].image`,",
test: "pod OS changing from Linux to Windows, no IdentifyPodOS featuregate set, no validation done",
enablePodOS: false,
err: "Forbidden: pod updates may not change fields other than `spec.containers[*].image",
test: "pod OS changing from Linux to Windows, IdentifyPodOS featuregate set",
},
{
new: core.Pod{
@ -10892,32 +10858,8 @@ func TestValidatePodUpdate(t *testing.T) {
SecurityContext: &core.PodSecurityContext{SELinuxOptions: &core.SELinuxOptions{Role: "dummy"}},
},
},
err: "Forbidden: pod updates may not change fields other than `spec.containers[*].image",
test: "pod OS changing from Linux to Windows, IdentifyPodOS featuregate set",
enablePodOS: true,
},
{
new: core.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
Spec: core.PodSpec{
OS: &core.PodOS{Name: core.Windows},
SecurityContext: &core.PodSecurityContext{SELinuxOptions: &core.SELinuxOptions{Role: "dummy"}},
},
},
old: core.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
Spec: core.PodSpec{
OS: &core.PodOS{Name: core.Linux},
SecurityContext: &core.PodSecurityContext{SELinuxOptions: &core.SELinuxOptions{Role: "dummy"}},
},
},
err: "spec.securityContext.seLinuxOptions: Forbidden",
test: "pod OS changing from Linux to Windows, IdentifyPodOS featuregate set, we'd get SELinux errors as well",
enablePodOS: true,
err: "spec.securityContext.seLinuxOptions: Forbidden",
test: "pod OS changing from Linux to Windows, IdentifyPodOS featuregate set, we'd get SELinux errors as well",
},
{
new: core.Pod{
@ -10934,28 +10876,8 @@ func TestValidatePodUpdate(t *testing.T) {
},
Spec: core.PodSpec{},
},
err: "Forbidden: pod updates may not change fields other than `spec.containers[*].image",
test: "invalid PodOS update, IdentifyPodOS featuregate set",
enablePodOS: true,
},
{
new: core.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
Spec: core.PodSpec{
OS: &core.PodOS{Name: core.Windows},
},
},
old: core.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
Spec: core.PodSpec{},
},
err: "Forbidden: pod updates may not change fields other than `spec.containers[*].image",
test: "no pod spec OS to a valid value, no featuregate",
enablePodOS: false,
err: "Forbidden: pod updates may not change fields other than `spec.containers[*].image",
test: "invalid PodOS update, IdentifyPodOS featuregate set",
},
{
new: core.Pod{
@ -11004,7 +10926,7 @@ func TestValidatePodUpdate(t *testing.T) {
test.old.Spec.RestartPolicy = "Always"
}
errs := ValidatePodUpdate(&test.new, &test.old, PodValidationOptions{AllowOSField: test.enablePodOS})
errs := ValidatePodUpdate(&test.new, &test.old, PodValidationOptions{})
if test.err == "" {
if len(errs) != 0 {
t.Errorf("unexpected invalid: %s (%+v)\nA: %+v\nB: %+v", test.test, errs, test.new, test.old)
@ -17581,61 +17503,34 @@ func TestValidateEndpointsUpdate(t *testing.T) {
func TestValidateWindowsSecurityContext(t *testing.T) {
tests := []struct {
name string
sc *core.PodSpec
expectError bool
errorMsg string
errorType field.ErrorType
featureEnabled bool
name string
sc *core.PodSpec
expectError bool
errorMsg string
errorType field.ErrorType
}{
{
name: "pod with SELinux Options",
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: &core.SecurityContext{SELinuxOptions: &core.SELinuxOptions{Role: "dummy"}}}}},
expectError: true,
errorMsg: "cannot be set for a windows pod",
errorType: "FieldValueForbidden",
featureEnabled: true,
name: "pod with SELinux Options",
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: &core.SecurityContext{SELinuxOptions: &core.SELinuxOptions{Role: "dummy"}}}}},
expectError: true,
errorMsg: "cannot be set for a windows pod",
errorType: "FieldValueForbidden",
},
{
name: "pod with SeccompProfile",
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: &core.SecurityContext{SeccompProfile: &core.SeccompProfile{LocalhostProfile: utilpointer.String("dummy")}}}}},
expectError: true,
errorMsg: "cannot be set for a windows pod",
errorType: "FieldValueForbidden",
featureEnabled: true,
name: "pod with SeccompProfile",
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: &core.SecurityContext{SeccompProfile: &core.SeccompProfile{LocalhostProfile: utilpointer.String("dummy")}}}}},
expectError: true,
errorMsg: "cannot be set for a windows pod",
errorType: "FieldValueForbidden",
},
{
name: "pod with WindowsOptions, no error",
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: &core.SecurityContext{WindowsOptions: &core.WindowsSecurityContextOptions{RunAsUserName: utilpointer.String("dummy")}}}}},
expectError: false,
featureEnabled: true,
},
{
name: "pod with SELinux Options, no IdentifyPodOS enabled",
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: &core.SecurityContext{SELinuxOptions: &core.SELinuxOptions{Role: "dummy"}}}}},
expectError: true,
errorMsg: "cannot be set for a windows pod",
errorType: "FieldValueForbidden",
featureEnabled: false,
},
{
name: "pod with SeccompProfile, no IdentifyPodOS enabled",
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: &core.SecurityContext{SeccompProfile: &core.SeccompProfile{LocalhostProfile: utilpointer.String("dummy")}}}}},
expectError: true,
errorMsg: "cannot be set for a windows pod",
errorType: "FieldValueForbidden",
featureEnabled: false,
},
{
name: "pod with WindowsOptions, no error, no IdentifyPodOS enabled",
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: &core.SecurityContext{WindowsOptions: &core.WindowsSecurityContextOptions{RunAsUserName: utilpointer.String("dummy")}}}}},
expectError: false,
featureEnabled: false,
name: "pod with WindowsOptions, no error",
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: &core.SecurityContext{WindowsOptions: &core.WindowsSecurityContextOptions{RunAsUserName: utilpointer.String("dummy")}}}}},
expectError: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IdentifyPodOS, test.featureEnabled)()
errs := validateWindows(test.sc, field.NewPath("field"))
if test.expectError && len(errs) > 0 {
if errs[0].Type != test.errorType {
@ -17920,40 +17815,24 @@ func TestValidateLinuxSecurityContext(t *testing.T) {
WindowsOptions: &core.WindowsSecurityContextOptions{RunAsUserName: utilpointer.String("myUser")},
}
cases := map[string]struct {
sc *core.PodSpec
expectErr bool
errorType field.ErrorType
errorDetail string
featureEnabled bool
sc *core.PodSpec
expectErr bool
errorType field.ErrorType
errorDetail string
}{
"valid SC, linux, no error": {
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: validLinuxSC}}},
expectErr: false,
featureEnabled: true,
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: validLinuxSC}}},
expectErr: false,
},
"invalid SC, linux, error": {
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: invalidLinuxSC}}},
errorType: "FieldValueForbidden",
errorDetail: "windows options cannot be set for a linux pod",
expectErr: true,
featureEnabled: true,
},
"valid SC, linux, no error, no IdentifyPodOS featuregate": {
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: validLinuxSC}}},
expectErr: false,
featureEnabled: false,
},
"invalid SC, linux, error, no IdentifyPodOS featuregate": {
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: invalidLinuxSC}}},
errorType: "FieldValueForbidden",
errorDetail: "windows options cannot be set for a linux pod",
expectErr: true,
featureEnabled: false,
sc: &core.PodSpec{Containers: []core.Container{{SecurityContext: invalidLinuxSC}}},
errorType: "FieldValueForbidden",
errorDetail: "windows options cannot be set for a linux pod",
expectErr: true,
},
}
for k, v := range cases {
t.Run(k, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IdentifyPodOS, v.featureEnabled)()
errs := validateLinux(v.sc, field.NewPath("field"))
if v.expectErr && len(errs) > 0 {
if errs[0].Type != v.errorType || !strings.Contains(errs[0].Detail, v.errorDetail) {
@ -20454,83 +20333,44 @@ func TestValidateWindowsHostProcessPod(t *testing.T) {
func TestValidateOS(t *testing.T) {
testCases := []struct {
name string
expectError bool
featureEnabled bool
podSpec *core.PodSpec
name string
expectError bool
podSpec *core.PodSpec
}{
{
name: "no OS field, featuregate",
expectError: false,
featureEnabled: true,
podSpec: &core.PodSpec{OS: nil},
name: "no OS field, featuregate",
expectError: false,
podSpec: &core.PodSpec{OS: nil},
},
{
name: "empty OS field, featuregate",
expectError: true,
featureEnabled: true,
podSpec: &core.PodSpec{OS: &core.PodOS{}},
name: "empty OS field, featuregate",
expectError: true,
podSpec: &core.PodSpec{OS: &core.PodOS{}},
},
{
name: "no OS field, no featuregate",
expectError: false,
featureEnabled: false,
podSpec: &core.PodSpec{OS: nil},
name: "OS field, featuregate, valid OS",
expectError: false,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: core.Linux}},
},
{
name: "empty OS field, no featuregate",
expectError: true,
featureEnabled: false,
podSpec: &core.PodSpec{OS: &core.PodOS{}},
name: "OS field, featuregate, valid OS",
expectError: false,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: core.Windows}},
},
{
name: "OS field, featuregate, valid OS",
expectError: false,
featureEnabled: true,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: core.Linux}},
name: "OS field, featuregate, empty OS",
expectError: true,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: ""}},
},
{
name: "OS field, featuregate, valid OS",
expectError: false,
featureEnabled: true,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: core.Windows}},
},
{
name: "OS field, featuregate, empty OS",
expectError: true,
featureEnabled: true,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: ""}},
},
{
name: "OS field, no featuregate, empty OS",
expectError: true,
featureEnabled: false,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: ""}},
},
{
name: "OS field, featuregate, invalid OS",
expectError: true,
featureEnabled: true,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: "dummyOS"}},
},
{
name: "OS field, no featuregate, valid OS",
expectError: true,
featureEnabled: false,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: core.Linux}},
},
{
name: "OS field, no featuregate, invalid OS",
expectError: true,
featureEnabled: false,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: "dummyOS"}},
name: "OS field, featuregate, invalid OS",
expectError: true,
podSpec: &core.PodSpec{OS: &core.PodOS{Name: "dummyOS"}},
},
}
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IdentifyPodOS, testCase.featureEnabled)()
errs := validateOS(testCase.podSpec, field.NewPath("spec"), PodValidationOptions{AllowOSField: testCase.featureEnabled})
errs := validateOS(testCase.podSpec, field.NewPath("spec"), PodValidationOptions{})
if testCase.expectError && len(errs) == 0 {
t.Errorf("Unexpected success")
}

View File

@ -374,6 +374,7 @@ const (
// owner: @ravig
// alpha: v1.23
// beta: v1.24
// GA: v1.25
// IdentifyPodOS allows user to specify OS on which they'd like the Pod run. The user should still set the nodeSelector
// with appropriate `kubernetes.io/os` label for scheduler to identify appropriate node for the pod to run.
IdentifyPodOS featuregate.Feature = "IdentifyPodOS"
@ -905,7 +906,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
HonorPVReclaimPolicy: {Default: false, PreRelease: featuregate.Alpha},
IdentifyPodOS: {Default: true, PreRelease: featuregate.Beta},
IdentifyPodOS: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.27
InTreePluginAWSUnregister: {Default: false, PreRelease: featuregate.Alpha},

View File

@ -22176,7 +22176,7 @@ func schema_k8sio_api_core_v1_PodSpec(ref common.ReferenceCallback) common.OpenA
},
"os": {
SchemaProps: spec.SchemaProps{
Description: "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is a beta field and requires the IdentifyPodOS feature",
Description: "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup",
Ref: ref("k8s.io/api/core/v1.PodOS"),
},
},

View File

@ -3728,7 +3728,6 @@ message PodSpec {
// - spec.containers[*].securityContext.runAsUser
// - spec.containers[*].securityContext.runAsGroup
// +optional
// This is a beta field and requires the IdentifyPodOS feature
optional PodOS os = 36;
}

View File

@ -3305,7 +3305,6 @@ type PodSpec struct {
// - spec.containers[*].securityContext.runAsUser
// - spec.containers[*].securityContext.runAsGroup
// +optional
// This is a beta field and requires the IdentifyPodOS feature
OS *PodOS `json:"os,omitempty" protobuf:"bytes,36,opt,name=os"`
}

View File

@ -1670,7 +1670,7 @@ var map_PodSpec = map[string]string{
"overhead": "Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. This field will be autopopulated at admission time by the RuntimeClass admission controller. If the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. The RuntimeClass admission controller will reject Pod create requests which have the overhead already set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md",
"topologySpreadConstraints": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed.",
"setHostnameAsFQDN": "If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. If a pod does not have FQDN, this has no effect. Default to false.",
"os": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup This is a beta field and requires the IdentifyPodOS feature",
"os": "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set.\n\nIf the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions\n\nIf the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup",
}
func (PodSpec) SwaggerDoc() map[string]string {