Separate feature-gate for AppArmor fields

This commit is contained in:
Tim Allclair
2024-03-05 17:04:36 -08:00
parent 22068e0cc7
commit 2d86cbf261
6 changed files with 86 additions and 38 deletions

View File

@@ -707,19 +707,34 @@ func TestDropProcMount(t *testing.T) {
func TestDropAppArmor(t *testing.T) {
tests := []struct {
description string
hasAppArmor bool
pod api.Pod
description string
hasAnnotations bool
hasFields bool
pod api.Pod
}{{
description: "with AppArmor Annotations",
hasAppArmor: true,
description: "with AppArmor Annotations",
hasAnnotations: true,
pod: api.Pod{
ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"a": "1", v1.DeprecatedAppArmorBetaContainerAnnotationKeyPrefix + "foo": "default"}},
Spec: api.PodSpec{},
},
}, {
description: "with AppArmor Annotations & fields",
hasAnnotations: true,
hasFields: true,
pod: api.Pod{
ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"a": "1", v1.DeprecatedAppArmorBetaContainerAnnotationKeyPrefix + "foo": "default"}},
Spec: api.PodSpec{
SecurityContext: &api.PodSecurityContext{
AppArmorProfile: &api.AppArmorProfile{
Type: api.AppArmorProfileTypeRuntimeDefault,
},
},
},
},
}, {
description: "with pod AppArmor profile",
hasAppArmor: true,
hasFields: true,
pod: api.Pod{
ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"a": "1"}},
Spec: api.PodSpec{
@@ -732,7 +747,7 @@ func TestDropAppArmor(t *testing.T) {
},
}, {
description: "with container AppArmor profile",
hasAppArmor: true,
hasFields: true,
pod: api.Pod{
ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"a": "1"}},
Spec: api.PodSpec{
@@ -747,7 +762,6 @@ func TestDropAppArmor(t *testing.T) {
},
}, {
description: "without AppArmor",
hasAppArmor: false,
pod: api.Pod{
ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"a": "1"}},
Spec: api.PodSpec{},
@@ -756,34 +770,43 @@ func TestDropAppArmor(t *testing.T) {
for _, test := range tests {
for _, enabled := range []bool{true, false} {
t.Run(fmt.Sprintf("%v/enabled=%v", test.description, enabled), func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AppArmor, enabled)()
for _, fieldsEnabled := range []bool{true, false} {
t.Run(fmt.Sprintf("%v/enabled=%v/fields=%v", test.description, enabled, fieldsEnabled), func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AppArmor, enabled)()
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.AppArmorFields, fieldsEnabled)()
newPod := test.pod.DeepCopy()
newPod := test.pod.DeepCopy()
if actual := appArmorInUse(newPod.Annotations, &newPod.Spec); actual != test.hasAppArmor {
t.Errorf("appArmorInUse does not match expectation: %t != %t", actual, test.hasAppArmor)
}
DropDisabledPodFields(newPod, newPod)
require.Equal(t, &test.pod, newPod, "unchanged pod should never be mutated")
DropDisabledPodFields(newPod, nil)
if enabled {
assert.Equal(t, &test.pod, newPod, "pod should not be mutated when AppArmor is enabled")
} else {
if appArmorInUse(newPod.Annotations, &newPod.Spec) {
t.Errorf("newPod should not be using appArmor after dropping disabled fields")
if hasAnnotations := appArmorAnnotationsInUse(newPod.Annotations); hasAnnotations != test.hasAnnotations {
t.Errorf("appArmorAnnotationsInUse does not match expectation: %t != %t", hasAnnotations, test.hasAnnotations)
}
if hasFields := appArmorFieldsInUse(&newPod.Spec); hasFields != test.hasFields {
t.Errorf("appArmorFieldsInUse does not match expectation: %t != %t", hasFields, test.hasFields)
}
if test.hasAppArmor {
assert.NotEqual(t, &test.pod, newPod, "pod should be mutated to drop AppArmor")
} else {
assert.Equal(t, &test.pod, newPod, "pod without AppArmor should not be mutated")
DropDisabledPodFields(newPod, newPod)
require.Equal(t, &test.pod, newPod, "unchanged pod should never be mutated")
DropDisabledPodFields(newPod, nil)
if enabled && fieldsEnabled {
assert.Equal(t, &test.pod, newPod, "pod should not be mutated when both feature gates are enabled")
return
}
}
})
expectAnnotations := test.hasAnnotations && enabled
assert.Equal(t, expectAnnotations, appArmorAnnotationsInUse(newPod.Annotations), "AppArmor annotations expectation")
if expectAnnotations == test.hasAnnotations {
assert.Equal(t, test.pod.Annotations, newPod.Annotations, "annotations should not be mutated")
}
expectFields := test.hasFields && enabled && fieldsEnabled
assert.Equal(t, expectFields, appArmorFieldsInUse(&newPod.Spec), "AppArmor fields expectation")
if expectFields == test.hasFields {
assert.Equal(t, &test.pod.Spec, &newPod.Spec, "PodSpec should not be mutated")
}
})
}
}
}
}