Merge pull request #46909 from derekwaynecarr/fix-env-var-validation
Automatic merge from submit-queue (batch tested with PRs 47726, 47693, 46909, 46812) pod spec was not validating envFrom **What this PR does / why we need it**: adds missing validation for envFrom in a pod.spec.containers.envFrom fixes validation of pod.spec.containers.env.configMapRef.name fixes validation of pod.spec.containers.env.secretRef.name **Which issue this PR fixes** Fixes https://github.com/kubernetes/kubernetes/issues/46908
This commit is contained in:
		| @@ -1551,6 +1551,7 @@ func validateContainerPorts(ports []api.ContainerPort, fldPath *field.Path) fiel | ||||
| 	return allErrs | ||||
| } | ||||
|  | ||||
| // ValidateEnv validates env vars | ||||
| func ValidateEnv(vars []api.EnvVar, fldPath *field.Path) field.ErrorList { | ||||
| 	allErrs := field.ErrorList{} | ||||
|  | ||||
| @@ -1721,8 +1722,9 @@ func validateContainerResourceDivisor(rName string, divisor resource.Quantity, f | ||||
| func validateConfigMapKeySelector(s *api.ConfigMapKeySelector, fldPath *field.Path) field.ErrorList { | ||||
| 	allErrs := field.ErrorList{} | ||||
|  | ||||
| 	if len(s.Name) == 0 { | ||||
| 		allErrs = append(allErrs, field.Required(fldPath.Child("name"), "")) | ||||
| 	nameFn := ValidateNameFunc(ValidateSecretName) | ||||
| 	for _, msg := range nameFn(s.Name, false) { | ||||
| 		allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), s.Name, msg)) | ||||
| 	} | ||||
| 	if len(s.Key) == 0 { | ||||
| 		allErrs = append(allErrs, field.Required(fldPath.Child("key"), "")) | ||||
| @@ -1738,8 +1740,9 @@ func validateConfigMapKeySelector(s *api.ConfigMapKeySelector, fldPath *field.Pa | ||||
| func validateSecretKeySelector(s *api.SecretKeySelector, fldPath *field.Path) field.ErrorList { | ||||
| 	allErrs := field.ErrorList{} | ||||
|  | ||||
| 	if len(s.Name) == 0 { | ||||
| 		allErrs = append(allErrs, field.Required(fldPath.Child("name"), "")) | ||||
| 	nameFn := ValidateNameFunc(ValidateSecretName) | ||||
| 	for _, msg := range nameFn(s.Name, false) { | ||||
| 		allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), s.Name, msg)) | ||||
| 	} | ||||
| 	if len(s.Key) == 0 { | ||||
| 		allErrs = append(allErrs, field.Required(fldPath.Child("key"), "")) | ||||
| @@ -2011,6 +2014,7 @@ func validateContainers(containers []api.Container, volumes sets.String, fldPath | ||||
| 		allErrs = append(allErrs, validateProbe(ctr.ReadinessProbe, idxPath.Child("readinessProbe"))...) | ||||
| 		allErrs = append(allErrs, validateContainerPorts(ctr.Ports, idxPath.Child("ports"))...) | ||||
| 		allErrs = append(allErrs, ValidateEnv(ctr.Env, idxPath.Child("env"))...) | ||||
| 		allErrs = append(allErrs, ValidateEnvFrom(ctr.EnvFrom, idxPath.Child("envFrom"))...) | ||||
| 		allErrs = append(allErrs, ValidateVolumeMounts(ctr.VolumeMounts, volumes, idxPath.Child("volumeMounts"))...) | ||||
| 		allErrs = append(allErrs, validatePullPolicy(ctr.ImagePullPolicy, idxPath.Child("imagePullPolicy"))...) | ||||
| 		allErrs = append(allErrs, ValidateResourceRequirements(&ctr.Resources, idxPath.Child("resources"))...) | ||||
|   | ||||
| @@ -2733,6 +2733,34 @@ func TestValidateEnv(t *testing.T) { | ||||
| 			}}, | ||||
| 			expectedError: `[0].valueFrom: Invalid value: "": may not have more than one field specified at a time`, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "valueFrom.secretKeyRef.name invalid", | ||||
| 			envs: []api.EnvVar{{ | ||||
| 				Name: "abc", | ||||
| 				ValueFrom: &api.EnvVarSource{ | ||||
| 					SecretKeyRef: &api.SecretKeySelector{ | ||||
| 						LocalObjectReference: api.LocalObjectReference{ | ||||
| 							Name: "$%^&*#", | ||||
| 						}, | ||||
| 						Key: "a-key", | ||||
| 					}, | ||||
| 				}, | ||||
| 			}}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "valueFrom.configMapKeyRef.name invalid", | ||||
| 			envs: []api.EnvVar{{ | ||||
| 				Name: "abc", | ||||
| 				ValueFrom: &api.EnvVarSource{ | ||||
| 					ConfigMapKeyRef: &api.ConfigMapKeySelector{ | ||||
| 						LocalObjectReference: api.LocalObjectReference{ | ||||
| 							Name: "$%^&*#", | ||||
| 						}, | ||||
| 						Key: "some-key", | ||||
| 					}, | ||||
| 				}, | ||||
| 			}}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "missing FieldPath on ObjectFieldSelector", | ||||
| 			envs: []api.EnvVar{{ | ||||
| @@ -2939,6 +2967,26 @@ func TestValidateEnvFrom(t *testing.T) { | ||||
| 			}, | ||||
| 			expectedError: "field: Invalid value: \"\": may not have more than one field specified at a time", | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "invalid secret ref name", | ||||
| 			envs: []api.EnvFromSource{ | ||||
| 				{ | ||||
| 					SecretRef: &api.SecretEnvSource{ | ||||
| 						LocalObjectReference: api.LocalObjectReference{Name: "$%^&*#"}}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			expectedError: "field[0].secretRef.name: Invalid value: \"$%^&*#\": " + dnsSubdomainLabelErrMsg, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "invalid config ref name", | ||||
| 			envs: []api.EnvFromSource{ | ||||
| 				{ | ||||
| 					ConfigMapRef: &api.ConfigMapEnvSource{ | ||||
| 						LocalObjectReference: api.LocalObjectReference{Name: "$%^&*#"}}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			expectedError: "field[0].configMapRef.name: Invalid value: \"$%^&*#\": " + dnsSubdomainLabelErrMsg, | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, tc := range errorCases { | ||||
| 		if errs := ValidateEnvFrom(tc.envs, field.NewPath("field")); len(errs) == 0 { | ||||
| @@ -3253,6 +3301,21 @@ func TestValidateContainers(t *testing.T) { | ||||
| 			ImagePullPolicy:          "IfNotPresent", | ||||
| 			TerminationMessagePolicy: "File", | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:                     "env-from-source", | ||||
| 			Image:                    "image", | ||||
| 			ImagePullPolicy:          "IfNotPresent", | ||||
| 			TerminationMessagePolicy: "File", | ||||
| 			EnvFrom: []api.EnvFromSource{ | ||||
| 				{ | ||||
| 					ConfigMapRef: &api.ConfigMapEnvSource{ | ||||
| 						LocalObjectReference: api.LocalObjectReference{ | ||||
| 							Name: "test", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{Name: "abc-1234", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", SecurityContext: fakeValidSecurityContext(true)}, | ||||
| 	} | ||||
| 	if errs := validateContainers(successCase, volumes, field.NewPath("field")); len(errs) != 0 { | ||||
| @@ -3483,6 +3546,23 @@ func TestValidateContainers(t *testing.T) { | ||||
| 				TerminationMessagePolicy: "File", | ||||
| 			}, | ||||
| 		}, | ||||
| 		"Invalid env from": { | ||||
| 			{ | ||||
| 				Name:                     "env-from-source", | ||||
| 				Image:                    "image", | ||||
| 				ImagePullPolicy:          "IfNotPresent", | ||||
| 				TerminationMessagePolicy: "File", | ||||
| 				EnvFrom: []api.EnvFromSource{ | ||||
| 					{ | ||||
| 						ConfigMapRef: &api.ConfigMapEnvSource{ | ||||
| 							LocalObjectReference: api.LocalObjectReference{ | ||||
| 								Name: "$%^&*#", | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	for k, v := range errorCases { | ||||
| 		if errs := validateContainers(v, volumes, field.NewPath("field")); len(errs) == 0 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Kubernetes Submit Queue
					Kubernetes Submit Queue