Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[windows] Test: Check for failed sandbox pod when testing for RunAsUserName #105943

Merged
merged 2 commits into from Oct 28, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
78 changes: 75 additions & 3 deletions test/e2e/windows/security_context.go
Expand Up @@ -18,15 +18,22 @@ package windows

import (
"context"
"fmt"
"strings"
"time"

"github.com/onsi/ginkgo"
"github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/util/uuid"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/kubelet/events"
"k8s.io/kubernetes/test/e2e/framework"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
testutils "k8s.io/kubernetes/test/utils"
imageutils "k8s.io/kubernetes/test/utils/image"

"github.com/onsi/ginkgo"
)

const runAsUserNameContainerName = "run-as-username-container"
Expand All @@ -43,10 +50,59 @@ var _ = SIGDescribe("[Feature:Windows] SecurityContext", func() {
f.TestContainerOutput("check set user", podUserName, 0, []string{"ContainerAdministrator"})
})

ginkgo.It("should not be able to create pods with unknown usernames", func() {
ginkgo.It("should not be able to create pods with unknown usernames at Pod level", func() {
ginkgo.By("Creating a pod with an invalid username")
podInvalid := f.PodClient().Create(runAsUserNamePod(toPtr("FooLish")))

failedSandboxEventSelector := fields.Set{
"involvedObject.kind": "Pod",
"involvedObject.name": podInvalid.Name,
"involvedObject.namespace": podInvalid.Namespace,
"reason": events.FailedCreatePodSandBox,
}.AsSelector().String()
hcsschimError := "The user name or password is incorrect."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a module to get this error string from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I searched hcsshim and did not find this error, It seems this is coming from the OS and hcsshim is wrapping it.


// Hostprocess updated the cri to pass RunAsUserName to sandbox: https://github.com/kubernetes/kubernetes/pull/99576/commits/51a02fdb80cb7ba042a66362eb76facd2fd82401
// Some runtimes might use that and set the username on the podsandbox. Containerd 1.6+ is known to do this.
// If there is an error when creating the pod sandbox then the pod stays in pending state by design
// See https://github.com/kubernetes/kubernetes/issues/104635
// Not all runtimes use the sandbox information. This means the test needs to check if the pod
// sandbox failed or workload pod failed.
framework.Logf("Waiting for pod %s to enter the error state.", podInvalid.Name)
gomega.Eventually(func() bool {
failedSandbox, err := eventOccurred(f.ClientSet, podInvalid.Namespace, failedSandboxEventSelector, hcsschimError)
if err != nil {
framework.Logf("Error retrieving events for pod. Ignoring...")
}
if failedSandbox {
framework.Logf("Found Expected Event 'Failed to Create Pod Sandbox' with message containing: %s", hcsschimError)
return true
}

framework.Logf("No Sandbox error found. Looking for failure in workload pods")
pod, err := f.PodClient().Get(context.Background(), podInvalid.Name, metav1.GetOptions{})
if err != nil {
framework.Logf("Error retrieving pod: %s", err)
return false
}

podTerminatedReason := testutils.TerminatedContainers(pod)[runAsUserNameContainerName]
podFailedToStart := podTerminatedReason == "ContainerCannotRun" || podTerminatedReason == "StartError"
if pod.Status.Phase == v1.PodFailed && podFailedToStart {
framework.Logf("Found terminated workload Pod that could not start")
return true
}

return false
}, framework.PodStartTimeout, 1*time.Second).Should(gomega.BeTrue())
})

ginkgo.It("should not be able to create pods with unknown usernames at Container level", func() {
ginkgo.By("Creating a pod with an invalid username at container level and pod running as ContainerUser")
p := runAsUserNamePod(toPtr("FooLish"))
p.Spec.SecurityContext.WindowsOptions.RunAsUserName = toPtr("ContainerUser")
podInvalid := f.PodClient().Create(p)

framework.Logf("Waiting for pod %s to enter the error state.", podInvalid.Name)
framework.ExpectNoError(e2epod.WaitForPodTerminatedInNamespace(f.ClientSet, podInvalid.Name, "", f.Namespace.Name))

Expand All @@ -71,6 +127,7 @@ var _ = SIGDescribe("[Feature:Windows] SecurityContext", func() {
f.TestContainerOutput("check overridden username", pod, 0, []string{"ContainerUser"})
f.TestContainerOutput("check pod SecurityContext username", pod, 1, []string{"ContainerAdministrator"})
})

ginkgo.It("should ignore Linux Specific SecurityContext if set", func() {
ginkgo.By("Creating a pod with SELinux options")
// It is sufficient to show that the pod comes up here. Since we're stripping the SELinux and other linux
Expand Down Expand Up @@ -129,3 +186,18 @@ func runAsUserNamePod(username *string) *v1.Pod {
func toPtr(s string) *string {
return &s
}

func eventOccurred(c clientset.Interface, namespace, eventSelector, msg string) (bool, error) {
options := metav1.ListOptions{FieldSelector: eventSelector}

events, err := c.CoreV1().Events(namespace).List(context.TODO(), options)
if err != nil {
return false, fmt.Errorf("got error while getting events: %v", err)
}
for _, event := range events.Items {
if strings.Contains(event.Message, msg) {
return true, nil
}
}
return false, nil
}