Merge pull request #114086 from xmcqueen/113935

block ephemeral container addition to static pods
This commit is contained in:
Kubernetes Prow Robot 2023-01-13 07:36:28 -08:00 committed by GitHub
commit 696701b9fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 289 additions and 0 deletions

View File

@ -4690,6 +4690,11 @@ func ValidatePodEphemeralContainersUpdate(newPod, oldPod *core.Pod, opts PodVali
allErrs = append(allErrs, validatePodMetadataAndSpec(newPod, opts)...)
allErrs = append(allErrs, ValidatePodSpecificAnnotationUpdates(newPod, oldPod, fldPath.Child("annotations"), opts)...)
// static pods don't support ephemeral containers #113935
if _, ok := oldPod.Annotations[core.MirrorPodAnnotationKey]; ok {
return field.ErrorList{field.Forbidden(field.NewPath(""), "static pods do not support ephemeral containers")}
}
// Part 2: Validate that the changes between oldPod.Spec.EphemeralContainers and
// newPod.Spec.EphemeralContainers are allowed.
//

View File

@ -12788,6 +12788,34 @@ func TestValidatePodEphemeralContainersUpdate(t *testing.T) {
makeWindowsHostPod(nil),
"spec.ephemeralContainers[0].securityContext.windowsOptions.hostProcess: Invalid value: false: pod hostProcess value must be identical",
},
{
"Add ephemeral container to static pod",
func() *core.Pod {
p := makePod(nil)
p.Spec.NodeName = "some-name"
p.ObjectMeta.Annotations = map[string]string{
core.MirrorPodAnnotationKey: "foo",
}
p.Spec.EphemeralContainers = []core.EphemeralContainer{{
EphemeralContainerCommon: core.EphemeralContainerCommon{
Name: "debugger1",
Image: "debian",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
}}
return p
}(),
func() *core.Pod {
p := makePod(nil)
p.Spec.NodeName = "some-name"
p.ObjectMeta.Annotations = map[string]string{
core.MirrorPodAnnotationKey: "foo",
}
return p
}(),
"Forbidden: static pods do not support ephemeral containers",
},
}
for _, tc := range tests {

View File

@ -950,6 +950,262 @@ func TestPodStrategyValidate(t *testing.T) {
}
}
func TestEphemeralContainerStrategyValidateUpdate(t *testing.T) {
test := []struct {
name string
newPod *api.Pod
oldPod *api.Pod
}{
{
name: "add ephemeral container to regular pod and expect success",
oldPod: &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Namespace: "test-ns",
ResourceVersion: "1",
},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSDefault,
Containers: []api.Container{
{
Name: "container",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
},
},
newPod: &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Namespace: "test-ns",
ResourceVersion: "1",
},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSDefault,
Containers: []api.Container{
{
Name: "container",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
EphemeralContainers: []api.EphemeralContainer{
{
EphemeralContainerCommon: api.EphemeralContainerCommon{
Name: "debugger",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
},
},
},
},
}
// expect no errors
for _, tc := range test {
t.Run(tc.name, func(t *testing.T) {
if errs := EphemeralContainersStrategy.ValidateUpdate(genericapirequest.NewContext(), tc.newPod, tc.oldPod); len(errs) != 0 {
t.Errorf("unexpected error:%v", errs)
}
})
}
test = []struct {
name string
newPod *api.Pod
oldPod *api.Pod
}{
{
name: "add ephemeral container to static pod and expect failure",
oldPod: &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Namespace: "test-ns",
ResourceVersion: "1",
Annotations: map[string]string{api.MirrorPodAnnotationKey: "someVal"},
},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSDefault,
Containers: []api.Container{
{
Name: "container",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
NodeName: "example.com",
},
},
newPod: &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Namespace: "test-ns",
ResourceVersion: "1",
Annotations: map[string]string{api.MirrorPodAnnotationKey: "someVal"},
},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSDefault,
Containers: []api.Container{
{
Name: "container",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
EphemeralContainers: []api.EphemeralContainer{
{
EphemeralContainerCommon: api.EphemeralContainerCommon{
Name: "debugger",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
},
NodeName: "example.com",
},
},
},
{
name: "remove ephemeral container from regular pod and expect failure",
newPod: &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Namespace: "test-ns",
ResourceVersion: "1",
},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSDefault,
Containers: []api.Container{
{
Name: "container",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
},
},
oldPod: &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Namespace: "test-ns",
ResourceVersion: "1",
},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSDefault,
Containers: []api.Container{
{
Name: "container",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
EphemeralContainers: []api.EphemeralContainer{
{
EphemeralContainerCommon: api.EphemeralContainerCommon{
Name: "debugger",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
},
},
},
},
{
name: "change ephemeral container from regular pod and expect failure",
newPod: &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Namespace: "test-ns",
ResourceVersion: "1",
},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSDefault,
Containers: []api.Container{
{
Name: "container",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
EphemeralContainers: []api.EphemeralContainer{
{
EphemeralContainerCommon: api.EphemeralContainerCommon{
Name: "debugger",
Image: "image2",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
},
},
},
oldPod: &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Namespace: "test-ns",
ResourceVersion: "1",
},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSDefault,
Containers: []api.Container{
{
Name: "container",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
EphemeralContainers: []api.EphemeralContainer{
{
EphemeralContainerCommon: api.EphemeralContainerCommon{
Name: "debugger",
Image: "image",
ImagePullPolicy: "IfNotPresent",
TerminationMessagePolicy: "File",
},
},
},
},
},
},
}
// expect one error
for _, tc := range test {
t.Run(tc.name, func(t *testing.T) {
errs := EphemeralContainersStrategy.ValidateUpdate(genericapirequest.NewContext(), tc.newPod, tc.oldPod)
if len(errs) == 0 {
t.Errorf("unexpected success:ephemeral containers are not supported for static pods")
} else if len(errs) != 1 {
t.Errorf("unexpected errors:expected one error about ephemeral containers are not supported for static pods:got:%v:", errs)
}
})
}
}
func TestPodStrategyValidateUpdate(t *testing.T) {
test := []struct {
name string