Commit 633079eb authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #47864 from droot/podpreset-conflict-fix

Automatic merge from submit-queue (batch tested with PRs 49444, 47864, 48584, 49395, 49118) fixed conflict resolution behavior while apply podpresets **What this PR does / why we need it**: This fixes the PodPreset application behavior in case of conflicts occur during the merging of Pod's information with PodPreset's. More details are in issue #47861 **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes # fixes #47861 **Special notes for your reviewer**: We are splitting the PodPreset application logic in two phases. In first phase, we try to detect the conflicts in information merging without modifying the Pod at all. If conflict occurs, then we reject the PodPresets injection. Incase of no conflicts, we apply the PodPresets and merge the information. **Release note**: ```release-note PodPreset is not injected if conflict occurs while applying PodPresets to a Pod. ```
parents 9891f666 4d5b96f9
...@@ -406,7 +406,6 @@ function start_apiserver { ...@@ -406,7 +406,6 @@ function start_apiserver {
# Admission Controllers to invoke prior to persisting objects in cluster # Admission Controllers to invoke prior to persisting objects in cluster
ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount${security_admission},ResourceQuota,DefaultStorageClass,DefaultTolerationSeconds ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount${security_admission},ResourceQuota,DefaultStorageClass,DefaultTolerationSeconds
# This is the default dir and filename where the apiserver will generate a self-signed cert # This is the default dir and filename where the apiserver will generate a self-signed cert
# which should be able to be used as the CA to verify itself # which should be able to be used as the CA to verify itself
......
...@@ -43,6 +43,7 @@ go_library( ...@@ -43,6 +43,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library", "//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
], ],
) )
......
...@@ -66,8 +66,8 @@ func TestMergeEnv(t *testing.T) { ...@@ -66,8 +66,8 @@ func TestMergeEnv(t *testing.T) {
for name, test := range tests { for name, test := range tests {
result, err := mergeEnv( result, err := mergeEnv(
&settings.PodPreset{Spec: settings.PodPresetSpec{Env: test.mod}},
test.orig, test.orig,
[]*settings.PodPreset{{Spec: settings.PodPresetSpec{Env: test.mod}}},
) )
if test.shouldFail && err == nil { if test.shouldFail && err == nil {
t.Fatalf("expected test %q to fail but got nil", name) t.Fatalf("expected test %q to fail but got nil", name)
...@@ -162,8 +162,8 @@ func TestMergeEnvFrom(t *testing.T) { ...@@ -162,8 +162,8 @@ func TestMergeEnvFrom(t *testing.T) {
for name, test := range tests { for name, test := range tests {
result, err := mergeEnvFrom( result, err := mergeEnvFrom(
&settings.PodPreset{Spec: settings.PodPresetSpec{EnvFrom: test.mod}},
test.orig, test.orig,
[]*settings.PodPreset{{Spec: settings.PodPresetSpec{EnvFrom: test.mod}}},
) )
if test.shouldFail && err == nil { if test.shouldFail && err == nil {
t.Fatalf("expected test %q to fail but got nil", name) t.Fatalf("expected test %q to fail but got nil", name)
...@@ -295,8 +295,8 @@ func TestMergeVolumeMounts(t *testing.T) { ...@@ -295,8 +295,8 @@ func TestMergeVolumeMounts(t *testing.T) {
for name, test := range tests { for name, test := range tests {
result, err := mergeVolumeMounts( result, err := mergeVolumeMounts(
&settings.PodPreset{Spec: settings.PodPresetSpec{VolumeMounts: test.mod}},
test.orig, test.orig,
[]*settings.PodPreset{{Spec: settings.PodPresetSpec{VolumeMounts: test.mod}}},
) )
if test.shouldFail && err == nil { if test.shouldFail && err == nil {
t.Fatalf("expected test %q to fail but got nil", name) t.Fatalf("expected test %q to fail but got nil", name)
...@@ -376,8 +376,8 @@ func TestMergeVolumes(t *testing.T) { ...@@ -376,8 +376,8 @@ func TestMergeVolumes(t *testing.T) {
for name, test := range tests { for name, test := range tests {
result, err := mergeVolumes( result, err := mergeVolumes(
&settings.PodPreset{Spec: settings.PodPresetSpec{Volumes: test.mod}},
test.orig, test.orig,
[]*settings.PodPreset{{Spec: settings.PodPresetSpec{Volumes: test.mod}}},
) )
if test.shouldFail && err == nil { if test.shouldFail && err == nil {
t.Fatalf("expected test %q to fail but got nil", name) t.Fatalf("expected test %q to fail but got nil", name)
...@@ -496,6 +496,56 @@ func TestAdmitConflictWithNonMatchingLabelsShouldNotError(t *testing.T) { ...@@ -496,6 +496,56 @@ func TestAdmitConflictWithNonMatchingLabelsShouldNotError(t *testing.T) {
} }
} }
func TestAdmitConflictShouldNotModifyPod(t *testing.T) {
containerName := "container"
pod := &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "mypod",
Namespace: "namespace",
Labels: map[string]string{
"security": "S2",
},
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: containerName,
Env: []api.EnvVar{{Name: "abc", Value: "value2"}, {Name: "ABC", Value: "value3"}},
},
},
},
}
origPod := *pod
pip := &settings.PodPreset{
ObjectMeta: v1.ObjectMeta{
Name: "hello",
Namespace: "namespace",
},
Spec: settings.PodPresetSpec{
Selector: v1.LabelSelector{
MatchExpressions: []v1.LabelSelectorRequirement{
{
Key: "security",
Operator: v1.LabelSelectorOpIn,
Values: []string{"S2"},
},
},
},
Env: []api.EnvVar{{Name: "abc", Value: "value"}, {Name: "ABC", Value: "value"}},
},
}
err := admitPod(pod, pip)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(&origPod, pod) {
t.Fatalf("pod should not get modified in case of conflict origPod: %+v got: %+v", &origPod, pod)
}
}
func TestAdmit(t *testing.T) { func TestAdmit(t *testing.T) {
containerName := "container" containerName := "container"
...@@ -759,7 +809,7 @@ func TestAdmitEmptyPodNamespace(t *testing.T) { ...@@ -759,7 +809,7 @@ func TestAdmitEmptyPodNamespace(t *testing.T) {
// verify PodSpec has not been mutated // verify PodSpec has not been mutated
if !reflect.DeepEqual(pod, originalPod) { if !reflect.DeepEqual(pod, originalPod) {
t.Fatalf("Expected pod spec of '%v' to be unchanged", pod.Name) t.Fatalf("pod should not get modified in case of emptyNamespace origPod: %+v got: %+v", originalPod, pod)
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment