From 2ade9ec91bc16f616a545d87f1bc07b964373225 Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Mon, 2 Nov 2020 11:37:15 -0800 Subject: [PATCH] e2e: override-frontend-port, duplicate path and multiple url path maps (#1037) * e2e: override-port, duplicate path and multiple url path maps * update test title --- scripts/e2e/cmd/runner/helper.go | 36 ++- .../mfu_one_namespace_one_ingress_test.go | 70 ++++++ .../invalid-configuration/app.yaml | 214 ++++++++++++++++++ .../override-frontend-port/app.yaml | 94 ++++++++ 4 files changed, 410 insertions(+), 4 deletions(-) create mode 100644 scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/invalid-configuration/app.yaml create mode 100644 scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/override-frontend-port/app.yaml diff --git a/scripts/e2e/cmd/runner/helper.go b/scripts/e2e/cmd/runner/helper.go index 56537b22a..60b96e2da 100644 --- a/scripts/e2e/cmd/runner/helper.go +++ b/scripts/e2e/cmd/runner/helper.go @@ -209,7 +209,7 @@ func parseK8sYaml(fileName string) ([]runtime.Object, error) { return nil, err } - acceptedK8sTypes := regexp.MustCompile(`(Namespace|Deployment|Service|Ingress|Secret|ConfigMap)`) + acceptedK8sTypes := regexp.MustCompile(`(Namespace|Deployment|Service|Ingress|Secret|ConfigMap|Pod)`) fileAsString := string(fileR[:]) sepYamlfiles := strings.Split(fileAsString, "---") retVal := make([]runtime.Object, 0, len(sepYamlfiles)) @@ -283,7 +283,6 @@ func applyYaml(clientset *kubernetes.Clientset, namespaceName string, fileName s } else { return errors.New("namespace is not defined for service") } - } if deployment, ok := objs.(*appsv1.Deployment); ok { nm := deployment.Namespace @@ -298,7 +297,6 @@ func applyYaml(clientset *kubernetes.Clientset, namespaceName string, fileName s } else { return errors.New("namespace is not defined for deployment") } - } if cm, ok := objs.(*v1.ConfigMap); ok { nm := cm.Namespace @@ -313,8 +311,23 @@ func applyYaml(clientset *kubernetes.Clientset, namespaceName string, fileName s } else { return errors.New("namespace is not defined for configmaps") } - } + if pod, ok := objs.(*v1.Pod); ok { + nm := pod.Namespace + if len(nm) == 0 && len(namespaceName) != 0 { + if _, err := clientset.CoreV1().Pods(namespaceName).Create(pod); err != nil { + return err + } + } else if len(nm) != 0 { + if _, err := clientset.CoreV1().Pods(nm).Create(pod); err != nil { + return err + } + } else { + return errors.New("namespace is not defined for pods") + } + } + + return fmt.Errorf("unable to apply YAML. Unknown object type: %v", objs) } return nil } @@ -436,3 +449,18 @@ func makeGetRequest(url string, host string, statusCode int, inSecure bool) (*ht return nil, fmt.Errorf("Unable to get status code %d with url '%s' with host '%s'. Response: [%+v]", statusCode, url, host, resp) } + +func readBody(resp *http.Response) (string, error) { + defer resp.Body.Close() + + if resp.StatusCode == http.StatusOK { + bodyBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + return string(bodyBytes), nil + } + + return "", nil +} diff --git a/scripts/e2e/cmd/runner/mfu_one_namespace_one_ingress_test.go b/scripts/e2e/cmd/runner/mfu_one_namespace_one_ingress_test.go index e2f7212b7..24cf1c1a3 100644 --- a/scripts/e2e/cmd/runner/mfu_one_namespace_one_ingress_test.go +++ b/scripts/e2e/cmd/runner/mfu_one_namespace_one_ingress_test.go @@ -189,6 +189,76 @@ var _ = Describe("MFU", func() { Expect(err).To(BeNil()) }) + It("[override-frontend-port] should be able to use frontend port other than 80/443", func() { + namespaceName := "e2e-override-frontend-port" + ns := &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespaceName, + }, + } + klog.Info("Creating namespace: ", namespaceName) + _, err = clientset.CoreV1().Namespaces().Create(ns) + Expect(err).To(BeNil()) + + OverrideFrontendPortYamlPath := "testdata/one-namespace-one-ingress/override-frontend-port/app.yaml" + klog.Info("Applying yaml: ", OverrideFrontendPortYamlPath) + err = applyYaml(clientset, namespaceName, OverrideFrontendPortYamlPath) + Expect(err).To(BeNil()) + time.Sleep(30 * time.Second) + + // get ip address for 1 ingress + klog.Info("Getting public IP from Ingress...") + publicIP, _ := getPublicIP(clientset, namespaceName) + Expect(publicIP).ToNot(Equal("")) + + urlHttp := fmt.Sprintf("http://%s:%d/good", publicIP, 8080) + urlHttps := fmt.Sprintf("https://%s:%d/good", publicIP, 8443) + // http get to return 200 ok + _, err = makeGetRequest(urlHttp, "app.http", 200, true) + Expect(err).To(BeNil()) + // https get to return 200 ok + _, err = makeGetRequest(urlHttps, "app.https", 200, true) + Expect(err).To(BeNil()) + }) + + It("[configuration-reliability] should be able to work with an invalid configuration containing duplicate paths and multiple backend port", func() { + namespaceName := "e2e-configuration-reliability" + ns := &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespaceName, + }, + } + klog.Info("Creating namespace: ", namespaceName) + _, err = clientset.CoreV1().Namespaces().Create(ns) + Expect(err).To(BeNil()) + + InvalidConfigYamlPath := "testdata/one-namespace-one-ingress/invalid-configuration/app.yaml" + klog.Info("Applying yaml: ", InvalidConfigYamlPath) + err = applyYaml(clientset, namespaceName, InvalidConfigYamlPath) + Expect(err).To(BeNil()) + time.Sleep(30 * time.Second) + + // get ip address for 1 ingress + klog.Info("Getting public IP from Ingress...") + publicIP, _ := getPublicIP(clientset, namespaceName) + Expect(publicIP).ToNot(Equal("")) + + url := fmt.Sprintf("http://%s/", publicIP) + resp, err := makeGetRequest(url, "app.http", 200, true) + Expect(err).To(BeNil()) + Expect(readBody(resp)).To(Equal("app")) + + url = fmt.Sprintf("http://%s/app", publicIP) + resp, err = makeGetRequest(url, "app.http", 200, true) + Expect(err).To(BeNil()) + Expect(readBody(resp)).To(Equal("app")) + + url = fmt.Sprintf("http://%s/app1", publicIP) + resp, err = makeGetRequest(url, "app.http", 200, true) + Expect(err).To(BeNil()) + Expect(readBody(resp)).To(Equal("app")) + }) + AfterEach(func() { // clear all namespaces cleanUp(clientset) diff --git a/scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/invalid-configuration/app.yaml b/scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/invalid-configuration/app.yaml new file mode 100644 index 000000000..7ed4b67c8 --- /dev/null +++ b/scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/invalid-configuration/app.yaml @@ -0,0 +1,214 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-cm +data: + default.conf: |- + server { + listen 80 default_server; + location / { + return 200 "app"; + } + } + +--- +apiVersion: v1 +kind: Pod +metadata: + name: pod1 + labels: + app: backend +spec: + containers: + - name: nginx + imagePullPolicy: Always + image: nginx:latest + ports: + - containerPort: 80 + name: http + volumeMounts: + - mountPath: /etc/nginx/conf.d + name: configmap-volume + volumes: + - name: configmap-volume + configMap: + name: nginx-cm + +--- +apiVersion: v1 +kind: Pod +metadata: + name: pod2 + labels: + app: backend +spec: + containers: + - name: nginx + imagePullPolicy: Always + image: nginx:latest + ports: + - containerPort: 5000 + name: http + volumeMounts: + - mountPath: /etc/nginx/conf.d + name: configmap-volume + volumes: + - name: configmap-volume + configMap: + name: nginx-cm + +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx-service +spec: + selector: + app: backend + ports: + - name: http + port: 80 + targetPort: http + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: http-bin-service-deployment +spec: + selector: + matchLabels: + app: http-bin-service + replicas: 2 + template: + metadata: + labels: + app: http-bin-service + spec: + containers: + - name: http-bin-service + imagePullPolicy: Always + image: docker.io/kennethreitz/httpbin + ports: + - containerPort: 80 + livenessProbe: + httpGet: + path: /status/201 + port: 80 + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + failureThreshold: 10 + httpGet: + path: /status/202 + port: 80 + scheme: HTTP + +--- +apiVersion: v1 +kind: Service +metadata: + name: http-bin-service +spec: + selector: + app: http-bin-service + ports: + - name: http + port: 80 + targetPort: 80 + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: frontend-ingress + annotations: + kubernetes.io/ingress.class: azure/application-gateway +spec: + rules: + - host: app.http + http: + paths: + - path: / + backend: + serviceName: nginx-service + servicePort: http + - path: /app + backend: + serviceName: nginx-service + servicePort: http + - path: /app + backend: + serviceName: http-bin-service + servicePort: http + - host: app.http + http: + paths: + - path: / + backend: + serviceName: nginx-service + servicePort: http + - path: /app + backend: + serviceName: nginx-service + servicePort: http + - path: /app1 + backend: + serviceName: nginx-service + servicePort: http + - path: /app1 + backend: + serviceName: http-bin-service + servicePort: http + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: frontend-ingress2 + annotations: + kubernetes.io/ingress.class: azure/application-gateway +spec: + rules: + - host: app.http + http: + paths: + - path: / + backend: + serviceName: nginx-service + servicePort: http + - path: /app + backend: + serviceName: nginx-service + servicePort: http + - path: /app + backend: + serviceName: http-bin-service + servicePort: http + - host: app.http + http: + paths: + - path: / + backend: + serviceName: nginx-service + servicePort: http + - path: / + backend: + serviceName: nginx-service + servicePort: http + - path: /app + backend: + serviceName: nginx-service + servicePort: http + - path: /app + backend: + serviceName: http-bin-service + servicePort: http + - path: /app1 + backend: + serviceName: nginx-service + servicePort: http + - path: /app1 + backend: + serviceName: http-bin-service + servicePort: http diff --git a/scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/override-frontend-port/app.yaml b/scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/override-frontend-port/app.yaml new file mode 100644 index 000000000..1b4ea4fae --- /dev/null +++ b/scripts/e2e/cmd/runner/testdata/one-namespace-one-ingress/override-frontend-port/app.yaml @@ -0,0 +1,94 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: backend-deployment +spec: + selector: + matchLabels: + app: ws-app + replicas: 1 + template: + metadata: + labels: + app: ws-app + spec: + containers: + - name: backend-app + imagePullPolicy: Always + image: docker.io/kennethreitz/httpbin + ports: + - containerPort: 80 + livenessProbe: + httpGet: + path: /status/201 + port: 80 + initialDelaySeconds: 3 + periodSeconds: 3 + readinessProbe: + failureThreshold: 10 + httpGet: + path: /status/202 + port: 80 + scheme: HTTP + +--- +apiVersion: v1 +kind: Service +metadata: + name: backend-service +spec: + selector: + app: ws-app + ports: + - protocol: TCP + port: 80 + targetPort: 80 + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: ingress-http + annotations: + kubernetes.io/ingress.class: azure/application-gateway + appgw.ingress.kubernetes.io/backend-path-prefix: "/" + appgw.ingress.kubernetes.io/override-frontend-port: "8080" +spec: + rules: + - host: app.http + http: + paths: + - path: /good + backend: + serviceName: backend-service + servicePort: 80 + +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: ingress-https + annotations: + kubernetes.io/ingress.class: azure/application-gateway + appgw.ingress.kubernetes.io/backend-path-prefix: "/" + appgw.ingress.kubernetes.io/override-frontend-port: "8443" +spec: + tls: + - secretName: testsecret-tls + rules: + - host: app.https + http: + paths: + - path: /good + backend: + serviceName: backend-service + servicePort: 80 +--- +apiVersion: v1 +kind: Secret +metadata: + name: testsecret-tls +type: kubernetes.io/tls +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJEVENCdEFJSkFLWTlOYkJMVjlJTE1Bb0dDQ3FHU000OUJBTUNNQTh4RFRBTEJnTlZCQU1NQkhSbGMzUXcKSGhjTk1qQXdOVEU0TWpFeU1UUXpXaGNOTWpFd05URTRNakV5TVRReldqQVBNUTB3Q3dZRFZRUUREQVIwWlhOMApNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUU2eHlzV0lhZUFkenYveXdUNTl5NDNreXppUGViCmMvaEpLOCt1Nm9uMmtOYjJpZ2tuTDZndU9PYWxsamQxOVB1dTYwYmh4aEpobGJpcHpBcWZCcFYzYnpBS0JnZ3EKaGtqT1BRUURBZ05JQURCRkFpRUFzbGNmNjNId0hxUDZoMHJTdjg3TXlBRVVoWmRoUlNZdm5sMGQyazRxZGtZQwpJRG1qNWdDcFAzTldmZWRVZHh6bTlsOEtxRUl2c1VxL1hXYWxUODhTWitWQQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + tls.key: LS0tLS1CRUdJTiBFQyBQQVJBTUVURVJTLS0tLS0KQmdncWhrak9QUU1CQnc9PQotLS0tLUVORCBFQyBQQVJBTUVURVJTLS0tLS0KLS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUdQeE1qSytnOEd1dWhlMW1PQUZHY1V3V09xdHZRbjZCTHBQZVJGUTZUNHhvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFNnh5c1dJYWVBZHp2L3l3VDU5eTQza3l6aVBlYmMvaEpLOCt1Nm9uMmtOYjJpZ2tuTDZndQpPT2FsbGpkMTlQdXU2MGJoeGhKaGxiaXB6QXFmQnBWM2J3PT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=