Field status.hostIPs
added for Pod (#101566)
* Add FeatureGate PodHostIPs * Add HostIPs field and update PodIPs field * Types conversion * Add dropDisabledStatusFields * Add HostIPs for kubelet * Add fuzzer for PodStatus * Add status.hostIPs in ConvertDownwardAPIFieldLabel * Add status.hostIPs in validEnvDownwardAPIFieldPathExpressions * Downward API support for status.hostIPs * Add DownwardAPI validation for status.hostIPs * Add e2e to check that hostIPs works * Add e2e to check that Downward API works * Regenerate
This commit is contained in:
@@ -1044,6 +1044,7 @@ func validateDownwardAPIVolumeFile(file *core.DownwardAPIVolumeFile, fldPath *fi
|
||||
if file.ResourceFieldRef != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, "resource", "fieldRef and resourceFieldRef can not be specified simultaneously"))
|
||||
}
|
||||
allErrs = append(allErrs, validateDownwardAPIHostIPs(file.FieldRef, fldPath.Child("fieldRef"), opts)...)
|
||||
} else if file.ResourceFieldRef != nil {
|
||||
localValidContainerResourceFieldPathPrefixes := validContainerResourceFieldPathPrefixes
|
||||
if opts.AllowDownwardAPIHugePages {
|
||||
@@ -2329,8 +2330,10 @@ var validEnvDownwardAPIFieldPathExpressions = sets.NewString(
|
||||
"spec.nodeName",
|
||||
"spec.serviceAccountName",
|
||||
"status.hostIP",
|
||||
"status.hostIPs",
|
||||
"status.podIP",
|
||||
"status.podIPs")
|
||||
"status.podIPs",
|
||||
)
|
||||
|
||||
var validContainerResourceFieldPathExpressions = sets.NewString("limits.cpu", "limits.memory", "limits.ephemeral-storage", "requests.cpu", "requests.memory", "requests.ephemeral-storage")
|
||||
|
||||
@@ -2353,6 +2356,7 @@ func validateEnvVarValueFrom(ev core.EnvVar, fldPath *field.Path, opts PodValida
|
||||
if ev.ValueFrom.FieldRef != nil {
|
||||
numSources++
|
||||
allErrs = append(allErrs, validateObjectFieldSelector(ev.ValueFrom.FieldRef, &validEnvDownwardAPIFieldPathExpressions, fldPath.Child("fieldRef"))...)
|
||||
allErrs = append(allErrs, validateDownwardAPIHostIPs(ev.ValueFrom.FieldRef, fldPath.Child("fieldRef"), opts)...)
|
||||
}
|
||||
if ev.ValueFrom.ResourceFieldRef != nil {
|
||||
numSources++
|
||||
@@ -2423,6 +2427,16 @@ func validateObjectFieldSelector(fs *core.ObjectFieldSelector, expressions *sets
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateDownwardAPIHostIPs(fieldSel *core.ObjectFieldSelector, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if !opts.AllowHostIPsField {
|
||||
if fieldSel.FieldPath == "status.hostIPs" {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, "status.hostIPs", "not allowed when feature gate 'PodHostIPs' is not enabled"))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateContainerResourceFieldSelector(fs *core.ResourceFieldSelector, expressions *sets.String, prefixes *sets.String, fldPath *field.Path, volume bool) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
@@ -3415,6 +3429,8 @@ type PodValidationOptions struct {
|
||||
AllowExpandedDNSConfig bool
|
||||
// Allow OSField to be set in the pod spec
|
||||
AllowOSField bool
|
||||
// Allow pod spec to use status.hostIPs in downward API
|
||||
AllowHostIPsField bool
|
||||
// Allow sysctl name to contain a slash
|
||||
AllowSysctlRegexContainSlash bool
|
||||
}
|
||||
|
@@ -5688,7 +5688,7 @@ func TestValidateEnv(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}},
|
||||
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP", "status.podIPs"`,
|
||||
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.hostIPs", "status.podIP", "status.podIPs"`,
|
||||
},
|
||||
{
|
||||
name: "metadata.annotations without subscript",
|
||||
@@ -5701,7 +5701,7 @@ func TestValidateEnv(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}},
|
||||
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.annotations": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP", "status.podIPs"`,
|
||||
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.annotations": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.hostIPs", "status.podIP", "status.podIPs"`,
|
||||
},
|
||||
{
|
||||
name: "metadata.annotations with invalid key",
|
||||
@@ -5740,7 +5740,7 @@ func TestValidateEnv(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}},
|
||||
expectedError: `valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP", "status.podIPs"`,
|
||||
expectedError: `valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.hostIPs", "status.podIP", "status.podIPs"`,
|
||||
},
|
||||
}
|
||||
for _, tc := range errorCases {
|
||||
@@ -20455,3 +20455,50 @@ func TestValidateAppArmorProfileFormat(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateDownwardAPIHostIPs(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
expectError bool
|
||||
featureEnabled bool
|
||||
fieldSel *core.ObjectFieldSelector
|
||||
}{
|
||||
{
|
||||
name: "has no hostIPs field, featuregate enabled",
|
||||
expectError: false,
|
||||
featureEnabled: true,
|
||||
fieldSel: &core.ObjectFieldSelector{FieldPath: "status.hostIP"},
|
||||
},
|
||||
{
|
||||
name: "has hostIPs field, featuregate enabled",
|
||||
expectError: false,
|
||||
featureEnabled: true,
|
||||
fieldSel: &core.ObjectFieldSelector{FieldPath: "status.hostIPs"},
|
||||
},
|
||||
{
|
||||
name: "has no hostIPs field, featuregate disabled",
|
||||
expectError: false,
|
||||
featureEnabled: false,
|
||||
fieldSel: &core.ObjectFieldSelector{FieldPath: "status.hostIP"},
|
||||
},
|
||||
{
|
||||
name: "has hostIPs field, featuregate disabled",
|
||||
expectError: true,
|
||||
featureEnabled: false,
|
||||
fieldSel: &core.ObjectFieldSelector{FieldPath: "status.hostIPs"},
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodHostIPs, testCase.featureEnabled)()
|
||||
|
||||
errs := validateDownwardAPIHostIPs(testCase.fieldSel, field.NewPath("fieldSel"), PodValidationOptions{AllowHostIPsField: testCase.featureEnabled})
|
||||
if testCase.expectError && len(errs) == 0 {
|
||||
t.Errorf("Unexpected success")
|
||||
}
|
||||
if !testCase.expectError && len(errs) != 0 {
|
||||
t.Errorf("Unexpected error(s): %v", errs)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user