1
16
17 package node
18
19 import (
20 "context"
21 "fmt"
22 "path/filepath"
23 "sync"
24 "time"
25
26 rbacv1 "k8s.io/api/rbac/v1"
27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28 "k8s.io/apimachinery/pkg/runtime/schema"
29 "k8s.io/apiserver/pkg/authentication/serviceaccount"
30 clientset "k8s.io/client-go/kubernetes"
31 podutil "k8s.io/kubernetes/pkg/api/v1/pod"
32 commonutils "k8s.io/kubernetes/test/e2e/common"
33 "k8s.io/kubernetes/test/e2e/feature"
34 "k8s.io/kubernetes/test/e2e/framework"
35 e2eauth "k8s.io/kubernetes/test/e2e/framework/auth"
36 e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl"
37 e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
38 e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
39 e2etestfiles "k8s.io/kubernetes/test/e2e/framework/testfiles"
40 admissionapi "k8s.io/pod-security-admission/api"
41
42 "github.com/onsi/ginkgo/v2"
43 )
44
45 const (
46 serverStartTimeout = framework.PodStartTimeout + 3*time.Minute
47 )
48
49 var _ = SIGDescribe(feature.Example, func() {
50 f := framework.NewDefaultFramework("examples")
51 f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
52
53 var c clientset.Interface
54 var ns string
55 ginkgo.BeforeEach(func(ctx context.Context) {
56 c = f.ClientSet
57 ns = f.Namespace.Name
58
59
60
61 err := e2eauth.BindClusterRoleInNamespace(ctx, c.RbacV1(), "edit", f.Namespace.Name,
62 rbacv1.Subject{Kind: rbacv1.ServiceAccountKind, Namespace: f.Namespace.Name, Name: "default"})
63 framework.ExpectNoError(err)
64
65 err = e2eauth.WaitForAuthorizationUpdate(ctx, c.AuthorizationV1(),
66 serviceaccount.MakeUsername(f.Namespace.Name, "default"),
67 f.Namespace.Name, "create", schema.GroupResource{Resource: "pods"}, true)
68 framework.ExpectNoError(err)
69 })
70
71 ginkgo.Describe("Liveness", func() {
72 ginkgo.It("liveness pods should be automatically restarted", func(ctx context.Context) {
73 test := "test/fixtures/doc-yaml/user-guide/liveness"
74 execYaml := readFile(test, "exec-liveness.yaml.in")
75 httpYaml := readFile(test, "http-liveness.yaml.in")
76
77 e2ekubectl.RunKubectlOrDieInput(ns, execYaml, "create", "-f", "-")
78 e2ekubectl.RunKubectlOrDieInput(ns, httpYaml, "create", "-f", "-")
79
80
81 var wg sync.WaitGroup
82 passed := true
83 checkRestart := func(podName string, timeout time.Duration) {
84 err := e2epod.WaitForPodNameRunningInNamespace(ctx, c, podName, ns)
85 framework.ExpectNoError(err)
86 for t := time.Now(); time.Since(t) < timeout; time.Sleep(framework.Poll) {
87 pod, err := c.CoreV1().Pods(ns).Get(ctx, podName, metav1.GetOptions{})
88 framework.ExpectNoError(err, fmt.Sprintf("getting pod %s", podName))
89 stat := podutil.GetExistingContainerStatus(pod.Status.ContainerStatuses, podName)
90 framework.Logf("Pod: %s, restart count:%d", stat.Name, stat.RestartCount)
91 if stat.RestartCount > 0 {
92 framework.Logf("Saw %v restart, succeeded...", podName)
93 wg.Done()
94 return
95 }
96 }
97 framework.Logf("Failed waiting for %v restart! ", podName)
98 passed = false
99 wg.Done()
100 }
101
102 ginkgo.By("Check restarts")
103
104
105
106
107 wg.Add(2)
108 for _, c := range []string{"liveness-http", "liveness-exec"} {
109 go checkRestart(c, 2*time.Minute)
110 }
111 wg.Wait()
112 if !passed {
113 framework.Failf("At least one liveness example failed. See the logs above.")
114 }
115 })
116 })
117
118 ginkgo.Describe("Secret", func() {
119 ginkgo.It("should create a pod that reads a secret", func(ctx context.Context) {
120 test := "test/fixtures/doc-yaml/user-guide/secrets"
121 secretYaml := readFile(test, "secret.yaml")
122 podYaml := readFile(test, "secret-pod.yaml.in")
123
124 podName := "secret-test-pod"
125
126 ginkgo.By("creating secret and pod")
127 e2ekubectl.RunKubectlOrDieInput(ns, secretYaml, "create", "-f", "-")
128 e2ekubectl.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-")
129 err := e2epod.WaitForPodNoLongerRunningInNamespace(ctx, c, podName, ns)
130 framework.ExpectNoError(err)
131
132 ginkgo.By("checking if secret was read correctly")
133 _, err = e2eoutput.LookForStringInLog(ns, "secret-test-pod", "test-container", "value-1", serverStartTimeout)
134 framework.ExpectNoError(err)
135 })
136 })
137
138 ginkgo.Describe("Downward API", func() {
139 ginkgo.It("should create a pod that prints his name and namespace", func(ctx context.Context) {
140 test := "test/fixtures/doc-yaml/user-guide/downward-api"
141 podYaml := readFile(test, "dapi-pod.yaml.in")
142 podName := "dapi-test-pod"
143
144 ginkgo.By("creating the pod")
145 e2ekubectl.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-")
146 err := e2epod.WaitForPodNoLongerRunningInNamespace(ctx, c, podName, ns)
147 framework.ExpectNoError(err)
148
149 ginkgo.By("checking if name and namespace were passed correctly")
150 _, err = e2eoutput.LookForStringInLog(ns, podName, "test-container", fmt.Sprintf("MY_POD_NAMESPACE=%v", ns), serverStartTimeout)
151 framework.ExpectNoError(err)
152 _, err = e2eoutput.LookForStringInLog(ns, podName, "test-container", fmt.Sprintf("MY_POD_NAME=%v", podName), serverStartTimeout)
153 framework.ExpectNoError(err)
154 })
155 })
156 })
157
158 func readFile(test, file string) string {
159 from := filepath.Join(test, file)
160 data, err := e2etestfiles.Read(from)
161 if err != nil {
162 framework.Fail(err.Error())
163 }
164 return commonutils.SubstituteImageName(string(data))
165 }
166
View as plain text