Update AppArmor e2e tests
This commit is contained in:
		@@ -48,8 +48,8 @@ func LoadAppArmorProfiles(ctx context.Context, nsName string, clientset clientse
 | 
				
			|||||||
// CreateAppArmorTestPod creates a pod that tests apparmor profile enforcement. The pod exits with
 | 
					// CreateAppArmorTestPod creates a pod that tests apparmor profile enforcement. The pod exits with
 | 
				
			||||||
// an error code if the profile is incorrectly enforced. If runOnce is true the pod will exit after
 | 
					// an error code if the profile is incorrectly enforced. If runOnce is true the pod will exit after
 | 
				
			||||||
// a single test, otherwise it will repeat the test every 1 second until failure.
 | 
					// a single test, otherwise it will repeat the test every 1 second until failure.
 | 
				
			||||||
func CreateAppArmorTestPod(ctx context.Context, nsName string, clientset clientset.Interface, podClient *e2epod.PodClient, unconfined bool, runOnce bool) *v1.Pod {
 | 
					func AppArmorTestPod(nsName string, unconfined bool, runOnce bool) *v1.Pod {
 | 
				
			||||||
	profile := "localhost/" + appArmorProfilePrefix + nsName
 | 
						localhostProfile := appArmorProfilePrefix + nsName
 | 
				
			||||||
	testCmd := fmt.Sprintf(`
 | 
						testCmd := fmt.Sprintf(`
 | 
				
			||||||
if touch %[1]s; then
 | 
					if touch %[1]s; then
 | 
				
			||||||
  echo "FAILURE: write to %[1]s should be denied"
 | 
					  echo "FAILURE: write to %[1]s should be denied"
 | 
				
			||||||
@@ -64,7 +64,6 @@ elif [[ $(< /proc/self/attr/current) != "%[3]s" ]]; then
 | 
				
			|||||||
fi`, appArmorDeniedPath, appArmorAllowedPath, appArmorProfilePrefix+nsName)
 | 
					fi`, appArmorDeniedPath, appArmorAllowedPath, appArmorProfilePrefix+nsName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if unconfined {
 | 
						if unconfined {
 | 
				
			||||||
		profile = v1.AppArmorBetaProfileNameUnconfined
 | 
					 | 
				
			||||||
		testCmd = `
 | 
							testCmd = `
 | 
				
			||||||
if cat /proc/sysrq-trigger 2>&1 | grep 'Permission denied'; then
 | 
					if cat /proc/sysrq-trigger 2>&1 | grep 'Permission denied'; then
 | 
				
			||||||
  echo 'FAILURE: reading /proc/sysrq-trigger should be allowed'
 | 
					  echo 'FAILURE: reading /proc/sysrq-trigger should be allowed'
 | 
				
			||||||
@@ -94,17 +93,25 @@ done`, testCmd)
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						profile := &v1.AppArmorProfile{}
 | 
				
			||||||
 | 
						if unconfined {
 | 
				
			||||||
 | 
							profile.Type = v1.AppArmorProfileTypeUnconfined
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							profile.Type = v1.AppArmorProfileTypeLocalhost
 | 
				
			||||||
 | 
							profile.LocalhostProfile = &localhostProfile
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pod := &v1.Pod{
 | 
						pod := &v1.Pod{
 | 
				
			||||||
		ObjectMeta: metav1.ObjectMeta{
 | 
							ObjectMeta: metav1.ObjectMeta{
 | 
				
			||||||
			GenerateName: "test-apparmor-",
 | 
								GenerateName: "test-apparmor-",
 | 
				
			||||||
			Annotations: map[string]string{
 | 
					 | 
				
			||||||
				v1.AppArmorBetaContainerAnnotationKeyPrefix + "test": profile,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			Labels: map[string]string{
 | 
								Labels: map[string]string{
 | 
				
			||||||
				"test": "apparmor",
 | 
									"test": "apparmor",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Spec: v1.PodSpec{
 | 
							Spec: v1.PodSpec{
 | 
				
			||||||
 | 
								SecurityContext: &v1.PodSecurityContext{
 | 
				
			||||||
 | 
									AppArmorProfile: profile,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
			Affinity: loaderAffinity,
 | 
								Affinity: loaderAffinity,
 | 
				
			||||||
			Containers: []v1.Container{{
 | 
								Containers: []v1.Container{{
 | 
				
			||||||
				Name:    "test",
 | 
									Name:    "test",
 | 
				
			||||||
@@ -115,20 +122,24 @@ done`, testCmd)
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return pod
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RunAppArmorTestPod(ctx context.Context, pod *v1.Pod, clientset clientset.Interface, podClient *e2epod.PodClient, runOnce bool) *v1.Pod {
 | 
				
			||||||
	if runOnce {
 | 
						if runOnce {
 | 
				
			||||||
		pod = podClient.Create(ctx, pod)
 | 
							pod = podClient.Create(ctx, pod)
 | 
				
			||||||
		framework.ExpectNoError(e2epod.WaitForPodSuccessInNamespace(ctx,
 | 
							framework.ExpectNoError(e2epod.WaitForPodSuccessInNamespace(ctx,
 | 
				
			||||||
			clientset, pod.Name, nsName))
 | 
								clientset, pod.Name, pod.Namespace))
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
		pod, err = podClient.Get(ctx, pod.Name, metav1.GetOptions{})
 | 
							pod, err = podClient.Get(ctx, pod.Name, metav1.GetOptions{})
 | 
				
			||||||
		framework.ExpectNoError(err)
 | 
							framework.ExpectNoError(err)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		pod = podClient.CreateSync(ctx, pod)
 | 
							pod = podClient.CreateSync(ctx, pod)
 | 
				
			||||||
		framework.ExpectNoError(e2epod.WaitTimeoutForPodReadyInNamespace(ctx, clientset, pod.Name, nsName, framework.PodStartTimeout))
 | 
							framework.ExpectNoError(e2epod.WaitTimeoutForPodReadyInNamespace(ctx, clientset, pod.Name, pod.Namespace, framework.PodStartTimeout))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Verify Pod affinity colocated the Pods.
 | 
						// Verify Pod affinity colocated the Pods.
 | 
				
			||||||
	loader := getRunningLoaderPod(ctx, nsName, clientset)
 | 
						loader := getRunningLoaderPod(ctx, pod.Namespace, clientset)
 | 
				
			||||||
	gomega.Expect(pod.Spec.NodeName).To(gomega.Equal(loader.Spec.NodeName))
 | 
						gomega.Expect(pod.Spec.NodeName).To(gomega.Equal(loader.Spec.NodeName))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pod
 | 
						return pod
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@ package node
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
	"k8s.io/kubernetes/test/e2e/framework"
 | 
						"k8s.io/kubernetes/test/e2e/framework"
 | 
				
			||||||
	e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl"
 | 
						e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl"
 | 
				
			||||||
	e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
 | 
						e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
 | 
				
			||||||
@@ -45,12 +46,38 @@ var _ = SIGDescribe("AppArmor", func() {
 | 
				
			|||||||
			e2ekubectl.LogFailedContainers(ctx, f.ClientSet, f.Namespace.Name, framework.Logf)
 | 
								e2ekubectl.LogFailedContainers(ctx, f.ClientSet, f.Namespace.Name, framework.Logf)
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ginkgo.It("should enforce an AppArmor profile", func(ctx context.Context) {
 | 
							ginkgo.It("should enforce an AppArmor profile specified on the pod", func(ctx context.Context) {
 | 
				
			||||||
			e2esecurity.CreateAppArmorTestPod(ctx, f.Namespace.Name, f.ClientSet, e2epod.NewPodClient(f), false, true)
 | 
								pod := e2esecurity.AppArmorTestPod(f.Namespace.Name, false, true)
 | 
				
			||||||
 | 
								e2esecurity.RunAppArmorTestPod(ctx, pod, f.ClientSet, e2epod.NewPodClient(f), true)
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ginkgo.It("should enforce an AppArmor profile specified on the container", func(ctx context.Context) {
 | 
				
			||||||
 | 
								pod := e2esecurity.AppArmorTestPod(f.Namespace.Name, false, true)
 | 
				
			||||||
 | 
								// Move AppArmor profile to the container.
 | 
				
			||||||
 | 
								pod.Spec.Containers[0].SecurityContext = &v1.SecurityContext{
 | 
				
			||||||
 | 
									AppArmorProfile: pod.Spec.SecurityContext.AppArmorProfile,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								pod.Spec.SecurityContext = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								e2esecurity.RunAppArmorTestPod(ctx, pod, f.ClientSet, e2epod.NewPodClient(f), true)
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ginkgo.It("should enforce an AppArmor profile specified in annotations", func(ctx context.Context) {
 | 
				
			||||||
 | 
								pod := e2esecurity.AppArmorTestPod(f.Namespace.Name, false, true)
 | 
				
			||||||
 | 
								// Move AppArmor profile to the annotations.
 | 
				
			||||||
 | 
								profile := pod.Spec.SecurityContext.AppArmorProfile
 | 
				
			||||||
 | 
								key := v1.AppArmorBetaContainerAnnotationKeyPrefix + pod.Spec.Containers[0].Name
 | 
				
			||||||
 | 
								pod.Annotations = map[string]string{
 | 
				
			||||||
 | 
									key: v1.AppArmorBetaProfileNamePrefix + *profile.LocalhostProfile,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								pod.Spec.SecurityContext = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								e2esecurity.RunAppArmorTestPod(ctx, pod, f.ClientSet, e2epod.NewPodClient(f), true)
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ginkgo.It("can disable an AppArmor profile, using unconfined", func(ctx context.Context) {
 | 
							ginkgo.It("can disable an AppArmor profile, using unconfined", func(ctx context.Context) {
 | 
				
			||||||
			e2esecurity.CreateAppArmorTestPod(ctx, f.Namespace.Name, f.ClientSet, e2epod.NewPodClient(f), true, true)
 | 
								pod := e2esecurity.AppArmorTestPod(f.Namespace.Name, true, true)
 | 
				
			||||||
 | 
								e2esecurity.RunAppArmorTestPod(ctx, pod, f.ClientSet, e2epod.NewPodClient(f), true)
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -63,7 +63,8 @@ func (t *AppArmorUpgradeTest) Setup(ctx context.Context, f *framework.Framework)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Create the initial test pod.
 | 
						// Create the initial test pod.
 | 
				
			||||||
	ginkgo.By("Creating a long-running AppArmor enabled pod.")
 | 
						ginkgo.By("Creating a long-running AppArmor enabled pod.")
 | 
				
			||||||
	t.pod = e2esecurity.CreateAppArmorTestPod(ctx, f.Namespace.Name, f.ClientSet, e2epod.NewPodClient(f), false, false)
 | 
						pod := e2esecurity.AppArmorTestPod(f.Namespace.Name, false, false)
 | 
				
			||||||
 | 
						t.pod = e2esecurity.RunAppArmorTestPod(ctx, pod, f.ClientSet, e2epod.NewPodClient(f), false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Verify initial state.
 | 
						// Verify initial state.
 | 
				
			||||||
	t.verifyNodesAppArmorEnabled(ctx, f)
 | 
						t.verifyNodesAppArmorEnabled(ctx, f)
 | 
				
			||||||
@@ -99,7 +100,8 @@ func (t *AppArmorUpgradeTest) verifyPodStillUp(ctx context.Context, f *framework
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (t *AppArmorUpgradeTest) verifyNewPodSucceeds(ctx context.Context, f *framework.Framework) {
 | 
					func (t *AppArmorUpgradeTest) verifyNewPodSucceeds(ctx context.Context, f *framework.Framework) {
 | 
				
			||||||
	ginkgo.By("Verifying an AppArmor profile is enforced for a new pod")
 | 
						ginkgo.By("Verifying an AppArmor profile is enforced for a new pod")
 | 
				
			||||||
	e2esecurity.CreateAppArmorTestPod(ctx, f.Namespace.Name, f.ClientSet, e2epod.NewPodClient(f), false, true)
 | 
						pod := e2esecurity.AppArmorTestPod(f.Namespace.Name, false, true)
 | 
				
			||||||
 | 
						t.pod = e2esecurity.RunAppArmorTestPod(ctx, pod, f.ClientSet, e2epod.NewPodClient(f), true)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (t *AppArmorUpgradeTest) verifyNodesAppArmorEnabled(ctx context.Context, f *framework.Framework) {
 | 
					func (t *AppArmorUpgradeTest) verifyNodesAppArmorEnabled(ctx context.Context, f *framework.Framework) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user