Merge branch 'kubernetes:main' into main
This commit is contained in:
commit
9e79a36020
664 changed files with 19886 additions and 10226 deletions
|
|
@ -47,7 +47,7 @@ http {
|
|||
listen_ports = { ssl_proxy = "442", https = "443" },
|
||||
|
||||
hsts = true,
|
||||
hsts_max_age = 15724800,
|
||||
hsts_max_age = 31536000,
|
||||
hsts_include_subdomains = true,
|
||||
hsts_preload = false,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ lua_shared_dict ocsp_response_cache 5M;
|
|||
listen_ports = { ssl_proxy = "442", https = "443" },
|
||||
|
||||
hsts = true,
|
||||
hsts_max_age = 15724800,
|
||||
hsts_max_age = 31536000,
|
||||
hsts_include_subdomains = true,
|
||||
hsts_preload = false,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
"gzipTypes": "application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/javascript text/plain text/x-component",
|
||||
"hsts": true,
|
||||
"hstsIncludeSubdomains": true,
|
||||
"hstsMaxAge": "15724800",
|
||||
"hstsMaxAge": "31536000",
|
||||
"keepAlive": 75,
|
||||
"mapHashBucketSize": 64,
|
||||
"maxWorkerConnections": 16384,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
ARG E2E_BASE_IMAGE
|
||||
FROM ${E2E_BASE_IMAGE} AS BASE
|
||||
|
||||
FROM alpine:3.18.0
|
||||
FROM alpine:3.19.1
|
||||
|
||||
RUN apk update \
|
||||
&& apk upgrade && apk add -U --no-cache \
|
||||
ca-certificates \
|
||||
bash \
|
||||
curl \
|
||||
tzdata \
|
||||
libc6-compat \
|
||||
openssl
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||
E2E_BASE_IMAGE ?= "registry.k8s.io/ingress-nginx/e2e-test-runner:v20230623-d50c7193b@sha256:e5c68dc56934c273850bfb75c0348a2819756669baf59fcdce9e16771537b247"
|
||||
E2E_BASE_IMAGE ?= "registry.k8s.io/ingress-nginx/e2e-test-runner:v20240404-436df3e4@sha256:6bcba53b14d396177414e01f20e9111f1c009ac3b476a9b7668bb98d12bd5e85"
|
||||
|
||||
image:
|
||||
echo "..entered Makefile in /test/e2e-image"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
# TODO: remove the need to use fullnameOverride
|
||||
fullnameOverride: nginx-ingress
|
||||
controller:
|
||||
image:
|
||||
repository: ingress-controller/controller
|
||||
chroot: true
|
||||
tag: 1.0.0-dev
|
||||
digest:
|
||||
digestChroot:
|
||||
scope:
|
||||
# Necessary to allow the ingress controller to get the topology information from the nodes
|
||||
enabled: false
|
||||
config:
|
||||
worker-processes: "1"
|
||||
readinessProbe:
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 1
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 1
|
||||
service:
|
||||
type: NodePort
|
||||
extraArgs:
|
||||
# e2e tests do not require information about ingress status
|
||||
update-status: "false"
|
||||
terminationGracePeriodSeconds: 1
|
||||
admissionWebhooks:
|
||||
enabled: false
|
||||
|
||||
disableLeaderElection: true
|
||||
|
||||
rbac:
|
||||
create: true
|
||||
scope: false
|
||||
38
test/e2e-image/namespace-overlays/validations/values.yaml
Normal file
38
test/e2e-image/namespace-overlays/validations/values.yaml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# TODO: remove the need to use fullnameOverride
|
||||
fullnameOverride: nginx-ingress
|
||||
controller:
|
||||
image:
|
||||
repository: ingress-controller/controller
|
||||
chroot: true
|
||||
tag: 1.0.0-dev
|
||||
digest:
|
||||
digestChroot:
|
||||
containerPort:
|
||||
http: "1080"
|
||||
https: "1443"
|
||||
|
||||
extraArgs:
|
||||
http-port: "1080"
|
||||
https-port: "1443"
|
||||
# e2e tests do not require information about ingress status
|
||||
update-status: "false"
|
||||
|
||||
scope:
|
||||
enabled: true
|
||||
|
||||
config:
|
||||
worker-processes: "1"
|
||||
service:
|
||||
type: NodePort
|
||||
|
||||
admissionWebhooks:
|
||||
enabled: true
|
||||
certificate: "/usr/local/certificates/cert"
|
||||
key: "/usr/local/certificates/key"
|
||||
|
||||
defaultBackend:
|
||||
enabled: false
|
||||
|
||||
rbac:
|
||||
create: true
|
||||
scope: true
|
||||
|
|
@ -1 +1 @@
|
|||
registry.k8s.io/ingress-nginx/e2e-test-httpbun:v20230505-v0.0.1
|
||||
registry.k8s.io/ingress-nginx/e2e-test-httpbun:v20231011-8b53cabe0
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ import (
|
|||
networking "k8s.io/api/networking/v1"
|
||||
)
|
||||
|
||||
const admissionTestHost = "admission-test"
|
||||
|
||||
var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller", func() {
|
||||
f := framework.NewDefaultFramework("admission")
|
||||
|
||||
|
|
@ -43,7 +45,7 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("reject ingress with global-rate-limit annotations when memcached is not configured", func() {
|
||||
host := "admission-test"
|
||||
host := admissionTestHost
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/global-rate-limit": "100",
|
||||
|
|
@ -70,7 +72,7 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("should not allow overlaps of host and paths without canary annotations", func() {
|
||||
host := "admission-test"
|
||||
host := admissionTestHost
|
||||
|
||||
firstIngress := framework.NewSingleIngress("first-ingress", "/", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
_, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Create(context.TODO(), firstIngress, metav1.CreateOptions{})
|
||||
|
|
@ -87,7 +89,7 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("should allow overlaps of host and paths with canary annotation", func() {
|
||||
host := "admission-test"
|
||||
host := admissionTestHost
|
||||
|
||||
firstIngress := framework.NewSingleIngress("first-ingress", "/", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
_, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Create(context.TODO(), firstIngress, metav1.CreateOptions{})
|
||||
|
|
@ -125,7 +127,16 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("should return an error if there is an error validating the ingress definition", func() {
|
||||
host := "admission-test"
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := admissionTestHost
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": "something invalid",
|
||||
|
|
@ -136,7 +147,7 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("should return an error if there is an invalid value in some annotation", func() {
|
||||
host := "admission-test"
|
||||
host := admissionTestHost
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/connection-proxy-header": "a;}",
|
||||
|
|
@ -150,7 +161,7 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("should return an error if there is a forbidden value in some annotation", func() {
|
||||
host := "admission-test"
|
||||
host := admissionTestHost
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/connection-proxy-header": "set_by_lua",
|
||||
|
|
@ -195,7 +206,6 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
validPath := framework.NewSingleIngress("second-ingress", "/bloblo", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
_, err = f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Create(context.TODO(), validPath, metav1.CreateOptions{})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "creating an ingress with valid path should not return an error")
|
||||
|
||||
})
|
||||
|
||||
ginkgo.It("should not return an error if the Ingress V1 definition is valid with Ingress Class", func() {
|
||||
|
|
@ -231,6 +241,15 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("should return an error if the Ingress V1 definition contains invalid annotations", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
out, err := createIngress(f.Namespace, invalidV1Ingress)
|
||||
assert.Empty(ginkgo.GinkgoT(), out)
|
||||
assert.NotNil(ginkgo.GinkgoT(), err, "creating an ingress using kubectl")
|
||||
|
|
@ -242,6 +261,14 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("should not return an error for an invalid Ingress when it has unknown class", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
out, err := createIngress(f.Namespace, invalidV1IngressWithOtherClass)
|
||||
assert.Equal(ginkgo.GinkgoT(), "ingress.networking.k8s.io/extensions-invalid-other created\n", out)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "creating an invalid ingress with unknown class using kubectl")
|
||||
|
|
@ -346,7 +373,7 @@ func createIngress(namespace, ingressDefinition string) (string, error) {
|
|||
execOut bytes.Buffer
|
||||
execErr bytes.Buffer
|
||||
)
|
||||
|
||||
//nolint:gosec // Ignore G204 error
|
||||
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("%v --warnings-as-errors=false apply --namespace %s -f -", framework.KubectlPath, namespace))
|
||||
cmd.Stdin = strings.NewReader(ingressDefinition)
|
||||
cmd.Stdout = &execOut
|
||||
|
|
|
|||
|
|
@ -32,6 +32,14 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const (
|
||||
affinityAnnotation = "cookie"
|
||||
cookieName = "SERVERID"
|
||||
enableAnnotation = "true"
|
||||
disableAnnotation = "false"
|
||||
defaultHost = "foo.com"
|
||||
)
|
||||
|
||||
var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
||||
f := framework.NewDefaultFramework("affinity")
|
||||
|
||||
|
|
@ -42,8 +50,8 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
ginkgo.It("should set sticky cookie SERVERID", func() {
|
||||
host := "sticky.foo.com"
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -64,8 +72,8 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
ginkgo.It("should change cookie name on ingress definition change", func() {
|
||||
host := "change.foo.com"
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -80,7 +88,7 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
Header("Set-Cookie").Contains("SERVERID")
|
||||
Header("Set-Cookie").Contains(cookieName)
|
||||
|
||||
ing.ObjectMeta.Annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "OTHERCOOKIENAME"
|
||||
|
||||
|
|
@ -99,8 +107,8 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
ginkgo.It("should set the path to /something on the generated cookie", func() {
|
||||
host := "path.foo.com"
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/something", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -122,8 +130,8 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
pathtype := networking.PathTypePrefix
|
||||
host := "morethanonerule.foo.com"
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
|
||||
f.EnsureIngress(&networking.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
|
@ -194,7 +202,7 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
ginkgo.It("should set cookie with expires", func() {
|
||||
host := "cookieexpires.foo.com"
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "ExpiresCookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-expires"] = "172800"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-max-age"] = "259200"
|
||||
|
|
@ -211,7 +219,8 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
assert.Nil(ginkgo.GinkgoT(), err, "loading GMT location")
|
||||
assert.NotNil(ginkgo.GinkgoT(), local, "expected a location but none returned")
|
||||
|
||||
duration, _ := time.ParseDuration("48h")
|
||||
duration, err := time.ParseDuration("48h")
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "parsing duration")
|
||||
expected := time.Now().In(local).Add(duration).Format("Mon, 02-Jan-06 15:04")
|
||||
|
||||
f.HTTPTestClient().
|
||||
|
|
@ -225,7 +234,7 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
ginkgo.It("should set cookie with domain", func() {
|
||||
host := "cookiedomain.foo.com"
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "DomainCookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-domain"] = "foo.bar"
|
||||
|
||||
|
|
@ -248,7 +257,7 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
ginkgo.It("should not set cookie without domain annotation", func() {
|
||||
host := "cookienodomain.foo.com"
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "NoDomainCookie"
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
|
|
@ -270,9 +279,9 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
ginkgo.It("should work with use-regex annotation and session-cookie-path", func() {
|
||||
host := "useregex.foo.com"
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/use-regex"] = "true"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
annotations["nginx.ingress.kubernetes.io/use-regex"] = enableAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-path"] = "/foo/bar"
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/foo/.*", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
|
|
@ -294,9 +303,9 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
ginkgo.It("should warn user when use-regex is true and session-cookie-path is not set", func() {
|
||||
host := "useregexwarn.foo.com"
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/use-regex"] = "true"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
annotations["nginx.ingress.kubernetes.io/use-regex"] = enableAnnotation
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/foo/.*", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -321,7 +330,7 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
host := "separate.foo.com"
|
||||
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
|
||||
ing1 := framework.NewSingleIngress("ingress1", "/foo/bar", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing1)
|
||||
|
|
@ -351,8 +360,8 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
|
||||
ginkgo.It("should set sticky cookie without host", func() {
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
|
||||
ing := framework.NewSingleIngress("default-no-host", "/", "", f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -370,12 +379,12 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should work with server-alias annotation", func() {
|
||||
host := "foo.com"
|
||||
host := defaultHost
|
||||
alias1 := "a1.foo.com"
|
||||
alias2 := "a2.foo.com"
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
annotations["nginx.ingress.kubernetes.io/server-alias"] = fmt.Sprintf("%s,%s", alias1, alias2)
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/bar", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
|
|
@ -383,7 +392,7 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
//server alias sort by sort.Strings(), see: internal/ingress/annotations/alias/main.go:60
|
||||
// server alias sort by sort.Strings(), see: internal/ingress/annotations/alias/main.go:60
|
||||
return strings.Contains(server, fmt.Sprintf("server_name %s %s %s ;", host, alias1, alias2))
|
||||
})
|
||||
|
||||
|
|
@ -410,11 +419,11 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set secure in cookie with provided true annotation on http", func() {
|
||||
host := "foo.com"
|
||||
host := defaultHost
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-secure"] = "true"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-secure"] = enableAnnotation
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/bar", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -433,11 +442,11 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not set secure in cookie with provided false annotation on http", func() {
|
||||
host := "foo.com"
|
||||
host := defaultHost
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-secure"] = "false"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-secure"] = disableAnnotation
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/bar", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -456,11 +465,11 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set secure in cookie with provided false annotation on https", func() {
|
||||
host := "foo.com"
|
||||
host := defaultHost
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = "cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "SERVERID"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-secure"] = "false"
|
||||
annotations["nginx.ingress.kubernetes.io/affinity"] = affinityAnnotation
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = cookieName
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-secure"] = disableAnnotation
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, framework.EchoService, 80, annotations))
|
||||
|
||||
|
|
@ -470,6 +479,7 @@ var _ = framework.DescribeAnnotation("affinity session-cookie-name", func() {
|
|||
strings.Contains(server, "listen 443")
|
||||
})
|
||||
|
||||
//nolint:gosec // Ignore the gosec error in testing
|
||||
f.HTTPTestClientWithTLSConfig(&tls.Config{ServerName: host, InsecureSkipVerify: true}).
|
||||
GET("/").
|
||||
WithURL(f.GetURL(framework.HTTPS)).
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const sslRedirectValue = "false"
|
||||
|
||||
var _ = framework.DescribeAnnotation("affinitymode", func() {
|
||||
f := framework.NewDefaultFramework("affinity")
|
||||
|
||||
|
|
@ -45,7 +47,7 @@ var _ = framework.DescribeAnnotation("affinitymode", func() {
|
|||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "hello-cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-expires"] = "172800"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-max-age"] = "172800"
|
||||
annotations["nginx.ingress.kubernetes.io/ssl-redirect"] = "false"
|
||||
annotations["nginx.ingress.kubernetes.io/ssl-redirect"] = sslRedirectValue
|
||||
annotations["nginx.ingress.kubernetes.io/affinity-mode"] = "balanced"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-hash"] = "sha1"
|
||||
|
||||
|
|
@ -78,7 +80,7 @@ var _ = framework.DescribeAnnotation("affinitymode", func() {
|
|||
annotations["nginx.ingress.kubernetes.io/session-cookie-name"] = "hello-cookie"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-expires"] = "172800"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-max-age"] = "172800"
|
||||
annotations["nginx.ingress.kubernetes.io/ssl-redirect"] = "false"
|
||||
annotations["nginx.ingress.kubernetes.io/ssl-redirect"] = sslRedirectValue
|
||||
annotations["nginx.ingress.kubernetes.io/affinity-mode"] = "persistent"
|
||||
annotations["nginx.ingress.kubernetes.io/session-cookie-hash"] = "sha1"
|
||||
|
||||
|
|
@ -106,7 +108,7 @@ var _ = framework.DescribeAnnotation("affinitymode", func() {
|
|||
// Send new requests and add new backends. Check which backend responded to the sent request
|
||||
cookies := getCookiesFromHeader(response.Header("Set-Cookie").Raw())
|
||||
for sendRequestNumber := 0; sendRequestNumber < 10; sendRequestNumber++ {
|
||||
replicas = replicas + 1
|
||||
replicas++
|
||||
err := framework.UpdateDeployment(f.KubeClientSet, f.Namespace, deploymentName, replicas, nil)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
framework.Sleep()
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const fooHost = "foo"
|
||||
|
||||
var _ = framework.DescribeAnnotation("server-alias", func() {
|
||||
f := framework.NewDefaultFramework("alias")
|
||||
|
||||
|
|
@ -34,7 +36,7 @@ var _ = framework.DescribeAnnotation("server-alias", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 200 for host 'foo' and 404 for 'bar'", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -60,7 +62,7 @@ var _ = framework.DescribeAnnotation("server-alias", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 200 for host 'foo' and 'bar'", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/server-alias": "bar",
|
||||
}
|
||||
|
|
@ -73,7 +75,7 @@ var _ = framework.DescribeAnnotation("server-alias", func() {
|
|||
return strings.Contains(server, fmt.Sprintf("server_name %v", host))
|
||||
})
|
||||
|
||||
hosts := []string{"foo", "bar"}
|
||||
hosts := []string{fooHost, "bar"}
|
||||
for _, host := range hosts {
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
|
|
@ -85,7 +87,7 @@ var _ = framework.DescribeAnnotation("server-alias", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 200 for hosts defined in two ingresses, different path with one alias", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
|
||||
ing := framework.NewSingleIngress("app-a", "/app-a", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -101,7 +103,7 @@ var _ = framework.DescribeAnnotation("server-alias", func() {
|
|||
return strings.Contains(server, fmt.Sprintf("server_name %v bar", host))
|
||||
})
|
||||
|
||||
hosts := []string{"foo", "bar"}
|
||||
hosts := []string{fooHost, "bar"}
|
||||
for _, host := range hosts {
|
||||
f.HTTPTestClient().
|
||||
GET("/app-a").
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const (
|
||||
differentHost = "different"
|
||||
authHost = "auth"
|
||||
authURL = "http://foo.bar.baz:5000/path"
|
||||
)
|
||||
|
||||
var _ = framework.DescribeAnnotation("auth-*", func() {
|
||||
f := framework.NewDefaultFramework("auth", framework.WithHTTPBunEnabled())
|
||||
|
||||
|
|
@ -44,7 +50,7 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 200 when no authentication is configured", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -63,7 +69,7 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 503 when authentication is configured with an invalid secret", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||
"nginx.ingress.kubernetes.io/auth-secret": "something",
|
||||
|
|
@ -87,9 +93,9 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 401 when authentication is configured but Authorization header is not configured", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
s := f.EnsureSecret(buildSecret("foo", "bar", "test", f.Namespace))
|
||||
s := f.EnsureSecret(buildSecret(fooHost, "bar", "test", f.Namespace))
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||
|
|
@ -114,9 +120,9 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 401 when authentication is configured and Authorization header is sent with invalid credentials", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
s := f.EnsureSecret(buildSecret("foo", "bar", "test", f.Namespace))
|
||||
s := f.EnsureSecret(buildSecret(fooHost, "bar", "test", f.Namespace))
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||
|
|
@ -142,9 +148,9 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 401 and cors headers when authentication and cors is configured but Authorization header is not configured", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
s := f.EnsureSecret(buildSecret("foo", "bar", "test", f.Namespace))
|
||||
s := f.EnsureSecret(buildSecret(fooHost, "bar", "test", f.Namespace))
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||
|
|
@ -170,9 +176,9 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 200 when authentication is configured and Authorization header is sent", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
s := f.EnsureSecret(buildSecret("foo", "bar", "test", f.Namespace))
|
||||
s := f.EnsureSecret(buildSecret(fooHost, "bar", "test", f.Namespace))
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||
|
|
@ -191,15 +197,15 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
WithBasicAuth("foo", "bar").
|
||||
WithBasicAuth(fooHost, "bar").
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
|
||||
ginkgo.It("should return status code 200 when authentication is configured with a map and Authorization header is sent", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
s := f.EnsureSecret(buildMapSecret("foo", "bar", "test", f.Namespace))
|
||||
s := f.EnsureSecret(buildMapSecret(fooHost, "bar", "test", f.Namespace))
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||
|
|
@ -219,13 +225,13 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
WithBasicAuth("foo", "bar").
|
||||
WithBasicAuth(fooHost, "bar").
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
|
||||
ginkgo.It("should return status code 401 when authentication is configured with invalid content and Authorization header is sent", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
s := f.EnsureSecret(
|
||||
&corev1.Secret{
|
||||
|
|
@ -258,19 +264,27 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
WithBasicAuth("foo", "bar").
|
||||
WithBasicAuth(fooHost, "bar").
|
||||
Expect().
|
||||
Status(http.StatusUnauthorized)
|
||||
})
|
||||
|
||||
ginkgo.It(`should set snippet "proxy_set_header My-Custom-Header 42;" when external auth is configured`, func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-url": "http://foo.bar/basic-auth/user/password",
|
||||
"nginx.ingress.kubernetes.io/auth-snippet": `
|
||||
proxy_set_header My-Custom-Header 42;`,
|
||||
}
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -282,7 +296,16 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`should not set snippet "proxy_set_header My-Custom-Header 42;" when external auth is not configured`, func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-snippet": `
|
||||
|
|
@ -299,7 +322,7 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`should set "proxy_set_header 'My-Custom-Header' '42';" when auth-headers are set`, func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-url": "http://foo.bar/basic-auth/user/password",
|
||||
|
|
@ -320,11 +343,11 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`should set cache_key when external auth cache is configured`, func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-url": "http://foo.bar/basic-auth/user/password",
|
||||
"nginx.ingress.kubernetes.io/auth-cache-key": "foo",
|
||||
"nginx.ingress.kubernetes.io/auth-cache-key": fooHost,
|
||||
"nginx.ingress.kubernetes.io/auth-cache-duration": "200 202 401 30m",
|
||||
}
|
||||
|
||||
|
|
@ -337,7 +360,6 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
func(server string) bool {
|
||||
return cacheRegex.MatchString(server) &&
|
||||
strings.Contains(server, `proxy_cache_valid 200 202 401 30m;`)
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -403,9 +425,9 @@ http {
|
|||
f.EnsureIngress(ing2)
|
||||
|
||||
f.WaitForNginxServer(host, func(server string) bool {
|
||||
//nolint:goconst //server_name is a constant
|
||||
return strings.Contains(server, "server_name "+host)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
ginkgo.It("user retains cookie by default", func() {
|
||||
|
|
@ -431,7 +453,7 @@ http {
|
|||
})
|
||||
|
||||
ginkgo.It("user with annotated ingress retains cookie if upstream returns error status code", func() {
|
||||
annotations["nginx.ingress.kubernetes.io/auth-always-set-cookie"] = "true"
|
||||
annotations["nginx.ingress.kubernetes.io/auth-always-set-cookie"] = enableAnnotation
|
||||
f.UpdateIngress(ing1)
|
||||
f.UpdateIngress(ing2)
|
||||
|
||||
|
|
@ -451,7 +473,7 @@ http {
|
|||
})
|
||||
|
||||
ginkgo.Context("when external authentication is configured", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
var annotations map[string]string
|
||||
var ing *networking.Ingress
|
||||
|
||||
|
|
@ -495,7 +517,7 @@ http {
|
|||
annotations["nginx.ingress.kubernetes.io/auth-realm"] = "test auth"
|
||||
f.UpdateIngress(ing)
|
||||
|
||||
anotherHost := "different"
|
||||
anotherHost := differentHost
|
||||
anotherAnnotations := map[string]string{}
|
||||
|
||||
anotherIng := framework.NewSingleIngress(anotherHost, "/", anotherHost, f.Namespace, framework.EchoService, 80, anotherAnnotations)
|
||||
|
|
@ -544,12 +566,12 @@ http {
|
|||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
|
||||
annotations["nginx.ingress.kubernetes.io/auth-url"] = "http://foo.bar.baz:5000/path"
|
||||
annotations["nginx.ingress.kubernetes.io/auth-url"] = authURL
|
||||
f.UpdateIngress(ing)
|
||||
|
||||
f.WaitForNginxServer("",
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "http://foo.bar.baz:5000/path") &&
|
||||
return strings.Contains(server, authURL) &&
|
||||
!strings.Contains(server, `upstream auth-external-auth`)
|
||||
})
|
||||
})
|
||||
|
|
@ -582,19 +604,19 @@ http {
|
|||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
|
||||
annotations["nginx.ingress.kubernetes.io/auth-url"] = "http://foo.bar.baz:5000/path"
|
||||
annotations["nginx.ingress.kubernetes.io/auth-url"] = authURL
|
||||
annotations["nginx.ingress.kubernetes.io/auth-keepalive"] = "-1"
|
||||
f.UpdateIngress(ing)
|
||||
|
||||
f.WaitForNginxServer("",
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "http://foo.bar.baz:5000/path") &&
|
||||
return strings.Contains(server, authURL) &&
|
||||
!strings.Contains(server, `upstream auth-external-auth`)
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.It(`should not create additional upstream block when auth-keepalive is set with HTTP/2`, func() {
|
||||
annotations["nginx.ingress.kubernetes.io/auth-url"] = "http://foo.bar.baz:5000/path"
|
||||
annotations["nginx.ingress.kubernetes.io/auth-url"] = authURL
|
||||
annotations["nginx.ingress.kubernetes.io/auth-keepalive"] = "123"
|
||||
annotations["nginx.ingress.kubernetes.io/auth-keepalive-requests"] = "456"
|
||||
annotations["nginx.ingress.kubernetes.io/auth-keepalive-timeout"] = "789"
|
||||
|
|
@ -602,7 +624,7 @@ http {
|
|||
|
||||
f.WaitForNginxServer("",
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "http://foo.bar.baz:5000/path") &&
|
||||
return strings.Contains(server, authURL) &&
|
||||
!strings.Contains(server, `upstream auth-external-auth`)
|
||||
})
|
||||
})
|
||||
|
|
@ -628,10 +650,49 @@ http {
|
|||
strings.Contains(server, `keepalive_timeout 789s;`)
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.It(`should disable set_all_vars when auth-keepalive-share-vars is not set`, func() {
|
||||
f.UpdateNginxConfigMapData("use-http2", "false")
|
||||
defer func() {
|
||||
f.UpdateNginxConfigMapData("use-http2", "true")
|
||||
}()
|
||||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
|
||||
annotations["nginx.ingress.kubernetes.io/auth-keepalive"] = "10"
|
||||
f.UpdateIngress(ing)
|
||||
|
||||
f.WaitForNginxServer("",
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, `upstream auth-external-auth`) &&
|
||||
strings.Contains(server, `keepalive 10;`) &&
|
||||
strings.Contains(server, `share_all_vars = false`)
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.It(`should enable set_all_vars when auth-keepalive-share-vars is true`, func() {
|
||||
f.UpdateNginxConfigMapData("use-http2", "false")
|
||||
defer func() {
|
||||
f.UpdateNginxConfigMapData("use-http2", "true")
|
||||
}()
|
||||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
|
||||
annotations["nginx.ingress.kubernetes.io/auth-keepalive"] = "10"
|
||||
annotations["nginx.ingress.kubernetes.io/auth-keepalive-share-vars"] = enableAnnotation
|
||||
f.UpdateIngress(ing)
|
||||
|
||||
f.WaitForNginxServer("",
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, `upstream auth-external-auth`) &&
|
||||
strings.Contains(server, `keepalive 10;`) &&
|
||||
strings.Contains(server, `share_all_vars = true`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.Context("when external authentication is configured with a custom redirect param", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
var annotations map[string]string
|
||||
var ing *networking.Ingress
|
||||
|
||||
|
|
@ -676,7 +737,7 @@ http {
|
|||
annotations["nginx.ingress.kubernetes.io/auth-realm"] = "test auth"
|
||||
f.UpdateIngress(ing)
|
||||
|
||||
anotherHost := "different"
|
||||
anotherHost := differentHost
|
||||
anotherAnnotations := map[string]string{}
|
||||
|
||||
anotherIng := framework.NewSingleIngress(anotherHost, "/", anotherHost, f.Namespace, framework.EchoService, 80, anotherAnnotations)
|
||||
|
|
@ -696,8 +757,8 @@ http {
|
|||
})
|
||||
|
||||
ginkgo.Context("when external authentication with caching is configured", func() {
|
||||
thisHost := "auth"
|
||||
thatHost := "different"
|
||||
thisHost := authHost
|
||||
thatHost := differentHost
|
||||
|
||||
fooPath := "/foo"
|
||||
barPath := "/bar"
|
||||
|
|
@ -819,7 +880,7 @@ http {
|
|||
})
|
||||
|
||||
ginkgo.Context("with invalid auth-url should deny whole location", func() {
|
||||
host := "auth"
|
||||
host := authHost
|
||||
var annotations map[string]string
|
||||
var ing *networking.Ingress
|
||||
|
||||
|
|
@ -859,7 +920,6 @@ http {
|
|||
// Auth error
|
||||
|
||||
func buildSecret(username, password, name, namespace string) *corev1.Secret {
|
||||
//out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput()
|
||||
out, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
||||
encpass := fmt.Sprintf("%v:%s\n", username, out)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
|
|
@ -878,7 +938,6 @@ func buildSecret(username, password, name, namespace string) *corev1.Secret {
|
|||
}
|
||||
|
||||
func buildMapSecret(username, password, name, namespace string) *corev1.Secret {
|
||||
//out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput()
|
||||
out, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
|
||||
|
|
@ -889,7 +948,7 @@ func buildMapSecret(username, password, name, namespace string) *corev1.Secret {
|
|||
DeletionGracePeriodSeconds: framework.NewInt64(1),
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
username: []byte(out),
|
||||
username: out,
|
||||
},
|
||||
Type: corev1.SecretTypeOpaque,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const authTLSFooHost = "authtls.foo.com"
|
||||
|
||||
var _ = framework.DescribeAnnotation("auth-tls-*", func() {
|
||||
f := framework.NewDefaultFramework("authtls")
|
||||
|
||||
|
|
@ -34,7 +36,7 @@ var _ = framework.DescribeAnnotation("auth-tls-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set sslClientCertificate, sslVerifyClient and sslVerifyDepth with auth-tls-secret", func() {
|
||||
host := "authtls.foo.com"
|
||||
host := authTLSFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
clientConfig, err := framework.CreateIngressMASecret(
|
||||
|
|
@ -82,7 +84,7 @@ var _ = framework.DescribeAnnotation("auth-tls-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set valid auth-tls-secret, sslVerify to off, and sslVerifyDepth to 2", func() {
|
||||
host := "authtls.foo.com"
|
||||
host := authTLSFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
_, err := framework.CreateIngressMASecret(
|
||||
|
|
@ -112,7 +114,7 @@ var _ = framework.DescribeAnnotation("auth-tls-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should 302 redirect to error page instead of 400 when auth-tls-error-page is set", func() {
|
||||
host := "authtls.foo.com"
|
||||
host := authTLSFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
errorPath := "/error"
|
||||
|
|
@ -159,7 +161,7 @@ var _ = framework.DescribeAnnotation("auth-tls-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should pass URL-encoded certificate to upstream", func() {
|
||||
host := "authtls.foo.com"
|
||||
host := authTLSFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
clientConfig, err := framework.CreateIngressMASecret(
|
||||
|
|
@ -204,7 +206,7 @@ var _ = framework.DescribeAnnotation("auth-tls-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should validate auth-tls-verify-client", func() {
|
||||
host := "authtls.foo.com"
|
||||
host := authTLSFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
clientConfig, err := framework.CreateIngressMASecret(
|
||||
|
|
@ -260,11 +262,10 @@ var _ = framework.DescribeAnnotation("auth-tls-*", func() {
|
|||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
})
|
||||
|
||||
ginkgo.It("should return 403 using auth-tls-match-cn with no matching CN from client", func() {
|
||||
host := "authtls.foo.com"
|
||||
host := authTLSFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
clientConfig, err := framework.CreateIngressMASecret(
|
||||
|
|
@ -293,7 +294,7 @@ var _ = framework.DescribeAnnotation("auth-tls-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return 200 using auth-tls-match-cn with matching CN from client", func() {
|
||||
host := "authtls.foo.com"
|
||||
host := authTLSFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
clientConfig, err := framework.CreateIngressMASecret(
|
||||
|
|
@ -322,7 +323,7 @@ var _ = framework.DescribeAnnotation("auth-tls-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return 200 using auth-tls-match-cn where atleast one of the regex options matches CN from client", func() {
|
||||
host := "authtls.foo.com"
|
||||
host := authTLSFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
clientConfig, err := framework.CreateIngressMASecret(
|
||||
|
|
@ -351,7 +352,8 @@ var _ = framework.DescribeAnnotation("auth-tls-*", func() {
|
|||
})
|
||||
})
|
||||
|
||||
func assertSslClientCertificateConfig(f *framework.Framework, host string, verifyClient string, verifyDepth string) {
|
||||
//nolint:unparam // Ignore the invariant param: host
|
||||
func assertSslClientCertificateConfig(f *framework.Framework, host, verifyClient, verifyDepth string) {
|
||||
sslClientCertDirective := fmt.Sprintf("ssl_client_certificate /etc/ingress-controller/ssl/%s-%s.pem;", f.Namespace, host)
|
||||
sslVerify := fmt.Sprintf("ssl_verify_client %s;", verifyClient)
|
||||
sslVerifyDepth := fmt.Sprintf("ssl_verify_depth %s;", verifyDepth)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const backendProtocolHost = "backendprotocol.foo.com"
|
||||
|
||||
var _ = framework.DescribeAnnotation("backend-protocol", func() {
|
||||
f := framework.NewDefaultFramework("backendprotocol")
|
||||
|
||||
|
|
@ -32,7 +34,7 @@ var _ = framework.DescribeAnnotation("backend-protocol", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set backend protocol to https:// and use proxy_pass", func() {
|
||||
host := "backendprotocol.foo.com"
|
||||
host := backendProtocolHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "HTTPS",
|
||||
}
|
||||
|
|
@ -46,8 +48,23 @@ var _ = framework.DescribeAnnotation("backend-protocol", func() {
|
|||
})
|
||||
})
|
||||
|
||||
ginkgo.It("should set backend protocol to https:// and use proxy_pass with lowercase annotation", func() {
|
||||
host := backendProtocolHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "https",
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "proxy_pass https://upstream_balancer;")
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.It("should set backend protocol to $scheme:// and use proxy_pass", func() {
|
||||
host := "backendprotocol.foo.com"
|
||||
host := backendProtocolHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "AUTO_HTTP",
|
||||
}
|
||||
|
|
@ -62,7 +79,7 @@ var _ = framework.DescribeAnnotation("backend-protocol", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set backend protocol to grpc:// and use grpc_pass", func() {
|
||||
host := "backendprotocol.foo.com"
|
||||
host := backendProtocolHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "GRPC",
|
||||
}
|
||||
|
|
@ -77,7 +94,7 @@ var _ = framework.DescribeAnnotation("backend-protocol", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set backend protocol to grpcs:// and use grpc_pass", func() {
|
||||
host := "backendprotocol.foo.com"
|
||||
host := backendProtocolHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "GRPCS",
|
||||
}
|
||||
|
|
@ -92,7 +109,7 @@ var _ = framework.DescribeAnnotation("backend-protocol", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set backend protocol to '' and use fastcgi_pass", func() {
|
||||
host := "backendprotocol.foo.com"
|
||||
host := backendProtocolHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "FCGI",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
|
||||
ginkgo.Context("when canary is created", func() {
|
||||
ginkgo.It("should response with a 200 status from the mainline upstream when requests are made to the mainline ingress", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -87,7 +87,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return 404 status for requests to the canary if no matching ingress is found", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
|
||||
canaryAnnotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/canary": "true",
|
||||
|
|
@ -118,7 +118,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
TODO: This test needs improvements made to the e2e framework so that deployment updates work in order to successfully run
|
||||
|
||||
It("should return the correct status codes when endpoints are unavailable", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/info", host, f.Namespace, framework.HTTPBunService, 80, annotations)
|
||||
|
|
@ -172,7 +172,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
*/
|
||||
|
||||
ginkgo.It("should route requests to the correct upstream if mainline ingress is created before the canary ingress", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -230,7 +230,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should route requests to the correct upstream if mainline ingress is created after the canary ingress", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
|
||||
canaryAnnotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/canary": "true",
|
||||
|
|
@ -287,7 +287,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should route requests to the correct upstream if the mainline ingress is modified", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -321,7 +321,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
canaryAnnotations))
|
||||
|
||||
modAnnotations := map[string]string{
|
||||
"foo": "bar",
|
||||
fooHost: "bar",
|
||||
}
|
||||
|
||||
f.UpdateIngress(framework.NewSingleIngress(
|
||||
|
|
@ -361,7 +361,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should route requests to the correct upstream if the canary ingress is modified", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -443,7 +443,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
|
||||
ginkgo.Context("when canaried by header with no value", func() {
|
||||
ginkgo.It("should route requests to the correct upstream", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
host,
|
||||
|
|
@ -511,7 +511,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
|
||||
ginkgo.Context("when canaried by header with value", func() {
|
||||
ginkgo.It("should route requests to the correct upstream", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -592,7 +592,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
|
||||
ginkgo.Context("when canaried by header with value and pattern", func() {
|
||||
ginkgo.It("should route requests to the correct upstream", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -645,7 +645,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
Body().Contains(framework.HTTPBunService).NotContains(canaryService)
|
||||
})
|
||||
ginkgo.It("should route requests to the correct upstream", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -690,7 +690,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
Body().Contains(framework.HTTPBunService).NotContains(canaryService)
|
||||
})
|
||||
ginkgo.It("should routes to mainline upstream when the given Regex causes error", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -739,7 +739,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
|
||||
ginkgo.Context("when canaried by header with value and cookie", func() {
|
||||
ginkgo.It("should route requests to the correct upstream", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -788,7 +788,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
|
||||
ginkgo.Context("when canaried by cookie", func() {
|
||||
ginkgo.It("respects always and never values", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -860,7 +860,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
|
||||
ginkgo.Context("when canaried by weight", func() {
|
||||
ginkgo.It("should route requests only to mainline if canary weight is 0", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -908,7 +908,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should route requests only to canary if canary weight is 100", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -950,7 +950,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should route requests only to canary if canary weight is equal to canary weight total", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -993,7 +993,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should route requests split between mainline and canary if canary weight is 50", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -1029,7 +1029,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should route requests split between mainline and canary if canary weight is 100 and weight total is 200", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
annotations := map[string]string{}
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(
|
||||
|
|
@ -1068,7 +1068,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
|
||||
ginkgo.Context("Single canary Ingress", func() {
|
||||
ginkgo.It("should not use canary as a catch-all server", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
canaryIngName := fmt.Sprintf("%v-canary", host)
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/canary": "true",
|
||||
|
|
@ -1102,7 +1102,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not use canary with domain as a server", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
canaryIngName := fmt.Sprintf("%v-canary", host)
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/canary": "true",
|
||||
|
|
@ -1136,7 +1136,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("does not crash when canary ingress has multiple paths to the same non-matching backend", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
canaryIngName := fmt.Sprintf("%v-canary", host)
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/canary": "true",
|
||||
|
|
@ -1168,7 +1168,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.Context("canary affinity behavior", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
affinityCookieName := "aff"
|
||||
canaryIngName := fmt.Sprintf("%v-canary", host)
|
||||
|
||||
|
|
@ -1370,7 +1370,6 @@ var _ = framework.DescribeAnnotation("canary-*", func() {
|
|||
TestMainlineCanaryDistribution(f, host)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
// This method assumes canary weight being configured at 50%.
|
||||
|
|
@ -1407,12 +1406,12 @@ func TestMainlineCanaryDistribution(f *framework.Framework, host string) {
|
|||
|
||||
assert.GreaterOrEqual(
|
||||
ginkgo.GinkgoT(),
|
||||
int(replicaRequestCount[keys[0].String()]),
|
||||
replicaRequestCount[keys[0].String()],
|
||||
requestsNumberToTest,
|
||||
)
|
||||
assert.GreaterOrEqual(
|
||||
ginkgo.GinkgoT(),
|
||||
int(replicaRequestCount[keys[1].String()]),
|
||||
replicaRequestCount[keys[1].String()],
|
||||
requestsNumberToTest,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const clientBodyBufferSizeHost = "client-body-buffer-size.com"
|
||||
|
||||
var _ = framework.DescribeAnnotation("client-body-buffer-size", func() {
|
||||
f := framework.NewDefaultFramework("clientbodybuffersize")
|
||||
|
||||
|
|
@ -33,7 +35,7 @@ var _ = framework.DescribeAnnotation("client-body-buffer-size", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set client_body_buffer_size to 1000", func() {
|
||||
host := "client-body-buffer-size.com"
|
||||
host := clientBodyBufferSizeHost
|
||||
|
||||
clientBodyBufferSize := "1000"
|
||||
annotations := make(map[string]string)
|
||||
|
|
@ -55,7 +57,7 @@ var _ = framework.DescribeAnnotation("client-body-buffer-size", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set client_body_buffer_size to 1K", func() {
|
||||
host := "client-body-buffer-size.com"
|
||||
host := clientBodyBufferSizeHost
|
||||
|
||||
clientBodyBufferSize := "1K"
|
||||
annotations := make(map[string]string)
|
||||
|
|
@ -77,7 +79,7 @@ var _ = framework.DescribeAnnotation("client-body-buffer-size", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set client_body_buffer_size to 1k", func() {
|
||||
host := "client-body-buffer-size.com"
|
||||
host := clientBodyBufferSizeHost
|
||||
|
||||
clientBodyBufferSize := "1k"
|
||||
annotations := make(map[string]string)
|
||||
|
|
@ -99,7 +101,7 @@ var _ = framework.DescribeAnnotation("client-body-buffer-size", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set client_body_buffer_size to 1m", func() {
|
||||
host := "client-body-buffer-size.com"
|
||||
host := clientBodyBufferSizeHost
|
||||
|
||||
clientBodyBufferSize := "1m"
|
||||
annotations := make(map[string]string)
|
||||
|
|
@ -121,7 +123,7 @@ var _ = framework.DescribeAnnotation("client-body-buffer-size", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set client_body_buffer_size to 1M", func() {
|
||||
host := "client-body-buffer-size.com"
|
||||
host := clientBodyBufferSizeHost
|
||||
|
||||
clientBodyBufferSize := "1M"
|
||||
annotations := make(map[string]string)
|
||||
|
|
@ -143,7 +145,7 @@ var _ = framework.DescribeAnnotation("client-body-buffer-size", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not set client_body_buffer_size to invalid 1b", func() {
|
||||
host := "client-body-buffer-size.com"
|
||||
host := clientBodyBufferSizeHost
|
||||
|
||||
clientBodyBufferSize := "1b"
|
||||
annotations := make(map[string]string)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const (
|
||||
originHost = "http://origin.com:8080"
|
||||
corsHost = "cors.foo.com"
|
||||
)
|
||||
|
||||
var _ = framework.DescribeAnnotation("cors-*", func() {
|
||||
f := framework.NewDefaultFramework("cors")
|
||||
|
||||
|
|
@ -33,7 +38,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable cors", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
}
|
||||
|
|
@ -60,7 +65,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set cors methods to only allow POST, GET", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
"nginx.ingress.kubernetes.io/cors-allow-methods": "POST, GET",
|
||||
|
|
@ -76,7 +81,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set cors max-age", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
"nginx.ingress.kubernetes.io/cors-max-age": "200",
|
||||
|
|
@ -92,7 +97,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should disable cors allow credentials", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
"nginx.ingress.kubernetes.io/cors-allow-credentials": "false",
|
||||
|
|
@ -108,7 +113,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should allow origin for cors", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
origin := "https://origin.cors.com:8080"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
|
|
@ -135,7 +140,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should allow headers for cors", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
"nginx.ingress.kubernetes.io/cors-allow-headers": "DNT, User-Agent",
|
||||
|
|
@ -151,7 +156,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should expose headers for cors", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
"nginx.ingress.kubernetes.io/cors-expose-headers": "X-CustomResponseHeader, X-CustomSecondHeader",
|
||||
|
|
@ -167,7 +172,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should allow - single origin for multiple cors values", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
origin := "https://origin.cors.com:8080"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
|
|
@ -194,7 +199,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not allow - single origin for multiple cors values", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
origin := "http://no.origin.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
|
|
@ -214,7 +219,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should allow correct origins - single origin for multiple cors values", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
badOrigin := "origin.cors.com:8080"
|
||||
origin1 := "https://origin2.cors.com"
|
||||
origin2 := "https://origin.com"
|
||||
|
|
@ -265,7 +270,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not break functionality", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
"nginx.ingress.kubernetes.io/cors-allow-origin": "*",
|
||||
|
|
@ -289,7 +294,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not break functionality - without `*`", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
}
|
||||
|
|
@ -312,7 +317,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not break functionality with extra domain", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
"nginx.ingress.kubernetes.io/cors-allow-origin": "*, foo.bar.com",
|
||||
|
|
@ -336,7 +341,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not match", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
origin := "https://fooxbar.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
|
|
@ -356,8 +361,8 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should allow - single origin with required port", func() {
|
||||
host := "cors.foo.com"
|
||||
origin := "http://origin.com:8080"
|
||||
host := corsHost
|
||||
origin := originHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
"nginx.ingress.kubernetes.io/cors-allow-origin": "http://origin.cors.com:8080, http://origin.com:8080",
|
||||
|
|
@ -384,8 +389,8 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not allow - single origin with port and origin without port", func() {
|
||||
host := "cors.foo.com"
|
||||
origin := "http://origin.com:8080"
|
||||
host := corsHost
|
||||
origin := originHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
"nginx.ingress.kubernetes.io/cors-allow-origin": "https://origin2.cors.com, http://origin.com",
|
||||
|
|
@ -403,7 +408,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not allow - single origin without port and origin with required port", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
origin := "http://origin.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
|
|
@ -423,7 +428,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should allow - matching origin with wildcard origin (2 subdomains)", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
origin := "http://foo.origin.cors.com"
|
||||
origin2 := "http://bar-foo.origin.cors.com"
|
||||
annotations := map[string]string{
|
||||
|
|
@ -466,7 +471,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not allow - unmatching origin with wildcard origin (2 subdomains)", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
origin := "http://bar.foo.origin.cors.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
|
|
@ -486,7 +491,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should allow - matching origin+port with wildcard origin", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
origin := "http://abc.origin.com:8080"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
|
|
@ -513,7 +518,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not allow - portless origin with wildcard origin", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
origin := "http://abc.origin.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
|
|
@ -533,8 +538,8 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should allow correct origins - missing subdomain + origin with wildcard origin and correct origin", func() {
|
||||
host := "cors.foo.com"
|
||||
badOrigin := "http://origin.com:8080"
|
||||
host := corsHost
|
||||
badOrigin := originHost
|
||||
origin := "http://bar.origin.com:8080"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
|
|
@ -569,7 +574,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should allow - missing origins (should allow all origins)", func() {
|
||||
host := "cors.foo.com"
|
||||
host := corsHost
|
||||
origin := "http://origin.com"
|
||||
origin2 := "http://book.origin.com"
|
||||
origin3 := "test.origin.com"
|
||||
|
|
@ -627,4 +632,41 @@ var _ = framework.DescribeAnnotation("cors-*", func() {
|
|||
Status(http.StatusOK).Headers().
|
||||
ValueEqual("Access-Control-Allow-Origin", []string{"*"})
|
||||
})
|
||||
|
||||
ginkgo.It("should allow correct origin but not others - cors allow origin annotations contain trailing comma", func() {
|
||||
host := corsHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-cors": "true",
|
||||
"nginx.ingress.kubernetes.io/cors-allow-origin": "https://origin-123.cors.com:8080, ,https://origin-321.cors.com:8080,",
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
origin1 := "https://origin-123.cors.com:8080"
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Origin", origin1).
|
||||
Expect().
|
||||
Headers().ContainsKey("Access-Control-Allow-Origin")
|
||||
|
||||
origin2 := "https://origin-321.cors.com:8080"
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Origin", origin2).
|
||||
Expect().
|
||||
Status(http.StatusOK).Headers().
|
||||
ValueEqual("Access-Control-Allow-Origin", []string{origin2})
|
||||
|
||||
origin3 := "https://unknown.cors.com:8080"
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Origin", origin3).
|
||||
Expect().
|
||||
Headers().
|
||||
NotContainsKey("Access-Control-Allow-Origin")
|
||||
})
|
||||
})
|
||||
|
|
|
|||
110
test/e2e/annotations/customheaders.go
Normal file
110
test/e2e/annotations/customheaders.go
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package annotations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const (
|
||||
customHeaderHost = "custom-headers"
|
||||
)
|
||||
|
||||
var _ = framework.DescribeAnnotation("custom-headers-*", func() {
|
||||
f := framework.NewDefaultFramework("custom-headers")
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
f.NewEchoDeployment()
|
||||
})
|
||||
|
||||
ginkgo.It("should return status code 200 when no custom-headers is configured", func() {
|
||||
ing := framework.NewSingleIngress(customHeaderHost, "/", customHeaderHost, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.WaitForNginxServer(customHeaderHost,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "server_name custom-headers")
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", customHeaderHost).
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
Body().Contains(fmt.Sprintf("host=%v", customHeaderHost))
|
||||
})
|
||||
|
||||
ginkgo.It("should return status code 503 when custom-headers is configured with an invalid secret", func() {
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/custom-headers": f.Namespace + "/custom-headers",
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(customHeaderHost, "/", customHeaderHost, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.WaitForNginxServer(customHeaderHost,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "server_name custom-headers")
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", customHeaderHost).
|
||||
Expect().
|
||||
Status(http.StatusServiceUnavailable).
|
||||
Body().Contains("503 Service Temporarily Unavailable")
|
||||
})
|
||||
|
||||
ginkgo.It(`should set "more_set_headers 'My-Custom-Header' '42';" when custom-headers are set`, func() {
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/custom-headers": f.Namespace + "/custom-headers",
|
||||
}
|
||||
|
||||
f.CreateConfigMap("custom-headers", map[string]string{
|
||||
"My-Custom-Header": "42",
|
||||
"My-Custom-Header-Dollar": "$remote_addr",
|
||||
})
|
||||
f.UpdateNginxConfigMapData("global-allowed-response-headers", "My-Custom-Header,My-Custom-Header-Dollar")
|
||||
|
||||
ing := framework.NewSingleIngress(customHeaderHost, "/", customHeaderHost, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.WaitForNginxServer(customHeaderHost,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, `more_set_headers "My-Custom-Header: 42";`)
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", customHeaderHost).
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
Header("My-Custom-Header").Contains("42")
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", customHeaderHost).
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
Header("My-Custom-Header-Dollar").Contains("$remote_addr")
|
||||
})
|
||||
})
|
||||
|
|
@ -27,7 +27,7 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
func errorBlockName(upstreamName string, errorCode string) string {
|
||||
func errorBlockName(upstreamName, errorCode string) string {
|
||||
return fmt.Sprintf("@custom_%s_%s", upstreamName, errorCode)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,18 +48,18 @@ var _ = framework.DescribeAnnotation("default-backend", func() {
|
|||
return strings.Contains(server, fmt.Sprintf("server_name %v", host))
|
||||
})
|
||||
|
||||
requestId := "something-unique"
|
||||
requestID := "something-unique"
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/alma/armud").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("x-request-id", requestId).
|
||||
WithHeader("x-request-id", requestID).
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
Body().Contains("x-code=503").
|
||||
Contains(fmt.Sprintf("x-ingress-name=%s", host)).
|
||||
Contains("x-service-name=invalid").
|
||||
Contains(fmt.Sprintf("x-request-id=%s", requestId))
|
||||
Contains(fmt.Sprintf("x-request-id=%s", requestID))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
100
test/e2e/annotations/disableproxyintercepterrors.go
Normal file
100
test/e2e/annotations/disableproxyintercepterrors.go
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package annotations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
networking "k8s.io/api/networking/v1"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.DescribeAnnotation("disable-proxy-intercept-errors", func() {
|
||||
f := framework.NewDefaultFramework("disable-proxy-intercept-errors")
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
f.NewHttpbunDeployment()
|
||||
f.NewEchoDeployment()
|
||||
})
|
||||
|
||||
ginkgo.It("configures Nginx correctly", func() {
|
||||
host := "pie.foo.com"
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/custom-http-errors": "404",
|
||||
"nginx.ingress.kubernetes.io/disable-proxy-intercept-errors": "true",
|
||||
"nginx.ingress.kubernetes.io/default-backend": framework.EchoService,
|
||||
}
|
||||
|
||||
ingHTTPBunService := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBunService, 80, annotations)
|
||||
f.EnsureIngress(ingHTTPBunService)
|
||||
|
||||
var serverConfig string
|
||||
f.WaitForNginxServer(host, func(sc string) bool {
|
||||
serverConfig = sc
|
||||
return strings.Contains(serverConfig, fmt.Sprintf("server_name %s", host))
|
||||
})
|
||||
|
||||
ginkgo.By("turning off proxy_intercept_errors directive")
|
||||
assert.NotContains(ginkgo.GinkgoT(), serverConfig, "proxy_intercept_errors on;")
|
||||
|
||||
// the plan for client side testing
|
||||
// create ingress where we disable intercept for code 404 - that error should get to the client
|
||||
// the same ingress should intercept any other error (>300 and not 404) where we will get intercepted error
|
||||
ginkgo.By("client test to check response - with intercept disabled")
|
||||
requestID := "proxy_intercept_errors"
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/status/404").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("x-request-id", requestID).
|
||||
Expect().
|
||||
Status(http.StatusNotFound).
|
||||
Body().Empty()
|
||||
|
||||
ginkgo.By("client test to check response - with intercept enabled")
|
||||
err := framework.UpdateIngress(f.KubeClientSet, f.Namespace, host, func(ingress *networking.Ingress) error {
|
||||
ingress.ObjectMeta.Annotations["nginx.ingress.kubernetes.io/disable-proxy-intercept-errors"] = "false"
|
||||
return nil
|
||||
})
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
|
||||
f.WaitForNginxServer(host, func(sc string) bool {
|
||||
if serverConfig != sc {
|
||||
serverConfig = sc
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/status/404").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("x-request-id", requestID).
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
Body().Contains("x-code=404").
|
||||
Contains(fmt.Sprintf("x-ingress-name=%s", host)).
|
||||
Contains(fmt.Sprintf("x-service-name=%s", framework.HTTPBunService)).
|
||||
Contains(fmt.Sprintf("x-request-id=%s", requestID))
|
||||
})
|
||||
})
|
||||
|
|
@ -75,14 +75,14 @@ var _ = framework.DescribeAnnotation("backend-protocol - FastCGI", func() {
|
|||
Namespace: f.Namespace,
|
||||
},
|
||||
Data: map[string]string{
|
||||
"SCRIPT_FILENAME": "/home/www/scripts/php$fastcgi_script_name",
|
||||
"SCRIPT_FILENAME": "$fastcgi_script_name",
|
||||
"REDIRECT_STATUS": "200",
|
||||
},
|
||||
}
|
||||
|
||||
f.EnsureConfigMap(configuration)
|
||||
|
||||
host := "fastcgi-params-configmap"
|
||||
host := "fastcgi-params-configmap" //#nosec G101
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "FCGI",
|
||||
|
|
@ -94,7 +94,7 @@ var _ = framework.DescribeAnnotation("backend-protocol - FastCGI", func() {
|
|||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "fastcgi_param SCRIPT_FILENAME \"/home/www/scripts/php$fastcgi_script_name\";") &&
|
||||
return strings.Contains(server, "fastcgi_param SCRIPT_FILENAME \"$fastcgi_script_name\";") &&
|
||||
strings.Contains(server, "fastcgi_param REDIRECT_STATUS \"200\";")
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -62,6 +62,15 @@ var _ = framework.DescribeAnnotation("from-to-www-redirect", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should redirect from www HTTPS to HTTPS", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
ginkgo.By("setting up server for redirect from www")
|
||||
|
||||
fromHost := fmt.Sprintf("%s.nip.io", f.GetNginxIP())
|
||||
|
|
@ -90,7 +99,7 @@ var _ = framework.DescribeAnnotation("from-to-www-redirect", func() {
|
|||
|
||||
ginkgo.By("sending request to www should redirect to domain")
|
||||
f.HTTPTestClientWithTLSConfig(&tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
InsecureSkipVerify: true, //nolint:gosec // Ignore the gosec error in testing
|
||||
ServerName: toHost,
|
||||
}).
|
||||
GET("/").
|
||||
|
|
@ -102,7 +111,7 @@ var _ = framework.DescribeAnnotation("from-to-www-redirect", func() {
|
|||
|
||||
ginkgo.By("sending request to domain should not redirect to www")
|
||||
f.HTTPTestClientWithTLSConfig(&tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
InsecureSkipVerify: true, //nolint:gosec // Ignore the gosec error in testing
|
||||
ServerName: fromHost,
|
||||
}).
|
||||
GET("/").
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ var _ = framework.DescribeAnnotation("annotation-global-rate-limit", func() {
|
|||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
ing = f.EnsureIngress(ing)
|
||||
namespace := strings.Replace(string(ing.UID), "-", "", -1)
|
||||
namespace := strings.ReplaceAll(string(ing.UID), "-", "")
|
||||
|
||||
serverConfig := ""
|
||||
f.WaitForNginxServer(host, func(server string) bool {
|
||||
|
|
|
|||
|
|
@ -17,12 +17,11 @@ limitations under the License.
|
|||
package annotations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"context"
|
||||
|
||||
pb "github.com/moul/pb/grpcbin/go-grpc"
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -36,6 +35,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const echoHost = "echo"
|
||||
|
||||
var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
|
||||
f := framework.NewDefaultFramework("grpc", framework.WithHTTPBunEnabled())
|
||||
|
||||
|
|
@ -67,7 +68,7 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
|
|||
ginkgo.It("should return OK for service with backend protocol GRPC", func() {
|
||||
f.NewGRPCBinDeployment()
|
||||
|
||||
host := "echo"
|
||||
host := echoHost
|
||||
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
|
@ -102,14 +103,16 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
|
|||
return strings.Contains(server, "grpc_pass grpc://upstream_balancer;")
|
||||
})
|
||||
|
||||
conn, _ := grpc.Dial(f.GetNginxIP()+":443",
|
||||
//nolint:goconst //string interpolation
|
||||
conn, err := grpc.Dial(f.GetNginxIP()+":443",
|
||||
grpc.WithTransportCredentials(
|
||||
credentials.NewTLS(&tls.Config{
|
||||
ServerName: "echo",
|
||||
InsecureSkipVerify: true,
|
||||
ServerName: echoHost,
|
||||
InsecureSkipVerify: true, //nolint:gosec // Ignore certificate validation in testing
|
||||
}),
|
||||
),
|
||||
)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "error creating a connection")
|
||||
defer conn.Close()
|
||||
|
||||
client := pb.NewGRPCBinClient(conn)
|
||||
|
|
@ -125,7 +128,7 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
|
|||
|
||||
ginkgo.It("authorization metadata should be overwritten by external auth response headers", func() {
|
||||
f.NewGRPCBinDeployment()
|
||||
host := "echo"
|
||||
host := echoHost
|
||||
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
|
@ -162,14 +165,15 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
|
|||
return strings.Contains(server, "grpc_pass grpc://upstream_balancer;")
|
||||
})
|
||||
|
||||
conn, _ := grpc.Dial(f.GetNginxIP()+":443",
|
||||
conn, err := grpc.Dial(f.GetNginxIP()+":443",
|
||||
grpc.WithTransportCredentials(
|
||||
credentials.NewTLS(&tls.Config{
|
||||
ServerName: "echo",
|
||||
InsecureSkipVerify: true,
|
||||
ServerName: echoHost,
|
||||
InsecureSkipVerify: true, //nolint:gosec // Ignore certificate validation in testing
|
||||
}),
|
||||
),
|
||||
)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
defer conn.Close()
|
||||
|
||||
client := pb.NewGRPCBinClient(conn)
|
||||
|
|
@ -180,13 +184,22 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
|
|||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
|
||||
metadata := res.GetMetadata()
|
||||
assert.Equal(ginkgo.GinkgoT(), "foo", metadata["authorization"].Values[0])
|
||||
assert.Equal(ginkgo.GinkgoT(), fooHost, metadata["authorization"].Values[0])
|
||||
})
|
||||
|
||||
ginkgo.It("should return OK for service with backend protocol GRPCS", func() {
|
||||
f.NewGRPCBinDeployment()
|
||||
|
||||
host := "echo"
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := echoHost
|
||||
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
|
@ -226,14 +239,15 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
|
|||
return strings.Contains(server, "grpc_pass grpcs://upstream_balancer;")
|
||||
})
|
||||
|
||||
conn, _ := grpc.Dial(f.GetNginxIP()+":443",
|
||||
conn, err := grpc.Dial(f.GetNginxIP()+":443",
|
||||
grpc.WithTransportCredentials(
|
||||
credentials.NewTLS(&tls.Config{
|
||||
ServerName: "echo",
|
||||
InsecureSkipVerify: true,
|
||||
ServerName: echoHost,
|
||||
InsecureSkipVerify: true, //nolint:gosec // Ignore the gosec error in testing
|
||||
}),
|
||||
),
|
||||
)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
defer conn.Close()
|
||||
|
||||
client := pb.NewGRPCBinClient(conn)
|
||||
|
|
|
|||
|
|
@ -24,19 +24,19 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.DescribeAnnotation("whitelist-source-range", func() {
|
||||
f := framework.NewDefaultFramework("ipwhitelist")
|
||||
var _ = framework.DescribeAnnotation("allowlist-source-range", func() {
|
||||
f := framework.NewDefaultFramework("ipallowlist")
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
f.NewEchoDeployment()
|
||||
})
|
||||
|
||||
ginkgo.It("should set valid ip whitelist range", func() {
|
||||
host := "ipwhitelist.foo.com"
|
||||
ginkgo.It("should set valid ip allowlist range", func() {
|
||||
host := "ipallowlist.foo.com"
|
||||
nameSpace := f.Namespace
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/whitelist-source-range": "18.0.0.0/8, 56.0.0.0/8",
|
||||
"nginx.ingress.kubernetes.io/allowlist-source-range": "18.0.0.0/8, 56.0.0.0/8",
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, nameSpace, framework.EchoService, 80, annotations)
|
||||
|
|
@ -25,6 +25,17 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const (
|
||||
modSecurityFooHost = "modsecurity.foo.com"
|
||||
defaultSnippet = `SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts ABIJDEFHZ
|
||||
SecAuditLog /dev/stdout
|
||||
SecAuditLogType Serial
|
||||
SecRule REQUEST_HEADERS:User-Agent \"block-ua\" \"log,deny,id:107,status:403,msg:\'UA blocked\'\"`
|
||||
)
|
||||
|
||||
var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
||||
f := framework.NewDefaultFramework("modsecuritylocation")
|
||||
|
||||
|
|
@ -33,7 +44,7 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
annotations := map[string]string{
|
||||
|
|
@ -51,7 +62,7 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity with transaction ID and OWASP rules", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
annotations := map[string]string{
|
||||
|
|
@ -72,7 +83,7 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should disable modsecurity", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
annotations := map[string]string{
|
||||
|
|
@ -89,7 +100,16 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity with snippet", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
annotations := map[string]string{
|
||||
|
|
@ -109,10 +129,11 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
|
||||
ginkgo.It("should enable modsecurity without using 'modsecurity on;'", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"enable-modsecurity": "true"},
|
||||
"enable-modsecurity": "true",
|
||||
},
|
||||
)
|
||||
|
||||
host := "modsecurity.foo.com"
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
annotations := map[string]string{
|
||||
|
|
@ -131,10 +152,11 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
|
||||
ginkgo.It("should disable modsecurity using 'modsecurity off;'", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"enable-modsecurity": "true"},
|
||||
"enable-modsecurity": "true",
|
||||
},
|
||||
)
|
||||
|
||||
host := "modsecurity.foo.com"
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
annotations := map[string]string{
|
||||
|
|
@ -151,16 +173,19 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity with snippet and block requests", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
snippet := `SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts ABIJDEFHZ
|
||||
SecAuditLog /dev/stdout
|
||||
SecAuditLogType Serial
|
||||
SecRule REQUEST_HEADERS:User-Agent \"block-ua\" \"log,deny,id:107,status:403,msg:\'UA blocked\'\"`
|
||||
snippet := defaultSnippet
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/enable-modsecurity": "true",
|
||||
|
|
@ -187,16 +212,19 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity globally and with modsecurity-snippet block requests", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
snippet := `SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts ABIJDEFHZ
|
||||
SecAuditLog /dev/stdout
|
||||
SecAuditLogType Serial
|
||||
SecRule REQUEST_HEADERS:User-Agent \"block-ua\" \"log,deny,id:107,status:403,msg:\'UA blocked\'\"`
|
||||
snippet := defaultSnippet
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/modsecurity-snippet": snippet,
|
||||
|
|
@ -223,16 +251,21 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity when enable-owasp-modsecurity-crs is set to true", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
"enable-modsecurity": "true",
|
||||
"enable-owasp-modsecurity-crs": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
snippet := `SecRuleEngine On
|
||||
SecRequestBodyAccess On
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts ABIJDEFHZ
|
||||
SecAuditLog /dev/stdout
|
||||
SecAuditLogType Serial
|
||||
SecRule REQUEST_HEADERS:User-Agent \"block-ua\" \"log,deny,id:107,status:403,msg:\'UA blocked\'\"`
|
||||
snippet := defaultSnippet
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/modsecurity-snippet": snippet,
|
||||
|
|
@ -243,11 +276,6 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
ing := framework.NewSingleIngress(host, "/", host, nameSpace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"enable-modsecurity": "true",
|
||||
"enable-owasp-modsecurity-crs": "true",
|
||||
})
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "SecRuleEngine On")
|
||||
|
|
@ -262,7 +290,7 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity through the config map", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
snippet := `SecRequestBodyAccess On
|
||||
|
|
@ -282,12 +310,17 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
f.EnsureIngress(ing)
|
||||
|
||||
expectedComment := "SecRuleEngine On"
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
"enable-modsecurity": "true",
|
||||
"enable-owasp-modsecurity-crs": "true",
|
||||
"modsecurity-snippet": expectedComment,
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
|
|
@ -303,7 +336,7 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity through the config map but ignore snippet as disabled by admin", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
snippet := `SecRequestBodyAccess On
|
||||
|
|
@ -345,7 +378,15 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should disable default modsecurity conf setting when modsecurity-snippet is specified", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
snippet := `SecRuleEngine On
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const proxyRedirectToHost = "goodbye.com"
|
||||
|
||||
var _ = framework.DescribeAnnotation("proxy-*", func() {
|
||||
f := framework.NewDefaultFramework("proxy")
|
||||
host := "proxy.foo.com"
|
||||
|
|
@ -38,7 +40,7 @@ var _ = framework.DescribeAnnotation("proxy-*", func() {
|
|||
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-redirect-from"] = proxyRedirectFrom
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-redirect-to"] = "goodbye.com"
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-redirect-to"] = proxyRedirectToHost
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -54,7 +56,7 @@ var _ = framework.DescribeAnnotation("proxy-*", func() {
|
|||
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-redirect-from"] = proxyRedirectFrom
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-redirect-to"] = "goodbye.com"
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-redirect-to"] = proxyRedirectToHost
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -67,7 +69,7 @@ var _ = framework.DescribeAnnotation("proxy-*", func() {
|
|||
|
||||
ginkgo.It("should set proxy_redirect to hello.com goodbye.com", func() {
|
||||
proxyRedirectFrom := "hello.com"
|
||||
proxyRedirectTo := "goodbye.com"
|
||||
proxyRedirectTo := proxyRedirectToHost
|
||||
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-redirect-from"] = proxyRedirectFrom
|
||||
|
|
@ -244,5 +246,4 @@ var _ = framework.DescribeAnnotation("proxy-*", func() {
|
|||
return strings.Contains(server, fmt.Sprintf("proxy_http_version %s;", proxyHTTPVersion))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const proxySSLHost = "proxyssl.foo.com"
|
||||
|
||||
var _ = framework.DescribeAnnotation("proxy-ssl-*", func() {
|
||||
f := framework.NewDefaultFramework("proxyssl")
|
||||
|
||||
|
|
@ -35,7 +37,7 @@ var _ = framework.DescribeAnnotation("proxy-ssl-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set valid proxy-ssl-secret", func() {
|
||||
host := "proxyssl.foo.com"
|
||||
host := proxySSLHost
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-ssl-secret"] = f.Namespace + "/" + host
|
||||
|
||||
|
|
@ -62,7 +64,7 @@ var _ = framework.DescribeAnnotation("proxy-ssl-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should set valid proxy-ssl-secret, proxy-ssl-verify to on, proxy-ssl-verify-depth to 2, and proxy-ssl-server-name to on", func() {
|
||||
host := "proxyssl.foo.com"
|
||||
host := proxySSLHost
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-ssl-secret"] = f.Namespace + "/" + host
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-ssl-verify"] = "on"
|
||||
|
|
@ -90,9 +92,9 @@ var _ = framework.DescribeAnnotation("proxy-ssl-*", func() {
|
|||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
ginkgo.It("should set valid proxy-ssl-secret, proxy-ssl-ciphers to HIGH:!AES", func() {
|
||||
host := "proxyssl.foo.com"
|
||||
host := proxySSLHost
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-ssl-secret"] = f.Namespace + "/" + host
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-ssl-ciphers"] = "HIGH:!AES"
|
||||
|
|
@ -118,9 +120,9 @@ var _ = framework.DescribeAnnotation("proxy-ssl-*", func() {
|
|||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
ginkgo.It("should set valid proxy-ssl-secret, proxy-ssl-protocols", func() {
|
||||
host := "proxyssl.foo.com"
|
||||
host := proxySSLHost
|
||||
annotations := make(map[string]string)
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-ssl-secret"] = f.Namespace + "/" + host
|
||||
annotations["nginx.ingress.kubernetes.io/proxy-ssl-protocols"] = "TLSv1.2 TLSv1.3"
|
||||
|
|
@ -195,7 +197,6 @@ var _ = framework.DescribeAnnotation("proxy-ssl-*", func() {
|
|||
strings.Contains(server, "proxy_ssl_certificate_key"))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
func assertProxySSL(f *framework.Framework, host, sslName, ciphers, protocols, verify string, depth int, proxySSLServerName string) {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const rewriteHost = "rewrite.bar.com"
|
||||
|
||||
var _ = framework.DescribeAnnotation("rewrite-target use-regex enable-rewrite-log", func() {
|
||||
f := framework.NewDefaultFramework("rewrite")
|
||||
|
||||
|
|
@ -37,7 +39,7 @@ var _ = framework.DescribeAnnotation("rewrite-target use-regex enable-rewrite-lo
|
|||
ginkgo.It("should write rewrite logs", func() {
|
||||
ginkgo.By("setting enable-rewrite-log annotation")
|
||||
|
||||
host := "rewrite.bar.com"
|
||||
host := rewriteHost
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/rewrite-target": "/",
|
||||
"nginx.ingress.kubernetes.io/enable-rewrite-log": "true",
|
||||
|
|
@ -64,7 +66,7 @@ var _ = framework.DescribeAnnotation("rewrite-target use-regex enable-rewrite-lo
|
|||
})
|
||||
|
||||
ginkgo.It("should use correct longest path match", func() {
|
||||
host := "rewrite.bar.com"
|
||||
host := rewriteHost
|
||||
|
||||
ginkgo.By("creating a regular ingress definition")
|
||||
ing := framework.NewSingleIngress("kube-lego", "/.well-known/acme/challenge", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
|
|
@ -109,10 +111,10 @@ var _ = framework.DescribeAnnotation("rewrite-target use-regex enable-rewrite-lo
|
|||
})
|
||||
|
||||
ginkgo.It("should use ~* location modifier if regex annotation is present", func() {
|
||||
host := "rewrite.bar.com"
|
||||
host := rewriteHost
|
||||
|
||||
ginkgo.By("creating a regular ingress definition")
|
||||
ing := framework.NewSingleIngress("foo", "/foo", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
ing := framework.NewSingleIngress(fooHost, "/foo", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
|
|
@ -156,10 +158,10 @@ var _ = framework.DescribeAnnotation("rewrite-target use-regex enable-rewrite-lo
|
|||
})
|
||||
|
||||
ginkgo.It("should fail to use longest match for documented warning", func() {
|
||||
host := "rewrite.bar.com"
|
||||
host := rewriteHost
|
||||
|
||||
ginkgo.By("creating a regular ingress definition")
|
||||
ing := framework.NewSingleIngress("foo", "/foo/bar/bar", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
ing := framework.NewSingleIngress(fooHost, "/foo/bar/bar", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
ginkgo.By(`creating an ingress definition with the use-regex annotation`)
|
||||
|
|
@ -188,7 +190,7 @@ var _ = framework.DescribeAnnotation("rewrite-target use-regex enable-rewrite-lo
|
|||
})
|
||||
|
||||
ginkgo.It("should allow for custom rewrite parameters", func() {
|
||||
host := "rewrite.bar.com"
|
||||
host := rewriteHost
|
||||
|
||||
ginkgo.By(`creating an ingress definition with the use-regex annotation`)
|
||||
annotations := map[string]string{
|
||||
|
|
|
|||
|
|
@ -33,6 +33,15 @@ var _ = framework.DescribeAnnotation("server-snippet", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`add valid directives to server via server snippet`, func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := "serversnippet.foo.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/server-snippet": `
|
||||
|
|
@ -59,6 +68,15 @@ var _ = framework.DescribeAnnotation("server-snippet", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`drops server snippet if disabled by the administrator`, func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := "noserversnippet.foo.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/server-snippet": `
|
||||
|
|
@ -89,6 +107,5 @@ var _ = framework.DescribeAnnotation("server-snippet", func() {
|
|||
Status(http.StatusOK).Headers().
|
||||
NotContainsKey("Foo").
|
||||
NotContainsKey("Xpto")
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/nginx"
|
||||
)
|
||||
|
||||
const dbgCmd = "/dbg backends all"
|
||||
|
||||
var _ = framework.DescribeAnnotation("service-upstream", func() {
|
||||
f := framework.NewDefaultFramework("serviceupstream")
|
||||
host := "serviceupstream"
|
||||
|
|
@ -59,10 +59,9 @@ var _ = framework.DescribeAnnotation("service-upstream", func() {
|
|||
|
||||
ginkgo.By("checking if the Service Cluster IP and Port are used")
|
||||
s := f.GetService(f.Namespace, framework.EchoService)
|
||||
curlCmd := fmt.Sprintf("curl --fail --silent http://localhost:%v/configuration/backends", nginx.StatusPort)
|
||||
output, err := f.ExecIngressPod(curlCmd)
|
||||
output, err := f.ExecIngressPod(dbgCmd)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
assert.Contains(ginkgo.GinkgoT(), output, fmt.Sprintf(`{"address":"%s"`, s.Spec.ClusterIP))
|
||||
assert.Contains(ginkgo.GinkgoT(), output, fmt.Sprintf(`"address": %q`, s.Spec.ClusterIP))
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -88,10 +87,9 @@ var _ = framework.DescribeAnnotation("service-upstream", func() {
|
|||
|
||||
ginkgo.By("checking if the Service Cluster IP and Port are used")
|
||||
s := f.GetService(f.Namespace, framework.EchoService)
|
||||
curlCmd := fmt.Sprintf("curl --fail --silent http://localhost:%v/configuration/backends", nginx.StatusPort)
|
||||
output, err := f.ExecIngressPod(curlCmd)
|
||||
output, err := f.ExecIngressPod(dbgCmd)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
assert.Contains(ginkgo.GinkgoT(), output, fmt.Sprintf(`{"address":"%s"`, s.Spec.ClusterIP))
|
||||
assert.Contains(ginkgo.GinkgoT(), output, fmt.Sprintf(`"address": %q`, s.Spec.ClusterIP))
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -119,10 +117,9 @@ var _ = framework.DescribeAnnotation("service-upstream", func() {
|
|||
|
||||
ginkgo.By("checking if the Service Cluster IP and Port are not used")
|
||||
s := f.GetService(f.Namespace, framework.EchoService)
|
||||
curlCmd := fmt.Sprintf("curl --fail --silent http://localhost:%v/configuration/backends", nginx.StatusPort)
|
||||
output, err := f.ExecIngressPod(curlCmd)
|
||||
output, err := f.ExecIngressPod(dbgCmd)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
assert.NotContains(ginkgo.GinkgoT(), output, fmt.Sprintf(`{"address":"%s"`, s.Spec.ClusterIP))
|
||||
assert.NotContains(ginkgo.GinkgoT(), output, fmt.Sprintf(`"address": %q`, s.Spec.ClusterIP))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -33,6 +33,16 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() {
|
|||
|
||||
ginkgo.It("set snippet more_set_headers in all locations", func() {
|
||||
host := "configurationsnippet.foo.com"
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Foo1: Bar1";`,
|
||||
}
|
||||
|
|
@ -76,10 +86,6 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() {
|
|||
annotations)
|
||||
|
||||
f.UpdateNginxConfigMapData("allow-snippet-annotations", "false")
|
||||
defer func() {
|
||||
// Return to the original value
|
||||
f.UpdateNginxConfigMapData("allow-snippet-annotations", "true")
|
||||
}()
|
||||
|
||||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
|
|
|
|||
|
|
@ -54,4 +54,27 @@ var _ = framework.DescribeAnnotation("ssl-ciphers", func() {
|
|||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
|
||||
ginkgo.It("should keep ssl ciphers", func() {
|
||||
host := "ciphers.foo.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/ssl-ciphers": "ALL:!aNULL:!EXPORT56:RC4+RSA@STRENGTH:+HIGH@SECLEVEL=0:+MEDIUM:+LOW:+SSLv2:+EXP",
|
||||
"nginx.ingress.kubernetes.io/ssl-prefer-server-ciphers": "true",
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/something", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA@STRENGTH:+HIGH@SECLEVEL=0:+MEDIUM:+LOW:+SSLv2:+EXP;") &&
|
||||
strings.Contains(server, "ssl_prefer_server_ciphers on;")
|
||||
})
|
||||
f.HTTPTestClient().
|
||||
GET("/something").
|
||||
WithURL(f.GetURL(framework.HTTPS)).
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -39,6 +39,15 @@ var _ = framework.DescribeSetting("stream-snippet", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should add value of stream-snippet to nginx config", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := "foo.com"
|
||||
|
||||
snippet := `server {listen 8000; proxy_pass 127.0.0.1:80;}`
|
||||
|
|
|
|||
|
|
@ -39,12 +39,13 @@ func startIngress(f *framework.Framework, annotations map[string]string) map[str
|
|||
return strings.Contains(server, fmt.Sprintf("server_name %s ;", host))
|
||||
})
|
||||
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
err := wait.Poll(framework.Poll, framework.DefaultTimeout, func() (bool, error) {
|
||||
|
||||
resp := f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().Raw()
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
return true, nil
|
||||
|
|
@ -55,7 +56,9 @@ func startIngress(f *framework.Framework, annotations map[string]string) map[str
|
|||
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
|
||||
re, _ := regexp.Compile(fmt.Sprintf(`Hostname: %v.*`, framework.EchoService))
|
||||
re, err := regexp.Compile(fmt.Sprintf(`Hostname: %v.*`, framework.EchoService))
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "error compiling regex")
|
||||
|
||||
podMap := map[string]bool{}
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ var _ = framework.IngressNginxDescribe("Debug CLI", func() {
|
|||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
|
||||
// Should be 2: the default and the echo deployment
|
||||
numUpstreams := len(strings.Split(strings.Trim(string(output), "\n"), "\n"))
|
||||
numUpstreams := len(strings.Split(strings.Trim(output, "\n"), "\n"))
|
||||
assert.Equal(ginkgo.GinkgoT(), numUpstreams, 2)
|
||||
})
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ var _ = framework.IngressNginxDescribe("Debug CLI", func() {
|
|||
output, err := f.ExecIngressPod(cmd)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
|
||||
backends := strings.Split(string(output), "\n")
|
||||
backends := strings.Split(output, "\n")
|
||||
assert.Greater(ginkgo.GinkgoT(), len(backends), 0)
|
||||
|
||||
getCmd := "/dbg backends get " + backends[0]
|
||||
|
|
|
|||
|
|
@ -49,15 +49,15 @@ var _ = framework.IngressNginxDescribe("[Default Backend]", func() {
|
|||
{"basic HTTPS POST request without host to path / should return 404", "", framework.HTTPS, "POST", "/", http.StatusNotFound},
|
||||
{"basic HTTPS POST request without host to path /demo should return 404", "", framework.HTTPS, "POST", "/demo", http.StatusNotFound},
|
||||
|
||||
{"basic HTTP GET request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTP, "GET", "/", http.StatusNotFound},
|
||||
{"basic HTTP GET request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTP, "GET", "/demo", http.StatusNotFound},
|
||||
{"basic HTTPS GET request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTPS, "GET", "/", http.StatusNotFound},
|
||||
{"basic HTTPS GET request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTPS, "GET", "/demo", http.StatusNotFound},
|
||||
{"basic HTTP GET request to host foo.bar.com and path / should return 404", "foo.bar.com", framework.HTTP, "GET", "/", http.StatusNotFound},
|
||||
{"basic HTTP GET request to host foo.bar.com and path /demo should return 404", "foo.bar.com", framework.HTTP, "GET", "/demo", http.StatusNotFound},
|
||||
{"basic HTTPS GET request to host foo.bar.com and path / should return 404", "foo.bar.com", framework.HTTPS, "GET", "/", http.StatusNotFound},
|
||||
{"basic HTTPS GET request to host foo.bar.com and path /demo should return 404", "foo.bar.com", framework.HTTPS, "GET", "/demo", http.StatusNotFound},
|
||||
|
||||
{"basic HTTP POST request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTP, "POST", "/", http.StatusNotFound},
|
||||
{"basic HTTP POST request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTP, "POST", "/demo", http.StatusNotFound},
|
||||
{"basic HTTPS POST request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTPS, "POST", "/", http.StatusNotFound},
|
||||
{"basic HTTPS POST request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTPS, "POST", "/demo", http.StatusNotFound},
|
||||
{"basic HTTP POST request to host foo.bar.com and path / should return 404", "foo.bar.com", framework.HTTP, "POST", "/", http.StatusNotFound},
|
||||
{"basic HTTP POST request to host foo.bar.com and path /demo should return 404", "foo.bar.com", framework.HTTP, "POST", "/demo", http.StatusNotFound},
|
||||
{"basic HTTPS POST request to host foo.bar.com and path / should return 404", "foo.bar.com", framework.HTTPS, "POST", "/", http.StatusNotFound},
|
||||
{"basic HTTPS POST request to host foo.bar.com and path /demo should return 404", "foo.bar.com", framework.HTTPS, "POST", "/demo", http.StatusNotFound},
|
||||
}
|
||||
|
||||
framework.Sleep()
|
||||
|
|
|
|||
93
test/e2e/disableleaderelection/disable_leader.go
Normal file
93
test/e2e/disableleaderelection/disable_leader.go
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Copyright 2024 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package disableleaderelection
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("[Disable Leader] Routing works when leader election was disabled", func() {
|
||||
f := framework.NewDefaultFramework("disableleaderelection")
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
f.NewEchoDeployment()
|
||||
})
|
||||
|
||||
ginkgo.It("should create multiple ingress routings rules when leader election has disabled", func() {
|
||||
host1 := "leader.election.disabled.com"
|
||||
host2 := "leader.election.disabled2.com"
|
||||
|
||||
ing1 := framework.NewSingleIngress(host1, "/foo", host1, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing1)
|
||||
|
||||
ing2 := framework.NewSingleIngress(host2, "/ping", host2, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing2)
|
||||
|
||||
f.WaitForNginxServer(host1,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, host1) &&
|
||||
strings.Contains(server, "location /foo")
|
||||
})
|
||||
|
||||
f.WaitForNginxServer(host2,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, host2) &&
|
||||
strings.Contains(server, "location /ping")
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/foo").
|
||||
WithHeader("Host", host1).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/bar").
|
||||
WithHeader("Host", host1).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/foo").
|
||||
WithHeader("Host", host2).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/ping").
|
||||
WithHeader("Host", host2).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/pong").
|
||||
WithHeader("Host", host2).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/ping").
|
||||
WithHeader("Host", host1).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
|
@ -35,6 +35,7 @@ import (
|
|||
_ "k8s.io/ingress-nginx/test/e2e/cgroups"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/dbg"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/defaultbackend"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/disableleaderelection"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/endpointslices"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/gracefulshutdown"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/ingress"
|
||||
|
|
@ -48,6 +49,7 @@ import (
|
|||
_ "k8s.io/ingress-nginx/test/e2e/settings"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/settings/modsecurity"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/settings/ocsp"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/settings/validations"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/ssl"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/status"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/tcpudp"
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ func init() {
|
|||
testing.Init()
|
||||
framework.RegisterParseFlags()
|
||||
}
|
||||
|
||||
func TestE2E(t *testing.T) {
|
||||
RunE2ETests(t)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ var _ = framework.IngressNginxDescribe("[Endpointslices] long service name", fun
|
|||
})
|
||||
|
||||
ginkgo.It("should return 200 when service name has max allowed number of characters 63", func() {
|
||||
|
||||
annotations := make(map[string]string)
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, name, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import (
|
|||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/nginx"
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
|
|
@ -41,7 +40,6 @@ var _ = framework.IngressNginxDescribeSerial("[TopologyHints] topology aware rou
|
|||
})
|
||||
|
||||
ginkgo.It("should return 200 when service has topology hints", func() {
|
||||
|
||||
annotations := make(map[string]string)
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -72,8 +70,8 @@ var _ = framework.IngressNginxDescribeSerial("[TopologyHints] topology aware rou
|
|||
}
|
||||
}
|
||||
|
||||
curlCmd := fmt.Sprintf("curl --fail --silent http://localhost:%v/configuration/backends", nginx.StatusPort)
|
||||
status, err := f.ExecIngressPod(curlCmd)
|
||||
dbgCmd := "/dbg backends all"
|
||||
status, err := f.ExecIngressPod(dbgCmd)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
var backends []map[string]interface{}
|
||||
err = json.Unmarshal([]byte(status), &backends)
|
||||
|
|
@ -86,7 +84,7 @@ var _ = framework.IngressNginxDescribeSerial("[TopologyHints] topology aware rou
|
|||
}
|
||||
|
||||
if gotHints {
|
||||
//we have 2 replics, if there is just one backend it means that we are routing according slices hints to same zone as controller is
|
||||
// we have 2 replics, if there is just one backend it means that we are routing according slices hints to same zone as controller is
|
||||
assert.Equal(ginkgo.GinkgoT(), 1, gotBackends)
|
||||
} else {
|
||||
// two replicas should have two endpoints without topology hints
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@ const NIPService = "external-nip"
|
|||
var HTTPBunImage = os.Getenv("HTTPBUN_IMAGE")
|
||||
|
||||
// EchoImage is the default image to be used by the echo service
|
||||
const EchoImage = "registry.k8s.io/ingress-nginx/e2e-test-echo@sha256:4938d1d91a2b7d19454460a8c1b010b89f6ff92d2987fd889ac3e8fc3b70d91a"
|
||||
const EchoImage = "registry.k8s.io/ingress-nginx/e2e-test-echo@sha256:4938d1d91a2b7d19454460a8c1b010b89f6ff92d2987fd889ac3e8fc3b70d91a" //#nosec G101
|
||||
|
||||
// TODO: change all Deployment functions to use these options
|
||||
// in order to reduce complexity and have a unified API accross the
|
||||
// in order to reduce complexity and have a unified API across the
|
||||
// framework
|
||||
type deploymentOptions struct {
|
||||
name string
|
||||
|
|
@ -67,11 +67,11 @@ func WithDeploymentNamespace(n string) func(*deploymentOptions) {
|
|||
}
|
||||
}
|
||||
|
||||
// WithSvcTopologyAnnotations create svc with topology aware hints sets to auto
|
||||
// WithSvcTopologyAnnotations create svc with topology mode sets to auto
|
||||
func WithSvcTopologyAnnotations() func(*deploymentOptions) {
|
||||
return func(o *deploymentOptions) {
|
||||
o.svcAnnotations = map[string]string{
|
||||
"service.kubernetes.io/topology-aware-hints": "auto",
|
||||
corev1.AnnotationTopologyMode: "auto",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@ func (f *Framework) NewHttpbunDeployment(opts ...func(*deploymentOptions)) strin
|
|||
80,
|
||||
int32(options.replicas),
|
||||
nil, nil,
|
||||
//Required to get hostname information
|
||||
// Required to get hostname information
|
||||
[]corev1.EnvVar{
|
||||
{
|
||||
Name: "HTTPBUN_INFO_ENABLED",
|
||||
|
|
@ -317,7 +317,7 @@ func (f *Framework) GetNginxBaseImage() string {
|
|||
|
||||
// NGINXDeployment creates a new simple NGINX Deployment using NGINX base image
|
||||
// and passing the desired configuration
|
||||
func (f *Framework) NGINXDeployment(name string, cfg string, waitendpoint bool) {
|
||||
func (f *Framework) NGINXDeployment(name, cfg string, waitendpoint bool) {
|
||||
cfgMap := map[string]string{
|
||||
"nginx.conf": cfg,
|
||||
}
|
||||
|
|
@ -389,7 +389,7 @@ func (f *Framework) NGINXDeployment(name string, cfg string, waitendpoint bool)
|
|||
}
|
||||
|
||||
// NGINXWithConfigDeployment creates an NGINX deployment using a configmap containing the nginx.conf configuration
|
||||
func (f *Framework) NGINXWithConfigDeployment(name string, cfg string) {
|
||||
func (f *Framework) NGINXWithConfigDeployment(name, cfg string) {
|
||||
f.NGINXDeployment(name, cfg, true)
|
||||
}
|
||||
|
||||
|
|
@ -487,7 +487,8 @@ func (f *Framework) NewGRPCBinDeployment() {
|
|||
}
|
||||
|
||||
func newDeployment(name, namespace, image string, port int32, replicas int32, command []string, args []string, env []corev1.EnvVar,
|
||||
volumeMounts []corev1.VolumeMount, volumes []corev1.Volume, setProbe bool) *appsv1.Deployment {
|
||||
volumeMounts []corev1.VolumeMount, volumes []corev1.Volume, setProbe bool,
|
||||
) *appsv1.Deployment {
|
||||
probe := &corev1.Probe{
|
||||
InitialDelaySeconds: 2,
|
||||
PeriodSeconds: 1,
|
||||
|
|
@ -559,12 +560,12 @@ func newDeployment(name, namespace, image string, port int32, replicas int32, co
|
|||
return d
|
||||
}
|
||||
|
||||
func (f *Framework) NewDeployment(name, image string, port int32, replicas int32) {
|
||||
func (f *Framework) NewDeployment(name, image string, port, replicas int32) {
|
||||
f.NewDeploymentWithOpts(name, image, port, replicas, nil, nil, nil, nil, nil, true)
|
||||
}
|
||||
|
||||
// NewDeployment creates a new deployment in a particular namespace.
|
||||
func (f *Framework) NewDeploymentWithOpts(name, image string, port int32, replicas int32, command []string, args []string, env []corev1.EnvVar, volumeMounts []corev1.VolumeMount, volumes []corev1.Volume, setProbe bool) {
|
||||
func (f *Framework) NewDeploymentWithOpts(name, image string, port, replicas int32, command, args []string, env []corev1.EnvVar, volumeMounts []corev1.VolumeMount, volumes []corev1.Volume, setProbe bool) {
|
||||
deployment := newDeployment(name, f.Namespace, image, port, replicas, command, args, env, volumeMounts, volumes, setProbe)
|
||||
|
||||
f.EnsureDeployment(deployment)
|
||||
|
|
@ -606,7 +607,7 @@ func (f *Framework) DeleteDeployment(name string) error {
|
|||
})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "deleting deployment")
|
||||
|
||||
return waitForPodsDeleted(f.KubeClientSet, 2*time.Minute, f.Namespace, metav1.ListOptions{
|
||||
return waitForPodsDeleted(f.KubeClientSet, 2*time.Minute, f.Namespace, &metav1.ListOptions{
|
||||
LabelSelector: labelSelectorToString(d.Spec.Selector.MatchLabels),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ func (f *Framework) ExecCommand(pod *corev1.Pod, command string) (string, error)
|
|||
execErr bytes.Buffer
|
||||
)
|
||||
|
||||
//nolint:gosec // Ignore G204 error
|
||||
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("%v exec --namespace %s %s --container controller -- %s", KubectlPath, pod.Namespace, pod.Name, command))
|
||||
cmd.Stdout = &execOut
|
||||
cmd.Stderr = &execErr
|
||||
|
|
@ -73,7 +74,6 @@ func (f *Framework) ExecCommand(pod *corev1.Pod, command string) (string, error)
|
|||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not execute '%s %s': %v", cmd.Path, cmd.Args, err)
|
||||
|
||||
}
|
||||
|
||||
if execErr.Len() > 0 {
|
||||
|
|
@ -91,6 +91,7 @@ func (f *Framework) NamespaceContent() (string, error) {
|
|||
execErr bytes.Buffer
|
||||
)
|
||||
|
||||
//nolint:gosec // Ignore G204 error
|
||||
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("%v get pods,services,endpoints,deployments --namespace %s", KubectlPath, f.Namespace))
|
||||
cmd.Stdout = &execOut
|
||||
cmd.Stderr = &execErr
|
||||
|
|
@ -98,11 +99,10 @@ func (f *Framework) NamespaceContent() (string, error) {
|
|||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not execute '%s %s': %v", cmd.Path, cmd.Args, err)
|
||||
|
||||
}
|
||||
|
||||
eout := strings.TrimSpace(execErr.String())
|
||||
if len(eout) > 0 {
|
||||
if eout != "" {
|
||||
return "", fmt.Errorf("stderr: %v", eout)
|
||||
}
|
||||
|
||||
|
|
@ -110,13 +110,18 @@ func (f *Framework) NamespaceContent() (string, error) {
|
|||
}
|
||||
|
||||
// newIngressController deploys a new NGINX Ingress controller in a namespace
|
||||
func (f *Framework) newIngressController(namespace string, namespaceOverlay string) error {
|
||||
func (f *Framework) newIngressController(namespace, namespaceOverlay string) error {
|
||||
// Creates an nginx deployment
|
||||
isChroot, ok := os.LookupEnv("IS_CHROOT")
|
||||
if !ok {
|
||||
isChroot = "false"
|
||||
}
|
||||
cmd := exec.Command("./wait-for-nginx.sh", namespace, namespaceOverlay, isChroot)
|
||||
|
||||
enableAnnotationValidations, ok := os.LookupEnv("ENABLE_VALIDATIONS")
|
||||
if !ok {
|
||||
enableAnnotationValidations = "false"
|
||||
}
|
||||
cmd := exec.Command("./wait-for-nginx.sh", namespace, namespaceOverlay, isChroot, enableAnnotationValidations)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unexpected error waiting for ingress controller deployment: %v.\nLogs:\n%v", err, string(out))
|
||||
|
|
@ -125,12 +130,11 @@ func (f *Framework) newIngressController(namespace string, namespaceOverlay stri
|
|||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
proxyRegexp = regexp.MustCompile("Starting to serve on .*:([0-9]+)")
|
||||
)
|
||||
var proxyRegexp = regexp.MustCompile(`Starting to serve on .*:(\d+)`)
|
||||
|
||||
// KubectlProxy creates a proxy to kubernetes apiserver
|
||||
func (f *Framework) KubectlProxy(port int) (int, *exec.Cmd, error) {
|
||||
//nolint:gosec // Ignore G204 error
|
||||
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("%s proxy --accept-hosts=.* --address=0.0.0.0 --port=%d", KubectlPath, port))
|
||||
stdout, stderr, err := startCmdAndStreamOutput(cmd)
|
||||
if err != nil {
|
||||
|
|
@ -158,6 +162,7 @@ func (f *Framework) KubectlProxy(port int) (int, *exec.Cmd, error) {
|
|||
}
|
||||
|
||||
func (f *Framework) UninstallChart() error {
|
||||
//nolint:gosec //Ignore G204 error
|
||||
cmd := exec.Command("helm", "uninstall", "--namespace", f.Namespace, "nginx-ingress")
|
||||
_, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
package framework
|
||||
|
||||
import (
|
||||
|
|
@ -75,7 +76,7 @@ func (f *Framework) NewNewFastCGIHelloServerDeploymentWithReplicas(replicas int3
|
|||
|
||||
d := f.EnsureDeployment(deployment)
|
||||
|
||||
err := waitForPodsReady(f.KubeClientSet, DefaultTimeout, int(replicas), f.Namespace, metav1.ListOptions{
|
||||
err := waitForPodsReady(f.KubeClientSet, DefaultTimeout, int(replicas), f.Namespace, &metav1.ListOptions{
|
||||
LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(),
|
||||
})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "failed to wait for to become ready")
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework/httpexpect"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
ginkgotypes "github.com/onsi/ginkgo/v2/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
|
@ -49,10 +50,8 @@ const (
|
|||
HTTPS RequestScheme = "https"
|
||||
)
|
||||
|
||||
var (
|
||||
// KubectlPath defines the full path of the kubectl binary
|
||||
KubectlPath = "/usr/local/bin/kubectl"
|
||||
)
|
||||
// KubectlPath defines the full path of the kubectl binary
|
||||
var KubectlPath = "/usr/local/bin/kubectl"
|
||||
|
||||
// Framework supports common operations used by e2e tests; it will keep a client & a namespace for you.
|
||||
type Framework struct {
|
||||
|
|
@ -131,7 +130,6 @@ func (f *Framework) CreateEnvironment() {
|
|||
|
||||
f.KubeClientSet, err = kubernetes.NewForConfig(f.KubeConfig)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "creating a kubernetes client")
|
||||
|
||||
}
|
||||
|
||||
f.Namespace, err = CreateKubeNamespace(f.BaseName, f.KubeClientSet)
|
||||
|
|
@ -181,7 +179,7 @@ func (f *Framework) AfterEach() {
|
|||
assert.Nil(ginkgo.GinkgoT(), err, "deleting IngressClass")
|
||||
}(f.KubeClientSet, f.IngressClass)
|
||||
|
||||
if !ginkgo.CurrentSpecReport().Failed() {
|
||||
if !ginkgo.CurrentSpecReport().Failed() || ginkgo.CurrentSpecReport().State.Is(ginkgotypes.SpecStateInterrupted) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -250,9 +248,9 @@ func (f *Framework) GetNginxPodIP() string {
|
|||
}
|
||||
|
||||
// GetURL returns the URL should be used to make a request to NGINX
|
||||
func (f *Framework) GetURL(scheme RequestScheme) string {
|
||||
func (f *Framework) GetURL(requestScheme RequestScheme) string {
|
||||
ip := f.GetNginxIP()
|
||||
return fmt.Sprintf("%v://%v", scheme, ip)
|
||||
return fmt.Sprintf("%v://%v", requestScheme, ip)
|
||||
}
|
||||
|
||||
// GetIngressNGINXPod returns the ingress controller running pod
|
||||
|
|
@ -270,6 +268,7 @@ func (f *Framework) updateIngressNGINXPod() error {
|
|||
// WaitForNginxServer waits until the nginx configuration contains a particular server section.
|
||||
// `cfg` passed to matcher is normalized by replacing all tabs and spaces with single space.
|
||||
func (f *Framework) WaitForNginxServer(name string, matcher func(cfg string) bool) {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
err := wait.Poll(Poll, DefaultTimeout, f.matchNginxConditions(name, matcher))
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "waiting for nginx server condition/s")
|
||||
Sleep(1 * time.Second)
|
||||
|
|
@ -278,13 +277,15 @@ func (f *Framework) WaitForNginxServer(name string, matcher func(cfg string) boo
|
|||
// WaitForNginxConfiguration waits until the nginx configuration contains a particular configuration
|
||||
// `cfg` passed to matcher is normalized by replacing all tabs and spaces with single space.
|
||||
func (f *Framework) WaitForNginxConfiguration(matcher func(cfg string) bool) {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
err := wait.Poll(Poll, DefaultTimeout, f.matchNginxConditions("", matcher))
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "waiting for nginx server condition/s")
|
||||
Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
// WaitForNginxCustomConfiguration waits until the nginx configuration given part (from, to) contains a particular configuration
|
||||
func (f *Framework) WaitForNginxCustomConfiguration(from string, to string, matcher func(cfg string) bool) {
|
||||
func (f *Framework) WaitForNginxCustomConfiguration(from, to string, matcher func(cfg string) bool) {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
err := wait.Poll(Poll, DefaultTimeout, f.matchNginxCustomConditions(from, to, matcher))
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "waiting for nginx server condition/s")
|
||||
}
|
||||
|
|
@ -312,7 +313,7 @@ func (f *Framework) matchNginxConditions(name string, matcher func(cfg string) b
|
|||
return false, nil
|
||||
}
|
||||
|
||||
if klog.V(10).Enabled() && len(o) > 0 {
|
||||
if klog.V(10).Enabled() && o != "" {
|
||||
klog.InfoS("NGINX", "configuration", o)
|
||||
}
|
||||
|
||||
|
|
@ -325,7 +326,7 @@ func (f *Framework) matchNginxConditions(name string, matcher func(cfg string) b
|
|||
}
|
||||
}
|
||||
|
||||
func (f *Framework) matchNginxCustomConditions(from string, to string, matcher func(cfg string) bool) wait.ConditionFunc {
|
||||
func (f *Framework) matchNginxCustomConditions(from, to string, matcher func(cfg string) bool) wait.ConditionFunc {
|
||||
return func() (bool, error) {
|
||||
cmd := fmt.Sprintf("cat /etc/nginx/nginx.conf| awk '/%v/,/%v/'", from, to)
|
||||
|
||||
|
|
@ -334,7 +335,7 @@ func (f *Framework) matchNginxCustomConditions(from string, to string, matcher f
|
|||
return false, nil
|
||||
}
|
||||
|
||||
if klog.V(10).Enabled() && len(o) > 0 {
|
||||
if klog.V(10).Enabled() && o != "" {
|
||||
klog.InfoS("NGINX", "configuration", o)
|
||||
}
|
||||
|
||||
|
|
@ -395,7 +396,7 @@ func (f *Framework) CreateConfigMap(name string, data map[string]string) {
|
|||
}
|
||||
|
||||
// UpdateNginxConfigMapData updates single field in ingress-nginx's nginx-ingress-controller map data
|
||||
func (f *Framework) UpdateNginxConfigMapData(key string, value string) {
|
||||
func (f *Framework) UpdateNginxConfigMapData(key, value string) {
|
||||
config, err := f.getConfigMap("nginx-ingress-controller")
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
assert.NotNil(ginkgo.GinkgoT(), config, "expected a configmap but none returned")
|
||||
|
|
@ -421,6 +422,7 @@ func (f *Framework) WaitForReload(fn func()) {
|
|||
fn()
|
||||
|
||||
count := 0
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
err := wait.Poll(1*time.Second, DefaultTimeout, func() (bool, error) {
|
||||
reloads := getReloadCount(f.pod, f.Namespace, f.KubeClientSet)
|
||||
// most of the cases reload the ingress controller
|
||||
|
|
@ -441,8 +443,8 @@ func getReloadCount(pod *v1.Pod, namespace string, client kubernetes.Interface)
|
|||
assert.Nil(ginkgo.GinkgoT(), err, "obtaining NGINX Pod")
|
||||
|
||||
reloadCount := 0
|
||||
for _, e := range events.Items {
|
||||
if e.Reason == "RELOAD" && e.Type == v1.EventTypeNormal {
|
||||
for i := range events.Items {
|
||||
if events.Items[i].Reason == "RELOAD" && events.Items[i].Type == v1.EventTypeNormal {
|
||||
reloadCount++
|
||||
}
|
||||
}
|
||||
|
|
@ -457,7 +459,7 @@ func (f *Framework) DeleteNGINXPod(grace int64) {
|
|||
|
||||
err := f.KubeClientSet.CoreV1().Pods(ns).Delete(context.TODO(), f.pod.GetName(), *metav1.NewDeleteOptions(grace))
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "deleting ingress nginx pod")
|
||||
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
err = wait.Poll(Poll, DefaultTimeout, func() (bool, error) {
|
||||
err := f.updateIngressNGINXPod()
|
||||
if err != nil || f.pod == nil {
|
||||
|
|
@ -487,7 +489,7 @@ func (f *Framework) HTTPTestClientWithTLSConfig(config *tls.Config) *httpexpect.
|
|||
func (f *Framework) newHTTPTestClient(config *tls.Config, setIngressURL bool) *httpexpect.HTTPRequest {
|
||||
if config == nil {
|
||||
config = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
InsecureSkipVerify: true, //nolint:gosec // Ignore the gosec error in testing
|
||||
}
|
||||
}
|
||||
var baseURL string
|
||||
|
|
@ -499,7 +501,7 @@ func (f *Framework) newHTTPTestClient(config *tls.Config, setIngressURL bool) *h
|
|||
Transport: &http.Transport{
|
||||
TLSClientConfig: config,
|
||||
},
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
CheckRedirect: func(_ *http.Request, _ []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}, httpexpect.NewAssertReporter())
|
||||
|
|
@ -507,12 +509,13 @@ func (f *Framework) newHTTPTestClient(config *tls.Config, setIngressURL bool) *h
|
|||
|
||||
// WaitForNginxListening waits until NGINX starts accepting connections on a port
|
||||
func (f *Framework) WaitForNginxListening(port int) {
|
||||
err := waitForPodsReady(f.KubeClientSet, DefaultTimeout, 1, f.Namespace, metav1.ListOptions{
|
||||
err := waitForPodsReady(f.KubeClientSet, DefaultTimeout, 1, f.Namespace, &metav1.ListOptions{
|
||||
LabelSelector: "app.kubernetes.io/name=ingress-nginx",
|
||||
})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "waiting for ingress pods to be ready")
|
||||
|
||||
podIP := f.GetNginxIP()
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
err = wait.Poll(500*time.Millisecond, DefaultTimeout, func() (bool, error) {
|
||||
hostPort := net.JoinHostPort(podIP, fmt.Sprintf("%v", port))
|
||||
conn, err := net.Dial("tcp", hostPort)
|
||||
|
|
@ -529,7 +532,7 @@ func (f *Framework) WaitForNginxListening(port int) {
|
|||
|
||||
// WaitForPod waits for a specific Pod to be ready, using a label selector
|
||||
func (f *Framework) WaitForPod(selector string, timeout time.Duration, shouldFail bool) {
|
||||
err := waitForPodsReady(f.KubeClientSet, timeout, 1, f.Namespace, metav1.ListOptions{
|
||||
err := waitForPodsReady(f.KubeClientSet, timeout, 1, f.Namespace, &metav1.ListOptions{
|
||||
LabelSelector: selector,
|
||||
})
|
||||
|
||||
|
|
@ -541,7 +544,7 @@ func (f *Framework) WaitForPod(selector string, timeout time.Duration, shouldFai
|
|||
}
|
||||
|
||||
// UpdateDeployment runs the given updateFunc on the deployment and waits for it to be updated
|
||||
func UpdateDeployment(kubeClientSet kubernetes.Interface, namespace string, name string, replicas int, updateFunc func(d *appsv1.Deployment) error) error {
|
||||
func UpdateDeployment(kubeClientSet kubernetes.Interface, namespace, name string, replicas int, updateFunc func(d *appsv1.Deployment) error) error {
|
||||
deployment, err := kubeClientSet.AppsV1().Deployments(namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -571,7 +574,7 @@ func UpdateDeployment(kubeClientSet kubernetes.Interface, namespace string, name
|
|||
}
|
||||
}
|
||||
|
||||
err = waitForPodsReady(kubeClientSet, DefaultTimeout, replicas, namespace, metav1.ListOptions{
|
||||
err = waitForPodsReady(kubeClientSet, DefaultTimeout, replicas, namespace, &metav1.ListOptions{
|
||||
LabelSelector: fields.SelectorFromSet(fields.Set(deployment.Spec.Template.ObjectMeta.Labels)).String(),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
@ -582,6 +585,7 @@ func UpdateDeployment(kubeClientSet kubernetes.Interface, namespace string, name
|
|||
}
|
||||
|
||||
func waitForDeploymentRollout(kubeClientSet kubernetes.Interface, resource *appsv1.Deployment) error {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
return wait.Poll(Poll, 5*time.Minute, func() (bool, error) {
|
||||
d, err := kubeClientSet.AppsV1().Deployments(resource.Namespace).Get(context.TODO(), resource.Name, metav1.GetOptions{})
|
||||
if apierrors.IsNotFound(err) {
|
||||
|
|
@ -605,7 +609,7 @@ func waitForDeploymentRollout(kubeClientSet kubernetes.Interface, resource *apps
|
|||
}
|
||||
|
||||
// UpdateIngress runs the given updateFunc on the ingress
|
||||
func UpdateIngress(kubeClientSet kubernetes.Interface, namespace string, name string, updateFunc func(d *networking.Ingress) error) error {
|
||||
func UpdateIngress(kubeClientSet kubernetes.Interface, namespace, name string, updateFunc func(d *networking.Ingress) error) error {
|
||||
ingress, err := kubeClientSet.NetworkingV1().Ingresses(namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
package framework
|
||||
|
||||
import (
|
||||
|
|
@ -75,7 +76,7 @@ func (f *Framework) NewNewGRPCFortuneTellerDeploymentWithReplicas(replicas int32
|
|||
|
||||
d := f.EnsureDeployment(deployment)
|
||||
|
||||
err := waitForPodsReady(f.KubeClientSet, DefaultTimeout, int(replicas), f.Namespace, metav1.ListOptions{
|
||||
err := waitForPodsReady(f.KubeClientSet, DefaultTimeout, int(replicas), f.Namespace, &metav1.ListOptions{
|
||||
LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(),
|
||||
})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "failed to wait for to become ready")
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ func (f *Framework) VerifyHealthz(ip string, statusCode int) error {
|
|||
url := fmt.Sprintf("http://%v:10254/healthz", ip)
|
||||
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||
req, err := http.NewRequest(http.MethodGet, url, http.NoBody)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating GET request for URL %q failed: %v", url, err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ type Match struct {
|
|||
names map[string]int
|
||||
}
|
||||
|
||||
func makeMatch(chain chain, submatches []string, names []string) *Match {
|
||||
func makeMatch(chain chain, submatches, names []string) *Match {
|
||||
if submatches == nil {
|
||||
submatches = []string{}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ import (
|
|||
"github.com/yudai/gojsondiff/formatter"
|
||||
)
|
||||
|
||||
const unavailableMsg = " (unavailable)"
|
||||
|
||||
// Object provides methods to inspect attached map[string]interface{} object
|
||||
// (Go representation of JSON object).
|
||||
type Object struct {
|
||||
|
|
@ -81,20 +83,21 @@ func diffValues(expected, actual interface{}) string {
|
|||
|
||||
var diff gojsondiff.Diff
|
||||
|
||||
if ve, ok := expected.(map[string]interface{}); ok {
|
||||
switch ve := expected.(type) {
|
||||
case map[string]interface{}:
|
||||
if va, ok := actual.(map[string]interface{}); ok {
|
||||
diff = differ.CompareObjects(ve, va)
|
||||
} else {
|
||||
return " (unavailable)"
|
||||
return unavailableMsg
|
||||
}
|
||||
} else if ve, ok := expected.([]interface{}); ok {
|
||||
case []interface{}:
|
||||
if va, ok := actual.([]interface{}); ok {
|
||||
diff = differ.CompareArrays(ve, va)
|
||||
} else {
|
||||
return " (unavailable)"
|
||||
return unavailableMsg
|
||||
}
|
||||
} else {
|
||||
return " (unavailable)"
|
||||
default:
|
||||
return unavailableMsg
|
||||
}
|
||||
|
||||
config := formatter.AsciiFormatterConfig{
|
||||
|
|
@ -104,7 +107,7 @@ func diffValues(expected, actual interface{}) string {
|
|||
|
||||
str, err := f.Format(diff)
|
||||
if err != nil {
|
||||
return " (unavailable)"
|
||||
return unavailableMsg
|
||||
}
|
||||
|
||||
return "--- expected\n+++ actual\n" + str
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ func (h *HTTPRequest) DoRequest(method, rpath string) *HTTPRequest {
|
|||
|
||||
var request *http.Request
|
||||
uri.Path = path.Join(uri.Path, rpath)
|
||||
if request, err = http.NewRequest(method, uri.String(), nil); err != nil {
|
||||
if request, err = http.NewRequest(method, uri.String(), http.NoBody); err != nil {
|
||||
h.chain.fail(err.Error())
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ func (h *HTTPRequest) ForceResolve(ip string, port uint16) *HTTPRequest {
|
|||
return h
|
||||
}
|
||||
newTransport := oldTransport.Clone()
|
||||
newTransport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
newTransport.DialContext = func(ctx context.Context, network, _ string) (net.Conn, error) {
|
||||
return dialer.DialContext(ctx, network, resolveAddr)
|
||||
}
|
||||
h.client.Transport = newTransport
|
||||
|
|
@ -110,6 +110,7 @@ func (h *HTTPRequest) Expect() *HTTPResponse {
|
|||
if err != nil {
|
||||
h.chain.fail(err.Error())
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
h.HTTPResponse.Response = response // set the HTTP response
|
||||
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@ func (r *HTTPResponse) checkContentType(expectedType string, expectedCharset ...
|
|||
}
|
||||
|
||||
if mediaType != expectedType {
|
||||
//nolint:goconst //string interpolation
|
||||
r.chain.fail("\nexpected \"Content-Type\" header with %q media type,"+
|
||||
"\nbut got %q", expectedType, mediaType)
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ func (f *Framework) EnsureSecret(secret *core.Secret) *core.Secret {
|
|||
}
|
||||
|
||||
// GetConfigMap gets a ConfigMap object from the given namespace, name and returns it, throws error if it does not exist.
|
||||
func (f *Framework) GetConfigMap(namespace string, name string) *core.ConfigMap {
|
||||
func (f *Framework) GetConfigMap(namespace, name string) *core.ConfigMap {
|
||||
cm, err := f.KubeClientSet.CoreV1().ConfigMaps(namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "getting configmap")
|
||||
assert.NotNil(ginkgo.GinkgoT(), cm, "expected a configmap but none returned")
|
||||
|
|
@ -73,7 +73,7 @@ func (f *Framework) EnsureConfigMap(configMap *core.ConfigMap) *core.ConfigMap {
|
|||
}
|
||||
|
||||
// GetIngress gets an Ingress object from the given namespace, name and returns it, throws error if it does not exists.
|
||||
func (f *Framework) GetIngress(namespace string, name string) *networking.Ingress {
|
||||
func (f *Framework) GetIngress(namespace, name string) *networking.Ingress {
|
||||
ing, err := f.KubeClientSet.NetworkingV1().Ingresses(namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "getting ingress")
|
||||
assert.NotNil(ginkgo.GinkgoT(), ing, "expected an ingress but none returned")
|
||||
|
|
@ -114,7 +114,7 @@ func (f *Framework) UpdateIngress(ingress *networking.Ingress) *networking.Ingre
|
|||
}
|
||||
|
||||
// GetService gets a Service object from the given namespace, name and returns it, throws error if it does not exist.
|
||||
func (f *Framework) GetService(namespace string, name string) *core.Service {
|
||||
func (f *Framework) GetService(namespace, name string) *core.Service {
|
||||
s, err := f.KubeClientSet.CoreV1().Services(namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "getting service")
|
||||
assert.NotNil(ginkgo.GinkgoT(), s, "expected a service but none returned")
|
||||
|
|
@ -143,16 +143,21 @@ func (f *Framework) EnsureDeployment(deployment *appsv1.Deployment) *appsv1.Depl
|
|||
}
|
||||
|
||||
// waitForPodsReady waits for a given amount of time until a group of Pods is running in the given namespace.
|
||||
func waitForPodsReady(kubeClientSet kubernetes.Interface, timeout time.Duration, expectedReplicas int, namespace string, opts metav1.ListOptions) error {
|
||||
func waitForPodsReady(kubeClientSet kubernetes.Interface, timeout time.Duration, expectedReplicas int, namespace string, opts *metav1.ListOptions) error {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.PollImmediate is deprecated
|
||||
return wait.PollImmediate(1*time.Second, timeout, func() (bool, error) {
|
||||
pl, err := kubeClientSet.CoreV1().Pods(namespace).List(context.TODO(), opts)
|
||||
pl, err := kubeClientSet.CoreV1().Pods(namespace).List(context.TODO(), *opts)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
r := 0
|
||||
for _, p := range pl.Items {
|
||||
if isRunning, _ := podRunningReady(&p); isRunning {
|
||||
for i := range pl.Items {
|
||||
isRunning, err := podRunningReady(&pl.Items[i])
|
||||
if err != nil {
|
||||
Logf("error checking if pod is running : %v", err)
|
||||
}
|
||||
if isRunning {
|
||||
r++
|
||||
}
|
||||
}
|
||||
|
|
@ -166,9 +171,10 @@ func waitForPodsReady(kubeClientSet kubernetes.Interface, timeout time.Duration,
|
|||
}
|
||||
|
||||
// waitForPodsDeleted waits for a given amount of time until a group of Pods are deleted in the given namespace.
|
||||
func waitForPodsDeleted(kubeClientSet kubernetes.Interface, timeout time.Duration, namespace string, opts metav1.ListOptions) error {
|
||||
func waitForPodsDeleted(kubeClientSet kubernetes.Interface, timeout time.Duration, namespace string, opts *metav1.ListOptions) error {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
return wait.Poll(Poll, timeout, func() (bool, error) {
|
||||
pl, err := kubeClientSet.CoreV1().Pods(namespace).List(context.TODO(), opts)
|
||||
pl, err := kubeClientSet.CoreV1().Pods(namespace).List(context.TODO(), *opts)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
|
@ -186,7 +192,7 @@ func WaitForEndpoints(kubeClientSet kubernetes.Interface, timeout time.Duration,
|
|||
if expectedEndpoints == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
//nolint:staticcheck // TODO: will replace it since wait.PollImmediate is deprecated
|
||||
return wait.PollImmediate(Poll, timeout, func() (bool, error) {
|
||||
endpoint, err := kubeClientSet.CoreV1().Endpoints(ns).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if k8sErrors.IsNotFound(err) {
|
||||
|
|
@ -248,6 +254,7 @@ func isPodReady(p *core.Pod) bool {
|
|||
// getIngressNGINXPod returns the ingress controller running pod
|
||||
func getIngressNGINXPod(ns string, kubeClientSet kubernetes.Interface) (*core.Pod, error) {
|
||||
var pod *core.Pod
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
err := wait.Poll(1*time.Second, DefaultTimeout, func() (bool, error) {
|
||||
l, err := kubeClientSet.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{
|
||||
LabelSelector: "app.kubernetes.io/name=ingress-nginx",
|
||||
|
|
@ -256,15 +263,16 @@ func getIngressNGINXPod(ns string, kubeClientSet kubernetes.Interface) (*core.Po
|
|||
return false, nil
|
||||
}
|
||||
|
||||
for _, p := range l.Items {
|
||||
for i := range l.Items {
|
||||
p := &l.Items[i]
|
||||
if strings.HasPrefix(p.GetName(), "nginx-ingress-controller") {
|
||||
isRunning, err := podRunningReady(&p)
|
||||
isRunning, err := podRunningReady(p)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if isRunning {
|
||||
pod = &p
|
||||
pod = p
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
|
@ -273,6 +281,7 @@ func getIngressNGINXPod(ns string, kubeClientSet kubernetes.Interface) (*core.Po
|
|||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.ErrWaitTimeout is deprecated
|
||||
if err == wait.ErrWaitTimeout {
|
||||
return nil, fmt.Errorf("timeout waiting at least one ingress-nginx pod running in namespace %v", ns)
|
||||
}
|
||||
|
|
@ -285,7 +294,7 @@ func getIngressNGINXPod(ns string, kubeClientSet kubernetes.Interface) (*core.Po
|
|||
|
||||
func createDeploymentWithRetries(c kubernetes.Interface, namespace string, obj *appsv1.Deployment) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.AppsV1().Deployments(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
|
|
@ -298,7 +307,7 @@ func createDeploymentWithRetries(c kubernetes.Interface, namespace string, obj *
|
|||
if isRetryableAPIError(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
|
||||
return retryWithExponentialBackOff(createFunc)
|
||||
|
|
@ -306,7 +315,7 @@ func createDeploymentWithRetries(c kubernetes.Interface, namespace string, obj *
|
|||
|
||||
func createSecretWithRetries(c kubernetes.Interface, namespace string, obj *core.Secret) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.CoreV1().Secrets(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
|
|
@ -319,14 +328,14 @@ func createSecretWithRetries(c kubernetes.Interface, namespace string, obj *core
|
|||
if isRetryableAPIError(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
return retryWithExponentialBackOff(createFunc)
|
||||
}
|
||||
|
||||
func createServiceWithRetries(c kubernetes.Interface, namespace string, obj *core.Service) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.CoreV1().Services(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
|
|
@ -339,7 +348,7 @@ func createServiceWithRetries(c kubernetes.Interface, namespace string, obj *cor
|
|||
if isRetryableAPIError(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
|
||||
return retryWithExponentialBackOff(createFunc)
|
||||
|
|
@ -347,7 +356,7 @@ func createServiceWithRetries(c kubernetes.Interface, namespace string, obj *cor
|
|||
|
||||
func createIngressWithRetries(c kubernetes.Interface, namespace string, obj *networking.Ingress) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
createFunc := func() (bool, error) {
|
||||
_, err := c.NetworkingV1().Ingresses(namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
|
|
@ -360,7 +369,7 @@ func createIngressWithRetries(c kubernetes.Interface, namespace string, obj *net
|
|||
if isRetryableAPIError(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to create object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to create object with non-retriable error: %v", err)
|
||||
}
|
||||
|
||||
return retryWithExponentialBackOff(createFunc)
|
||||
|
|
@ -368,7 +377,7 @@ func createIngressWithRetries(c kubernetes.Interface, namespace string, obj *net
|
|||
|
||||
func updateIngressWithRetries(c kubernetes.Interface, namespace string, obj *networking.Ingress) error {
|
||||
if obj == nil {
|
||||
return fmt.Errorf("Object provided to create is empty")
|
||||
return fmt.Errorf("object provided to create is empty")
|
||||
}
|
||||
updateFunc := func() (bool, error) {
|
||||
_, err := c.NetworkingV1().Ingresses(namespace).Update(context.TODO(), obj, metav1.UpdateOptions{})
|
||||
|
|
@ -378,7 +387,7 @@ func updateIngressWithRetries(c kubernetes.Interface, namespace string, obj *net
|
|||
if isRetryableAPIError(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("Failed to update object with non-retriable error: %v", err)
|
||||
return false, fmt.Errorf("failed to update object with non-retriable error: %v", err)
|
||||
}
|
||||
|
||||
return retryWithExponentialBackOff(updateFunc)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ func (f *Framework) GetMetric(metricName, ip string) (*dto.MetricFamily, error)
|
|||
url := fmt.Sprintf("http://%v:10254/metrics", ip)
|
||||
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||
req, err := http.NewRequest(http.MethodGet, url, http.NoBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating GET request for URL %q failed: %v", url, err)
|
||||
}
|
||||
|
|
@ -44,7 +44,6 @@ func (f *Framework) GetMetric(metricName, ip string) (*dto.MetricFamily, error)
|
|||
|
||||
var parser expfmt.TextParser
|
||||
metrics, err := parser.TextToMetricFamilies(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading text format failed: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,8 +93,8 @@ func CreateIngressTLSSecret(client kubernetes.Interface, hosts []string, secretN
|
|||
// CreateIngressMASecret creates or updates a Secret containing a Mutual Auth
|
||||
// certificate-chain for the given Ingress and returns a TLS configuration suitable
|
||||
// for HTTP clients to use against that particular Ingress.
|
||||
func CreateIngressMASecret(client kubernetes.Interface, host string, secretName, namespace string) (*tls.Config, error) {
|
||||
if len(host) == 0 {
|
||||
func CreateIngressMASecret(client kubernetes.Interface, host, secretName, namespace string) (*tls.Config, error) {
|
||||
if host == "" {
|
||||
return nil, fmt.Errorf("requires a non-empty host")
|
||||
}
|
||||
|
||||
|
|
@ -138,12 +138,13 @@ func CreateIngressMASecret(client kubernetes.Interface, host string, secretName,
|
|||
return &tls.Config{
|
||||
ServerName: host,
|
||||
Certificates: []tls.Certificate{clientPair},
|
||||
InsecureSkipVerify: true,
|
||||
InsecureSkipVerify: true, //nolint:gosec // Ignore the gosec error in testing
|
||||
}, nil
|
||||
}
|
||||
|
||||
// WaitForTLS waits until the TLS handshake with a given server completes successfully.
|
||||
func WaitForTLS(url string, tlsConfig *tls.Config) {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
err := wait.Poll(Poll, DefaultTimeout, matchTLSServerName(url, tlsConfig))
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "waiting for TLS configuration in URL %s", url)
|
||||
}
|
||||
|
|
@ -160,7 +161,6 @@ func generateRSACert(host string, isCA bool, keyOut, certOut io.Writer) error {
|
|||
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate serial number: %s", err)
|
||||
}
|
||||
|
|
@ -329,7 +329,7 @@ func tlsConfig(serverName string, pemCA []byte) (*tls.Config, error) {
|
|||
if !rootCAPool.AppendCertsFromPEM(pemCA) {
|
||||
return nil, fmt.Errorf("error creating CA certificate pool (%s)", serverName)
|
||||
}
|
||||
return &tls.Config{
|
||||
return &tls.Config{ //nolint:gosec // Ignore the gosec error in testing
|
||||
ServerName: serverName,
|
||||
RootCAs: rootCAPool,
|
||||
}, nil
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import (
|
|||
// TestContextType describes the client context to use in communications with the Kubernetes API.
|
||||
type TestContextType struct {
|
||||
KubeHost string
|
||||
//KubeConfig string
|
||||
// KubeConfig string
|
||||
KubeContext string
|
||||
}
|
||||
|
||||
|
|
@ -33,7 +33,6 @@ var TestContext TestContextType
|
|||
// registerCommonFlags registers flags common to all e2e test suites.
|
||||
func registerCommonFlags() {
|
||||
flag.StringVar(&TestContext.KubeHost, "kubernetes-host", "http://127.0.0.1:8080", "The kubernetes host, or apiserver, to connect to")
|
||||
//flag.StringVar(&TestContext.KubeConfig, "kubernetes-config", os.Getenv(clientcmd.RecommendedConfigPathEnvVar), "Path to config containing embedded authinfo for kubernetes. Default value is from environment variable "+clientcmd.RecommendedConfigPathEnvVar)
|
||||
flag.StringVar(&TestContext.KubeContext, "kubernetes-context", "", "config context to use for kubernetes. If unset, will use value from 'current-context'")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,24 +49,24 @@ func nowStamp() string {
|
|||
return time.Now().Format(time.StampMilli)
|
||||
}
|
||||
|
||||
func log(level string, format string, args ...interface{}) {
|
||||
func logf(level, format string, args ...interface{}) {
|
||||
fmt.Fprintf(ginkgo.GinkgoWriter, nowStamp()+": "+level+": "+format+"\n", args...)
|
||||
}
|
||||
|
||||
// Logf logs to the INFO logs.
|
||||
func Logf(format string, args ...interface{}) {
|
||||
log("INFO", format, args...)
|
||||
logf("INFO", format, args...)
|
||||
}
|
||||
|
||||
// Failf logs to the INFO logs and fails the test.
|
||||
func Failf(format string, args ...interface{}) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
log("INFO", msg)
|
||||
logf("INFO", msg)
|
||||
ginkgo.Fail(nowStamp()+": "+msg, 1)
|
||||
}
|
||||
|
||||
// RestclientConfig deserializes the contents of a kubeconfig file into a Config object.
|
||||
func RestclientConfig(config, context string) (*api.Config, error) {
|
||||
func RestclientConfig(config, newContext string) (*api.Config, error) {
|
||||
Logf(">>> config: %s\n", config)
|
||||
if config == "" {
|
||||
return nil, fmt.Errorf("config file must be specified to load client config")
|
||||
|
|
@ -75,9 +75,9 @@ func RestclientConfig(config, context string) (*api.Config, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("error loading config: %v", err.Error())
|
||||
}
|
||||
if context != "" {
|
||||
Logf(">>> context: %s\n", context)
|
||||
c.CurrentContext = context
|
||||
if newContext != "" {
|
||||
Logf(">>> context: %s\n", newContext)
|
||||
c.CurrentContext = newContext
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
|
@ -98,6 +98,7 @@ func createNamespace(baseName string, labels map[string]string, c kubernetes.Int
|
|||
var got *corev1.Namespace
|
||||
var err error
|
||||
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
err = wait.Poll(Poll, DefaultTimeout, func() (bool, error) {
|
||||
got, err = c.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
|
|
@ -114,13 +115,11 @@ func createNamespace(baseName string, labels map[string]string, c kubernetes.Int
|
|||
|
||||
// CreateKubeNamespace creates a new namespace in the cluster
|
||||
func CreateKubeNamespace(baseName string, c kubernetes.Interface) (string, error) {
|
||||
|
||||
return createNamespace(baseName, nil, c)
|
||||
}
|
||||
|
||||
// CreateKubeNamespaceWithLabel creates a new namespace with given labels in the cluster
|
||||
func CreateKubeNamespaceWithLabel(baseName string, labels map[string]string, c kubernetes.Interface) (string, error) {
|
||||
|
||||
return createNamespace(baseName, labels, c)
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +149,7 @@ func CreateIngressClass(namespace string, c kubernetes.Interface) (string, error
|
|||
},
|
||||
}, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Unexpected error creating IngressClass %s: %v", icname, err)
|
||||
return "", fmt.Errorf("unexpected error creating IngressClass %s: %v", icname, err)
|
||||
}
|
||||
|
||||
_, err = c.RbacV1().ClusterRoles().Create(context.TODO(), &rbacv1.ClusterRole{
|
||||
|
|
@ -162,7 +161,7 @@ func CreateIngressClass(namespace string, c kubernetes.Interface) (string, error
|
|||
}},
|
||||
}, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Unexpected error creating IngressClass ClusterRole %s: %v", icname, err)
|
||||
return "", fmt.Errorf("unexpected error creating IngressClass ClusterRole %s: %v", icname, err)
|
||||
}
|
||||
|
||||
_, err = c.RbacV1().ClusterRoleBindings().Create(context.TODO(), &rbacv1.ClusterRoleBinding{
|
||||
|
|
@ -184,7 +183,7 @@ func CreateIngressClass(namespace string, c kubernetes.Interface) (string, error
|
|||
},
|
||||
}, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Unexpected error creating IngressClass ClusterRoleBinding %s: %v", icname, err)
|
||||
return "", fmt.Errorf("unexpected error creating IngressClass ClusterRoleBinding %s: %v", icname, err)
|
||||
}
|
||||
return ic.Name, nil
|
||||
}
|
||||
|
|
@ -200,16 +199,16 @@ func deleteIngressClass(c kubernetes.Interface, ingressclass string) error {
|
|||
}
|
||||
err = c.NetworkingV1().IngressClasses().Delete(context.TODO(), ingressclass, deleteOptions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unexpected error deleting IngressClass %s: %v", ingressclass, err)
|
||||
return fmt.Errorf("unexpected error deleting IngressClass %s: %v", ingressclass, err)
|
||||
}
|
||||
|
||||
err = c.RbacV1().ClusterRoleBindings().Delete(context.TODO(), ingressclass, deleteOptions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unexpected error deleting IngressClass ClusterRoleBinding %s: %v", ingressclass, err)
|
||||
return fmt.Errorf("unexpected error deleting IngressClass ClusterRoleBinding %s: %v", ingressclass, err)
|
||||
}
|
||||
err = c.RbacV1().ClusterRoles().Delete(context.TODO(), ingressclass, deleteOptions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unexpected error deleting IngressClass ClusterRole %s: %v", ingressclass, err)
|
||||
return fmt.Errorf("unexpected error deleting IngressClass ClusterRole %s: %v", ingressclass, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -223,6 +222,7 @@ func GetIngressClassName(namespace string) *string {
|
|||
|
||||
// WaitForKubeNamespaceNotExist waits until a namespaces is not present in the cluster
|
||||
func WaitForKubeNamespaceNotExist(c kubernetes.Interface, namespace string) error {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
return wait.Poll(Poll, DefaultTimeout, namespaceNotExist(c, namespace))
|
||||
}
|
||||
|
||||
|
|
@ -241,6 +241,7 @@ func namespaceNotExist(c kubernetes.Interface, namespace string) wait.ConditionF
|
|||
|
||||
// WaitForNoPodsInNamespace waits until there are no pods running in a namespace
|
||||
func WaitForNoPodsInNamespace(c kubernetes.Interface, namespace string) error {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
return wait.Poll(Poll, DefaultTimeout, noPodsInNamespace(c, namespace))
|
||||
}
|
||||
|
||||
|
|
@ -267,15 +268,17 @@ func WaitForPodRunningInNamespace(c kubernetes.Interface, pod *corev1.Pod) error
|
|||
if pod.Status.Phase == corev1.PodRunning {
|
||||
return nil
|
||||
}
|
||||
return waitTimeoutForPodRunningInNamespace(c, pod.Name, pod.Namespace, DefaultTimeout)
|
||||
return waitTimeoutForPodRunningInNamespace(c, pod.Name, pod.Namespace)
|
||||
}
|
||||
|
||||
func waitTimeoutForPodRunningInNamespace(c kubernetes.Interface, podName, namespace string, timeout time.Duration) error {
|
||||
func waitTimeoutForPodRunningInNamespace(c kubernetes.Interface, podName, namespace string) error {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
return wait.Poll(Poll, DefaultTimeout, podRunning(c, podName, namespace))
|
||||
}
|
||||
|
||||
// WaitForSecretInNamespace waits a default amount of time for the specified secret is present in a particular namespace
|
||||
func WaitForSecretInNamespace(c kubernetes.Interface, namespace, name string) error {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
return wait.Poll(Poll, DefaultTimeout, secretInNamespace(c, namespace, name))
|
||||
}
|
||||
|
||||
|
|
@ -298,6 +301,7 @@ func secretInNamespace(c kubernetes.Interface, namespace, name string) wait.Cond
|
|||
|
||||
// WaitForFileInFS waits a default amount of time for the specified file is present in the filesystem
|
||||
func WaitForFileInFS(file string) error {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
return wait.Poll(Poll, DefaultTimeout, fileInFS(file))
|
||||
}
|
||||
|
||||
|
|
@ -322,6 +326,7 @@ func fileInFS(file string) wait.ConditionFunc {
|
|||
|
||||
// WaitForNoIngressInNamespace waits until there is no ingress object in a particular namespace
|
||||
func WaitForNoIngressInNamespace(c kubernetes.Interface, namespace, name string) error {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
return wait.Poll(Poll, DefaultTimeout, noIngressInNamespace(c, namespace, name))
|
||||
}
|
||||
|
||||
|
|
@ -344,6 +349,7 @@ func noIngressInNamespace(c kubernetes.Interface, namespace, name string) wait.C
|
|||
|
||||
// WaitForIngressInNamespace waits until a particular ingress object exists namespace
|
||||
func WaitForIngressInNamespace(c kubernetes.Interface, namespace, name string) error {
|
||||
//nolint:staticcheck // TODO: will replace it since wait.Poll is deprecated
|
||||
return wait.Poll(Poll, DefaultTimeout, ingressInNamespace(c, namespace, name))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ var _ = framework.IngressNginxDescribe("[Shutdown] Grace period shutdown", func(
|
|||
f := framework.NewDefaultFramework("shutdown-grace-period")
|
||||
|
||||
ginkgo.It("/healthz should return status code 500 during shutdown grace period", func() {
|
||||
|
||||
f.NewSlowEchoDeployment()
|
||||
|
||||
err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error {
|
||||
|
|
@ -83,6 +82,5 @@ var _ = framework.IngressNginxDescribe("[Shutdown] Grace period shutdown", func(
|
|||
for _, err := range <-result {
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
}
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -36,6 +36,15 @@ var _ = framework.IngressNginxDescribe("single ingress - multiple hosts", func()
|
|||
})
|
||||
|
||||
ginkgo.It("should set the correct $service_name NGINX variable", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_input_headers "service-name: $service_name";`,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,14 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] exact", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should choose exact location for /exact", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := "exact.path"
|
||||
|
||||
|
|
@ -42,7 +50,7 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] exact", func() {
|
|||
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_input_headers "pathType: exact";`,
|
||||
}
|
||||
|
||||
var exactPathType = networking.PathTypeExact
|
||||
exactPathType := networking.PathTypeExact
|
||||
ing := framework.NewSingleIngress("exact", "/exact", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
ing.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].PathType = &exactPathType
|
||||
f.EnsureIngress(ing)
|
||||
|
|
|
|||
|
|
@ -34,9 +34,17 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] mix Exact and Prefi
|
|||
f.NewEchoDeployment()
|
||||
})
|
||||
|
||||
var exactPathType = networking.PathTypeExact
|
||||
exactPathType := networking.PathTypeExact
|
||||
|
||||
ginkgo.It("should choose the correct location", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := "mixed.path"
|
||||
|
||||
|
|
|
|||
|
|
@ -68,4 +68,138 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] prefix checks", fun
|
|||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
|
||||
ginkgo.It("should test prefix path using simple regex pattern for /id/{int}", func() {
|
||||
host := "echo.com.br"
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/use-regex": `true`,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/id/[0-9]+", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/1").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/12").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/123").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/aaa").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/123a").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
|
||||
ginkgo.It("should test prefix path using regex pattern for /id/{int} ignoring non-digits characters at end of string", func() {
|
||||
host := "echo.regex.br"
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/use-regex": `true`,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/id/[0-9]+$", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/1").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/aaa").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/123a").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
})
|
||||
|
||||
ginkgo.It("should test prefix path using fixed path size regex pattern /id/{int}{3}", func() {
|
||||
host := "echo.regex.size.br"
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/use-regex": `true`,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/id/[0-9]{3}$", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/99").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/123").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/9999").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/123a").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
})
|
||||
|
||||
ginkgo.It("should correctly route multi-segment path patterns", func() {
|
||||
host := "echo.multi.segment.br"
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/use-regex": `true`,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/id/[0-9]+/post/[a-zA-Z]+$", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/123/post/abc").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/123/post/abc123").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/id/abc/post/abc").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -87,14 +87,14 @@ func provisionIngress(hostname string, f *framework.Framework) {
|
|||
func checkIngress(hostname string, f *framework.Framework) {
|
||||
resp := f.HTTPTestClientWithTLSConfig(&tls.Config{
|
||||
ServerName: hostname,
|
||||
InsecureSkipVerify: true,
|
||||
InsecureSkipVerify: true, //nolint:gosec // Ignore the gosec error in testing
|
||||
}).
|
||||
GET("/").
|
||||
WithURL(f.GetURL(framework.HTTPS)).
|
||||
WithHeader("Host", hostname).
|
||||
Expect().
|
||||
Raw()
|
||||
|
||||
defer resp.Body.Close()
|
||||
assert.Equal(ginkgo.GinkgoT(), resp.StatusCode, http.StatusOK)
|
||||
|
||||
// check the returned secret is not the fake one
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const loadBalanceHost = "load-balance.com"
|
||||
|
||||
var _ = framework.DescribeSetting("[Load Balancer] load-balance", func() {
|
||||
f := framework.NewDefaultFramework("lb-configmap")
|
||||
|
||||
|
|
@ -33,7 +35,7 @@ var _ = framework.DescribeSetting("[Load Balancer] load-balance", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should apply the configmap load-balance setting", func() {
|
||||
host := "load-balance.com"
|
||||
host := loadBalanceHost
|
||||
|
||||
f.UpdateNginxConfigMapData("load-balance", "ewma")
|
||||
|
||||
|
|
|
|||
|
|
@ -35,12 +35,13 @@ var _ = framework.DescribeSetting("[Load Balancer] EWMA", func() {
|
|||
f.NewEchoDeployment(framework.WithDeploymentReplicas(3))
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"worker-processes": "2",
|
||||
"load-balance": "ewma"},
|
||||
"load-balance": "ewma",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
ginkgo.It("does not fail requests", func() {
|
||||
host := "load-balance.com"
|
||||
host := loadBalanceHost
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil))
|
||||
f.WaitForNginxServer(host,
|
||||
|
|
@ -52,7 +53,9 @@ var _ = framework.DescribeSetting("[Load Balancer] EWMA", func() {
|
|||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
assert.Equal(ginkgo.GinkgoT(), algorithm, "ewma")
|
||||
|
||||
re, _ := regexp.Compile(fmt.Sprintf(`%v.*`, framework.EchoService))
|
||||
re, err := regexp.Compile(fmt.Sprintf(`%v.*`, framework.EchoService))
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "error compiling regex")
|
||||
|
||||
replicaRequestCount := map[string]int{}
|
||||
|
||||
for i := 0; i < 30; i++ {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ var _ = framework.DescribeSetting("[Load Balancer] round-robin", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should evenly distribute requests with round-robin (default algorithm)", func() {
|
||||
host := "load-balance.com"
|
||||
host := loadBalanceHost
|
||||
|
||||
f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil))
|
||||
f.WaitForNginxServer(host,
|
||||
|
|
@ -45,7 +45,9 @@ var _ = framework.DescribeSetting("[Load Balancer] round-robin", func() {
|
|||
return strings.Contains(server, "server_name load-balance.com")
|
||||
})
|
||||
|
||||
re, _ := regexp.Compile(fmt.Sprintf(`%v.*`, framework.EchoService))
|
||||
re, err := regexp.Compile(fmt.Sprintf(`%v.*`, framework.EchoService))
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "error compiling regex")
|
||||
|
||||
replicaRequestCount := map[string]int{}
|
||||
|
||||
for i := 0; i < 600; i++ {
|
||||
|
|
|
|||
|
|
@ -245,7 +245,6 @@ var _ = framework.IngressNginxDescribe("[Lua] dynamic certificates", func() {
|
|||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -254,7 +253,6 @@ func extractReloadCount(mf *dto.MetricFamily) (float64, error) {
|
|||
vec, err := expfmt.ExtractSamples(&expfmt.DecodeOptions{
|
||||
Timestamp: model.Now(),
|
||||
}, mf)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import (
|
|||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
networking "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
|
|
@ -199,20 +198,18 @@ var _ = framework.IngressNginxDescribe("[Lua] dynamic configuration", func() {
|
|||
})
|
||||
})
|
||||
|
||||
func ensureIngress(f *framework.Framework, host string, deploymentName string) *networking.Ingress {
|
||||
ing := createIngress(f, host, deploymentName)
|
||||
func ensureIngress(f *framework.Framework, host, deploymentName string) {
|
||||
createIngress(f, host, deploymentName)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
|
||||
return ing
|
||||
}
|
||||
|
||||
func createIngress(f *framework.Framework, host string, deploymentName string) *networking.Ingress {
|
||||
ing := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, deploymentName, 80,
|
||||
func createIngress(f *framework.Framework, host, deploymentName string) {
|
||||
f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, deploymentName, 80,
|
||||
map[string]string{
|
||||
"nginx.ingress.kubernetes.io/load-balance": "ewma",
|
||||
},
|
||||
|
|
@ -223,21 +220,19 @@ func createIngress(f *framework.Framework, host string, deploymentName string) *
|
|||
return strings.Contains(server, fmt.Sprintf("server_name %s ;", host)) &&
|
||||
strings.Contains(server, "proxy_pass http://upstream_balancer;")
|
||||
})
|
||||
|
||||
return ing
|
||||
}
|
||||
|
||||
func ensureHTTPSRequest(f *framework.Framework, url string, host string, expectedDNSName string) {
|
||||
func ensureHTTPSRequest(f *framework.Framework, url, host, expectedDNSName string) {
|
||||
resp := f.HTTPTestClientWithTLSConfig(&tls.Config{
|
||||
ServerName: host,
|
||||
InsecureSkipVerify: true,
|
||||
InsecureSkipVerify: true, //nolint:gosec // Ignore the gosec error in testing
|
||||
}).
|
||||
GET("/").
|
||||
WithURL(url).
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Raw()
|
||||
|
||||
defer resp.Body.Close()
|
||||
assert.Equal(ginkgo.GinkgoT(), resp.StatusCode, http.StatusOK)
|
||||
assert.Equal(ginkgo.GinkgoT(), len(resp.TLS.PeerCertificates), 1)
|
||||
assert.Equal(ginkgo.GinkgoT(), resp.TLS.PeerCertificates[0].DNSNames[0], expectedDNSName)
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ var _ = framework.DescribeSetting("nginx-configuration", func() {
|
|||
f := framework.NewSimpleFramework("nginxconfiguration")
|
||||
|
||||
ginkgo.It("start nginx with default configuration", func() {
|
||||
|
||||
f.NGINXWithConfigDeployment("default-nginx", cfgOK)
|
||||
f.WaitForPod("app=default-nginx", 60*time.Second, false)
|
||||
framework.Sleep(5 * time.Second)
|
||||
|
|
@ -113,20 +112,16 @@ var _ = framework.DescribeSetting("nginx-configuration", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("fails when using alias directive", func() {
|
||||
|
||||
f.NGINXDeployment("alias-nginx", cfgAlias, false)
|
||||
// This should fail with a crashloopback because our NGINX does not have
|
||||
// alias directive!
|
||||
f.WaitForPod("app=alias-nginx", 60*time.Second, true)
|
||||
|
||||
})
|
||||
|
||||
ginkgo.It("fails when using root directive", func() {
|
||||
|
||||
f.NGINXDeployment("root-nginx", cfgRoot, false)
|
||||
// This should fail with a crashloopback because our NGINX does not have
|
||||
// root directive!
|
||||
f.WaitForPod("app=root-nginx", 60*time.Second, true)
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export KUBECONFIG="${KUBECONFIG:-$HOME/.kube/kind-config-$KIND_CLUSTER_NAME}"
|
|||
if [ "${SKIP_CLUSTER_CREATION:-false}" = "false" ]; then
|
||||
echo "[dev-env] creating Kubernetes cluster with kind"
|
||||
|
||||
export K8S_VERSION=${K8S_VERSION:-v1.26.3@sha256:61b92f38dff6ccc29969e7aa154d34e38b89443af1a2c14e6cfbd2df6419c66f}
|
||||
export K8S_VERSION=${K8S_VERSION:-v1.29.2@sha256:51a1434a5397193442f0be2a297b488b6c919ce8a3931be0ce822606ea5ca245}
|
||||
|
||||
kind create cluster \
|
||||
--verbosity=${KIND_LOG_LEVEL} \
|
||||
|
|
@ -78,7 +78,7 @@ fi
|
|||
|
||||
if [ "${SKIP_IMAGE_CREATION:-false}" = "false" ]; then
|
||||
if ! command -v ginkgo &> /dev/null; then
|
||||
go install github.com/onsi/ginkgo/v2/ginkgo@v2.9.5
|
||||
go install github.com/onsi/ginkgo/v2/ginkgo@v2.17.1
|
||||
fi
|
||||
echo "[dev-env] building image"
|
||||
make -C ${DIR}/../../ clean-image build image
|
||||
|
|
@ -104,13 +104,12 @@ if [ "${SKIP_CERT_MANAGER_CREATION:-false}" = "false" ]; then
|
|||
fi
|
||||
|
||||
echo "[dev-env] running helm chart e2e tests..."
|
||||
# Uses a custom chart-testing image to avoid timeouts waiting for namespace deletion.
|
||||
# The changes can be found here: https://github.com/aledbf/chart-testing/commit/41fe0ae0733d0c9a538099fb3cec522e888e3d82
|
||||
docker run --rm --interactive --network host \
|
||||
--name ct \
|
||||
--volume $KUBECONFIG:/root/.kube/config \
|
||||
--volume "${DIR}/../../":/workdir \
|
||||
--workdir /workdir \
|
||||
aledbf/chart-testing:v3.3.1-next ct install \
|
||||
registry.k8s.io/ingress-nginx/e2e-test-runner:v20240404-436df3e4@sha256:6bcba53b14d396177414e01f20e9111f1c009ac3b476a9b7668bb98d12bd5e85 \
|
||||
ct install \
|
||||
--charts charts/ingress-nginx \
|
||||
--helm-extra-args "--timeout 60s"
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ kubectl run --rm \
|
|||
--env="E2E_NODES=${E2E_NODES}" \
|
||||
--env="FOCUS=${FOCUS}" \
|
||||
--env="IS_CHROOT=${IS_CHROOT:-false}"\
|
||||
--env="ENABLE_VALIDATIONS=${ENABLE_VALIDATIONS:-false}"\
|
||||
--env="SKIP_OPENTELEMETRY_TESTS=${SKIP_OPENTELEMETRY_TESTS:-false}"\
|
||||
--env="E2E_CHECK_LEAKS=${E2E_CHECK_LEAKS}" \
|
||||
--env="NGINX_BASE_IMAGE=${NGINX_BASE_IMAGE}" \
|
||||
--env="HTTPBUN_IMAGE=${HTTPBUN_IMAGE}" \
|
||||
|
|
|
|||
|
|
@ -39,13 +39,14 @@ fi
|
|||
|
||||
KIND_LOG_LEVEL="1"
|
||||
IS_CHROOT="${IS_CHROOT:-false}"
|
||||
ENABLE_VALIDATIONS="${ENABLE_VALIDATIONS:-false}"
|
||||
export KIND_CLUSTER_NAME=${KIND_CLUSTER_NAME:-ingress-nginx-dev}
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
# Use 1.0.0-dev to make sure we use the latest configuration in the helm template
|
||||
export TAG=1.0.0-dev
|
||||
export ARCH=${ARCH:-amd64}
|
||||
export REGISTRY=ingress-controller
|
||||
NGINX_BASE_IMAGE=$(cat "$DIR"/../../NGINX_BASE)
|
||||
NGINX_BASE_IMAGE=${NGINX_BASE_IMAGE:-$(cat "$DIR"/../../NGINX_BASE)}
|
||||
export NGINX_BASE_IMAGE=$NGINX_BASE_IMAGE
|
||||
export DOCKER_CLI_EXPERIMENTAL=enabled
|
||||
export KUBECONFIG="${KUBECONFIG:-$HOME/.kube/kind-config-$KIND_CLUSTER_NAME}"
|
||||
|
|
@ -63,7 +64,7 @@ echo "Running e2e with nginx base image ${NGINX_BASE_IMAGE}"
|
|||
if [ "${SKIP_CLUSTER_CREATION}" = "false" ]; then
|
||||
echo "[dev-env] creating Kubernetes cluster with kind"
|
||||
|
||||
export K8S_VERSION=${K8S_VERSION:-v1.26.3@sha256:61b92f38dff6ccc29969e7aa154d34e38b89443af1a2c14e6cfbd2df6419c66f}
|
||||
export K8S_VERSION=${K8S_VERSION:-v1.29.2@sha256:51a1434a5397193442f0be2a297b488b6c919ce8a3931be0ce822606ea5ca245}
|
||||
|
||||
# delete the cluster if it exists
|
||||
if kind get clusters | grep "${KIND_CLUSTER_NAME}"; then
|
||||
|
|
@ -84,10 +85,10 @@ fi
|
|||
if [ "${SKIP_INGRESS_IMAGE_CREATION}" = "false" ]; then
|
||||
echo "[dev-env] building image"
|
||||
if [ "${IS_CHROOT}" = "true" ]; then
|
||||
make -C "${DIR}"/../../ clean-image build image-chroot
|
||||
make BASE_IMAGE="${NGINX_BASE_IMAGE}" -C "${DIR}"/../../ clean-image build image-chroot
|
||||
docker tag ${REGISTRY}/controller-chroot:${TAG} ${REGISTRY}/controller:${TAG}
|
||||
else
|
||||
make -C "${DIR}"/../../ clean-image build image
|
||||
make BASE_IMAGE="${NGINX_BASE_IMAGE}" -C "${DIR}"/../../ clean-image build image
|
||||
fi
|
||||
|
||||
echo "[dev-env] .. done building controller images"
|
||||
|
|
@ -95,7 +96,7 @@ fi
|
|||
|
||||
if [ "${SKIP_E2E_IMAGE_CREATION}" = "false" ]; then
|
||||
if ! command -v ginkgo &> /dev/null; then
|
||||
go install github.com/onsi/ginkgo/v2/ginkgo@v2.9.5
|
||||
go install github.com/onsi/ginkgo/v2/ginkgo@v2.17.1
|
||||
fi
|
||||
|
||||
echo "[dev-env] .. done building controller images"
|
||||
|
|
|
|||
|
|
@ -50,9 +50,9 @@ server {
|
|||
|
||||
f.UpdateNginxConfigMapData("http-snippet", snippet)
|
||||
|
||||
//TODO: currently using a self hosted HTTPBun instance results in a 499, we
|
||||
//should move away from using httpbun.com once we have the httpbun
|
||||
//deployment as part of the framework
|
||||
// TODO: currently using a self hosted HTTPBun instance results in a 499, we
|
||||
// should move away from using httpbun.com once we have the httpbun
|
||||
// deployment as part of the framework
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-signin": "https://httpbun.com/bearer/d4bcba7a-0def-4a31-91a7-47e420adf44b",
|
||||
"nginx.ingress.kubernetes.io/auth-url": "https://httpbun.com/basic-auth/user/passwd",
|
||||
|
|
@ -91,7 +91,7 @@ func smugglingRequest(host, addr string, port int) (string, error) {
|
|||
// wait for /_hidden/index.html response
|
||||
framework.Sleep()
|
||||
|
||||
var buf = make([]byte, 1024)
|
||||
buf := make([]byte, 1024)
|
||||
r := bufio.NewReader(conn)
|
||||
_, err = r.Read(buf)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -29,48 +29,50 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var pathtype = networking.PathTypePrefix
|
||||
var _ = framework.IngressNginxDescribe("[Service] backend status code 503", func() {
|
||||
f := framework.NewDefaultFramework("service-backend")
|
||||
var (
|
||||
pathtype = networking.PathTypePrefix
|
||||
_ = framework.IngressNginxDescribe("[Service] backend status code 503", func() {
|
||||
f := framework.NewDefaultFramework("service-backend")
|
||||
|
||||
ginkgo.It("should return 503 when backend service does not exist", func() {
|
||||
host := "nonexistent.svc.com"
|
||||
ginkgo.It("should return 503 when backend service does not exist", func() {
|
||||
host := "nonexistent.svc.com"
|
||||
|
||||
bi := buildIngressWithNonexistentService(host, f.Namespace, "/")
|
||||
f.EnsureIngress(bi)
|
||||
bi := buildIngressWithNonexistentService(host, f.Namespace, "/")
|
||||
f.EnsureIngress(bi)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "proxy_pass http://upstream_balancer;")
|
||||
})
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "proxy_pass http://upstream_balancer;")
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusServiceUnavailable)
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusServiceUnavailable)
|
||||
})
|
||||
|
||||
ginkgo.It("should return 503 when all backend service endpoints are unavailable", func() {
|
||||
host := "unavailable.svc.com"
|
||||
|
||||
bi, bs := buildIngressWithUnavailableServiceEndpoints(host, f.Namespace, "/")
|
||||
|
||||
f.EnsureService(bs)
|
||||
f.EnsureIngress(bi)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "proxy_pass http://upstream_balancer;")
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusServiceUnavailable)
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.It("should return 503 when all backend service endpoints are unavailable", func() {
|
||||
host := "unavailable.svc.com"
|
||||
|
||||
bi, bs := buildIngressWithUnavailableServiceEndpoints(host, f.Namespace, "/")
|
||||
|
||||
f.EnsureService(bs)
|
||||
f.EnsureIngress(bi)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "proxy_pass http://upstream_balancer;")
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusServiceUnavailable)
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
func buildIngressWithNonexistentService(host, namespace, path string) *networking.Ingress {
|
||||
backendService := "nonexistent-svc"
|
||||
|
|
@ -146,14 +148,15 @@ func buildIngressWithUnavailableServiceEndpoints(host, namespace, path string) (
|
|||
Name: backendService,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: corev1.ServiceSpec{Ports: []corev1.ServicePort{
|
||||
{
|
||||
Name: "tcp",
|
||||
Port: 80,
|
||||
TargetPort: intstr.FromInt(80),
|
||||
Protocol: "TCP",
|
||||
Spec: corev1.ServiceSpec{
|
||||
Ports: []corev1.ServicePort{
|
||||
{
|
||||
Name: "tcp",
|
||||
Port: 80,
|
||||
TargetPort: intstr.FromInt(80),
|
||||
Protocol: "TCP",
|
||||
},
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{
|
||||
"app": backendService,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,16 +30,17 @@ import (
|
|||
networking "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"k8s.io/ingress-nginx/internal/nginx"
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const echoHost = "echo"
|
||||
|
||||
var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() {
|
||||
f := framework.NewDefaultFramework("type-externalname", framework.WithHTTPBunEnabled())
|
||||
|
||||
ginkgo.It("works with external name set to incomplete fqdn", func() {
|
||||
f.NewEchoDeployment()
|
||||
host := "echo"
|
||||
host := echoHost
|
||||
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
|
@ -75,7 +76,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return 200 for service type=ExternalName without a port defined", func() {
|
||||
host := "echo"
|
||||
host := echoHost
|
||||
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
|
@ -115,7 +116,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return 200 for service type=ExternalName with a port defined", func() {
|
||||
host := "echo"
|
||||
host := echoHost
|
||||
|
||||
svc := framework.BuildNIPExternalNameService(f, f.HTTPBunIP, host)
|
||||
f.EnsureService(svc)
|
||||
|
|
@ -145,7 +146,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status 502 for service type=ExternalName with an invalid host", func() {
|
||||
host := "echo"
|
||||
host := echoHost
|
||||
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
|
@ -181,7 +182,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return 200 for service type=ExternalName using a port name", func() {
|
||||
host := "echo"
|
||||
host := echoHost
|
||||
|
||||
svc := framework.BuildNIPExternalNameService(f, f.HTTPBunIP, host)
|
||||
f.EnsureService(svc)
|
||||
|
|
@ -222,7 +223,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return 200 for service type=ExternalName using FQDN with trailing dot", func() {
|
||||
host := "echo"
|
||||
host := echoHost
|
||||
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
|
@ -258,7 +259,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should update the external name after a service update", func() {
|
||||
host := "echo"
|
||||
host := echoHost
|
||||
|
||||
svc := framework.BuildNIPExternalNameService(f, f.HTTPBunIP, host)
|
||||
f.EnsureService(svc)
|
||||
|
|
@ -307,7 +308,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() {
|
|||
Get(context.TODO(), framework.NIPService, metav1.GetOptions{})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "unexpected error obtaining external service")
|
||||
|
||||
//Deploy a new instance to switch routing to
|
||||
// Deploy a new instance to switch routing to
|
||||
ip := f.NewHttpbunDeployment(framework.WithDeploymentName("eu-server"))
|
||||
svc.Spec.ExternalName = framework.BuildNIPHost(ip)
|
||||
|
||||
|
|
@ -330,22 +331,18 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() {
|
|||
assert.Contains(ginkgo.GinkgoT(), body, `"X-Forwarded-Host": "echo"`)
|
||||
|
||||
ginkgo.By("checking the service is updated to use new host")
|
||||
curlCmd := fmt.Sprintf(
|
||||
"curl --fail --silent http://localhost:%v/configuration/backends",
|
||||
nginx.StatusPort,
|
||||
)
|
||||
|
||||
output, err := f.ExecIngressPod(curlCmd)
|
||||
dbgCmd := "/dbg backends all"
|
||||
output, err := f.ExecIngressPod(dbgCmd)
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
assert.Contains(
|
||||
ginkgo.GinkgoT(),
|
||||
output,
|
||||
fmt.Sprintf("{\"address\":\"%s\"", framework.BuildNIPHost(ip)),
|
||||
fmt.Sprintf(`"address": %q`, framework.BuildNIPHost(ip)),
|
||||
)
|
||||
})
|
||||
|
||||
ginkgo.It("should sync ingress on external name service addition/deletion", func() {
|
||||
host := "echo"
|
||||
host := echoHost
|
||||
|
||||
// Create the Ingress first
|
||||
ing := framework.NewSingleIngress(host,
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ var _ = framework.IngressNginxDescribe("[Service] Nil Service Backend", func() {
|
|||
WithHeader("Host", invalidHost).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ var _ = framework.DescribeSetting("access-log", func() {
|
|||
f := framework.NewDefaultFramework("access-log")
|
||||
|
||||
ginkgo.Context("access-log-path", func() {
|
||||
|
||||
ginkgo.It("use the default configuration", func() {
|
||||
f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
|
|
@ -50,7 +49,6 @@ var _ = framework.DescribeSetting("access-log", func() {
|
|||
})
|
||||
|
||||
ginkgo.Context("http-access-log-path", func() {
|
||||
|
||||
ginkgo.It("use the specified configuration", func() {
|
||||
f.UpdateNginxConfigMapData("http-access-log-path", "/tmp/nginx/http-access.log")
|
||||
f.WaitForNginxConfiguration(
|
||||
|
|
@ -63,7 +61,6 @@ var _ = framework.DescribeSetting("access-log", func() {
|
|||
})
|
||||
|
||||
ginkgo.Context("stream-access-log-path", func() {
|
||||
|
||||
ginkgo.It("use the specified configuration", func() {
|
||||
f.UpdateNginxConfigMapData("stream-access-log-path", "/tmp/nginx/stream-access.log")
|
||||
f.WaitForNginxConfiguration(
|
||||
|
|
@ -76,7 +73,6 @@ var _ = framework.DescribeSetting("access-log", func() {
|
|||
})
|
||||
|
||||
ginkgo.Context("http-access-log-path & stream-access-log-path", func() {
|
||||
|
||||
ginkgo.It("use the specified configuration", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"http-access-log-path": "/tmp/nginx/http-access.log",
|
||||
|
|
|
|||
54
test/e2e/settings/aio_write.go
Normal file
54
test/e2e/settings/aio_write.go
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package settings
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.DescribeSetting("aio-write", func() {
|
||||
f := framework.NewDefaultFramework("aio-write")
|
||||
|
||||
ginkgo.It("should be enabled by default", func() {
|
||||
f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, "aio_write on")
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.It("should be enabled when setting is true", func() {
|
||||
f.UpdateNginxConfigMapData("enable-aio-write", "true")
|
||||
|
||||
f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, "aio_write on")
|
||||
})
|
||||
})
|
||||
|
||||
ginkgo.It("should be disabled when setting is false", func() {
|
||||
f.UpdateNginxConfigMapData("enable-aio-write", "false")
|
||||
|
||||
f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return !strings.Contains(cfg, "aio_write on")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -34,6 +34,14 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is an invalid character in some annotation", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
host := "invalid-value-test"
|
||||
|
||||
annotations := map[string]string{
|
||||
|
|
@ -65,6 +73,15 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is a forbidden word in some annotation", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
host := "forbidden-value-test"
|
||||
|
||||
annotations := map[string]string{
|
||||
|
|
@ -100,7 +117,14 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("[BAD_ANNOTATIONS] should allow an ingress if there is a default blocklist config in place", func() {
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
hostValid := "custom-allowed-value-test"
|
||||
annotationsValid := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": `
|
||||
|
|
@ -131,6 +155,14 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is a custom blocklist config in place and allow others to pass", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
host := "custom-forbidden-value-test"
|
||||
|
||||
annotations := map[string]string{
|
||||
|
|
@ -159,6 +191,5 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -30,10 +30,12 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const fooHost = "foo"
|
||||
|
||||
var _ = framework.IngressNginxDescribe("[SSL] [Flag] default-ssl-certificate", func() {
|
||||
f := framework.NewDefaultFramework("default-ssl-certificate")
|
||||
var tlsConfig *tls.Config
|
||||
secretName := "my-custom-cert"
|
||||
secretName := "my-custom-cert" //nolint:gosec // Ignore the gosec error in testing
|
||||
service := framework.EchoService
|
||||
port := 80
|
||||
|
||||
|
|
@ -78,7 +80,7 @@ var _ = framework.IngressNginxDescribe("[SSL] [Flag] default-ssl-certificate", f
|
|||
})
|
||||
|
||||
ginkgo.It("uses default ssl certificate for host based ingress when configured certificate does not match host", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
|
||||
ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, service, port, nil))
|
||||
_, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ var _ = framework.IngressNginxDescribe("[Flag] disable-catch-all", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should ignore catch all Ingress with backend", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
|
||||
ing := framework.NewSingleCatchAllIngress("catch-all", f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -67,7 +67,7 @@ var _ = framework.IngressNginxDescribe("[Flag] disable-catch-all", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should ignore catch all Ingress with backend and rules", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
|
||||
ing := framework.NewSingleIngressWithBackendAndRules(host, "/", host, f.Namespace, framework.EchoService, 80, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -79,7 +79,7 @@ var _ = framework.IngressNginxDescribe("[Flag] disable-catch-all", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should delete Ingress updated to catch-all", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
@ -121,7 +121,7 @@ var _ = framework.IngressNginxDescribe("[Flag] disable-catch-all", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should allow Ingress with rules", func() {
|
||||
host := "foo"
|
||||
host := fooHost
|
||||
|
||||
ing := framework.NewSingleIngress("not-catch-all", "/", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
|
|
|||
|
|
@ -95,6 +95,5 @@ var _ = framework.IngressNginxDescribe("[Flag] disable-service-external-name", f
|
|||
WithHeader("Host", externalhost).
|
||||
Expect().
|
||||
StatusRange(httpexpect.Status5xx)
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -44,12 +44,14 @@ var _ = framework.IngressNginxDescribe("[Flag] disable-sync-events", func() {
|
|||
return strings.Contains(server, fmt.Sprintf("server_name %v", host))
|
||||
})
|
||||
|
||||
//nolint:goconst //string interpolation
|
||||
events, err := f.KubeClientSet.CoreV1().Events(ing.Namespace).List(context.TODO(), metav1.ListOptions{FieldSelector: "reason=Sync,involvedObject.name=" + host})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "listing events")
|
||||
|
||||
assert.NotEmpty(ginkgo.GinkgoT(), events.Items, "got events")
|
||||
})
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
ginkgo.It("should create sync events", func() {
|
||||
host := "disable-sync-events-false"
|
||||
f.NewEchoDeployment(framework.WithDeploymentReplicas(1))
|
||||
|
|
@ -77,6 +79,7 @@ var _ = framework.IngressNginxDescribe("[Flag] disable-sync-events", func() {
|
|||
assert.NotEmpty(ginkgo.GinkgoT(), events.Items, "got events")
|
||||
})
|
||||
|
||||
//nolint:dupl // Ignore dupl errors for similar test case
|
||||
ginkgo.It("should not create sync events", func() {
|
||||
host := "disable-sync-events-true"
|
||||
f.NewEchoDeployment(framework.WithDeploymentReplicas(1))
|
||||
|
|
@ -103,5 +106,4 @@ var _ = framework.IngressNginxDescribe("[Flag] disable-sync-events", func() {
|
|||
|
||||
assert.Empty(ginkgo.GinkgoT(), events.Items, "got events")
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ var _ = framework.DescribeSetting("enable-real-ip", func() {
|
|||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
//nolint:goconst //already a const
|
||||
return strings.Contains(server, "server_name "+host) &&
|
||||
!strings.Contains(server, "proxy_set_header X-Forwarded-Proto $full_x_forwarded_proto;")
|
||||
})
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const forwardedHeadersHost = "forwarded-headers"
|
||||
|
||||
var _ = framework.DescribeSetting("use-forwarded-headers", func() {
|
||||
f := framework.NewDefaultFramework("forwarded-headers")
|
||||
|
||||
|
|
@ -37,7 +39,7 @@ var _ = framework.DescribeSetting("use-forwarded-headers", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should trust X-Forwarded headers when setting is true", func() {
|
||||
host := "forwarded-headers"
|
||||
host := forwardedHeadersHost
|
||||
|
||||
f.UpdateNginxConfigMapData(setting, "true")
|
||||
|
||||
|
|
@ -89,7 +91,7 @@ var _ = framework.DescribeSetting("use-forwarded-headers", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should not trust X-Forwarded headers when setting is false", func() {
|
||||
host := "forwarded-headers"
|
||||
host := forwardedHeadersHost
|
||||
|
||||
f.UpdateNginxConfigMapData(setting, "false")
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,10 @@ package settings
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"net/http"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
|
|
@ -55,7 +54,7 @@ var _ = framework.DescribeSetting("Geoip2", func() {
|
|||
})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags")
|
||||
|
||||
filename := fmt.Sprintf("/etc/nginx/geoip/%s.mmdb", edition)
|
||||
filename := fmt.Sprintf("/etc/ingress-controller/geoip/%s.mmdb", edition)
|
||||
exec, err := f.ExecIngressPod(fmt.Sprintf(`sh -c "mkdir -p '%s' && wget -O '%s' '%s' 2>&1"`, filepath.Dir(filename), filename, testdataURL))
|
||||
framework.Logf(exec)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, fmt.Sprintln("error downloading test geoip2 db", filename))
|
||||
|
|
@ -70,10 +69,17 @@ var _ = framework.DescribeSetting("Geoip2", func() {
|
|||
ginkgo.It("should only allow requests from specific countries", func() {
|
||||
ginkgo.Skip("GeoIP test are temporarily disabled")
|
||||
|
||||
f.UpdateNginxConfigMapData("use-geoip2", "true")
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
"use-geoip2": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
|
||||
httpSnippetAllowingOnlyAustralia :=
|
||||
`map $geoip2_city_country_code $blocked_country {
|
||||
httpSnippetAllowingOnlyAustralia := `map $geoip2_city_country_code $blocked_country {
|
||||
default 1;
|
||||
AU 0;
|
||||
}`
|
||||
|
|
@ -85,8 +91,7 @@ var _ = framework.DescribeSetting("Geoip2", func() {
|
|||
return strings.Contains(cfg, "map $geoip2_city_country_code $blocked_country")
|
||||
})
|
||||
|
||||
configSnippet :=
|
||||
`if ($blocked_country) {
|
||||
configSnippet := `if ($blocked_country) {
|
||||
return 403;
|
||||
}`
|
||||
|
||||
|
|
@ -119,4 +124,52 @@ var _ = framework.DescribeSetting("Geoip2", func() {
|
|||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
|
||||
ginkgo.It("should up and running nginx controller using autoreload flag", func() {
|
||||
edition := "GeoLite2-Country"
|
||||
|
||||
err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error {
|
||||
args := deployment.Spec.Template.Spec.Containers[0].Args
|
||||
args = append(args, "--maxmind-edition-ids="+edition)
|
||||
deployment.Spec.Template.Spec.Containers[0].Args = args
|
||||
_, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{})
|
||||
return err
|
||||
})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags")
|
||||
|
||||
filename := fmt.Sprintf("/etc/ingress-controller/geoip/%s.mmdb", edition)
|
||||
exec, err := f.ExecIngressPod(fmt.Sprintf(`sh -c "mkdir -p '%s' && wget -O '%s' '%s' 2>&1"`, filepath.Dir(filename), filename, testdataURL))
|
||||
framework.Logf(exec)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, fmt.Sprintln("error downloading test geoip2 db", filename))
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"use-geoip2": "true",
|
||||
"geoip2-autoreload-in-minutes": "5",
|
||||
})
|
||||
|
||||
// Check Configmap Autoreload Patterns
|
||||
f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, fmt.Sprintf("geoip2 %s", filename)) &&
|
||||
strings.Contains(cfg, "auto_reload 5m;")
|
||||
},
|
||||
)
|
||||
|
||||
// Check if Nginx could up, running and routing with auto_reload configs
|
||||
host := "ping.com"
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, host) &&
|
||||
strings.Contains(server, "location /")
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const (
|
||||
disable = "false"
|
||||
noAuthLocaltionSetting = "no-auth-locations"
|
||||
)
|
||||
|
||||
var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
||||
f := framework.NewDefaultFramework(
|
||||
"global-external-auth",
|
||||
|
|
@ -46,7 +51,7 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
fooPath := "/foo"
|
||||
barPath := "/bar"
|
||||
|
||||
noAuthSetting := "no-auth-locations"
|
||||
noAuthSetting := noAuthLocaltionSetting
|
||||
noAuthLocations := barPath
|
||||
|
||||
enableGlobalExternalAuthAnnotation := "nginx.ingress.kubernetes.io/enable-global-auth"
|
||||
|
|
@ -56,7 +61,6 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
})
|
||||
|
||||
ginkgo.Context("when global external authentication is configured", func() {
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
globalExternalAuthURL := fmt.Sprintf("http://%s.%s.svc.cluster.local:80/status/401", framework.HTTPBunService, f.Namespace)
|
||||
|
||||
|
|
@ -85,7 +89,6 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 401 when request any protected service", func() {
|
||||
|
||||
ginkgo.By("Sending a request to protected service /foo")
|
||||
f.HTTPTestClient().
|
||||
GET(fooPath).
|
||||
|
|
@ -102,7 +105,6 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 200 when request whitelisted (via no-auth-locations) service and 401 when request protected service", func() {
|
||||
|
||||
ginkgo.By("Adding a no-auth-locations for /bar to configMap")
|
||||
f.UpdateNginxConfigMapData(noAuthSetting, noAuthLocations)
|
||||
f.WaitForNginxServer(host,
|
||||
|
|
@ -126,10 +128,9 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should return status code 200 when request whitelisted (via ingress annotation) service and 401 when request protected service", func() {
|
||||
|
||||
ginkgo.By("Adding an ingress rule for /bar with annotation enable-global-auth = false")
|
||||
err := framework.UpdateIngress(f.KubeClientSet, f.Namespace, "bar-ingress", func(ingress *networking.Ingress) error {
|
||||
ingress.ObjectMeta.Annotations[enableGlobalExternalAuthAnnotation] = "false"
|
||||
ingress.ObjectMeta.Annotations[enableGlobalExternalAuthAnnotation] = disable
|
||||
return nil
|
||||
})
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
|
|
@ -155,9 +156,8 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should still return status code 200 after auth backend is deleted using cache", func() {
|
||||
|
||||
globalExternalAuthCacheKeySetting := "global-auth-cache-key"
|
||||
globalExternalAuthCacheKey := "foo"
|
||||
globalExternalAuthCacheKey := fooHost
|
||||
globalExternalAuthCacheDurationSetting := "global-auth-cache-duration"
|
||||
globalExternalAuthCacheDuration := "200 201 401 30m"
|
||||
globalExternalAuthURL := fmt.Sprintf("http://%s.%s.svc.cluster.local:80/status/200", framework.HTTPBunService, f.Namespace)
|
||||
|
|
@ -197,7 +197,6 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`should proxy_method method when global-auth-method is configured`, func() {
|
||||
|
||||
globalExternalAuthMethodSetting := "global-auth-method"
|
||||
globalExternalAuthMethod := "GET"
|
||||
|
||||
|
|
@ -210,7 +209,6 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`should add custom error page when global-auth-signin url is configured`, func() {
|
||||
|
||||
globalExternalAuthSigninSetting := "global-auth-signin"
|
||||
globalExternalAuthSignin := "http://foo.com/global-error-page"
|
||||
|
||||
|
|
@ -223,7 +221,6 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`should add auth headers when global-auth-response-headers is configured`, func() {
|
||||
|
||||
globalExternalAuthResponseHeadersSetting := "global-auth-response-headers"
|
||||
globalExternalAuthResponseHeaders := "Foo, Bar"
|
||||
|
||||
|
|
@ -237,7 +234,6 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`should set request-redirect when global-auth-request-redirect is configured`, func() {
|
||||
|
||||
globalExternalAuthRequestRedirectSetting := "global-auth-request-redirect"
|
||||
globalExternalAuthRequestRedirect := "Foo-Redirect"
|
||||
|
||||
|
|
@ -260,7 +256,6 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() {
|
|||
return strings.Contains(server, globalExternalAuthSnippet)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
ginkgo.Context("cookie set by external authentication server", func() {
|
||||
|
|
@ -322,7 +317,6 @@ http {
|
|||
f.WaitForNginxServer(host, func(server string) bool {
|
||||
return strings.Contains(server, "server_name "+host)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
ginkgo.It("user retains cookie by default", func() {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ var _ = framework.IngressNginxDescribe("global-options", func() {
|
|||
ginkgo.It("should have worker_rlimit_nofile option", func() {
|
||||
f.WaitForNginxConfiguration(func(server string) bool {
|
||||
return strings.Contains(server, fmt.Sprintf("worker_rlimit_nofile %d;", rlimitMaxNumFiles()-1024))
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
110
test/e2e/settings/grpc.go
Normal file
110
test/e2e/settings/grpc.go
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Copyright 2024 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
pb "github.com/moul/pb/grpcbin/go-grpc"
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const echoHost = "echo"
|
||||
|
||||
var _ = framework.DescribeSetting("GRPC", func() {
|
||||
f := framework.NewDefaultFramework("grpc-buffersize", framework.WithHTTPBunEnabled())
|
||||
|
||||
ginkgo.It("should set the correct GRPC Buffer Size", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"grpc-buffer-size-kb": "8",
|
||||
})
|
||||
|
||||
f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, "grpc_buffer_size 8k")
|
||||
})
|
||||
|
||||
f.NewGRPCBinDeployment()
|
||||
|
||||
host := echoHost
|
||||
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "grpcbin-test",
|
||||
Namespace: f.Namespace,
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
ExternalName: fmt.Sprintf("grpcbin.%v.svc.cluster.local", f.Namespace),
|
||||
Type: corev1.ServiceTypeExternalName,
|
||||
Ports: []corev1.ServicePort{
|
||||
{
|
||||
Name: host,
|
||||
Port: 9000,
|
||||
TargetPort: intstr.FromInt(9000),
|
||||
Protocol: "TCP",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
f.EnsureService(svc)
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "GRPC",
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, "grpcbin-test", 9000, annotations)
|
||||
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "grpc_pass grpc://upstream_balancer;")
|
||||
})
|
||||
|
||||
conn, err := grpc.Dial(f.GetNginxIP()+":443",
|
||||
grpc.WithTransportCredentials(
|
||||
credentials.NewTLS(&tls.Config{
|
||||
ServerName: echoHost,
|
||||
InsecureSkipVerify: true, //nolint:gosec // Ignore certificate validation in testing
|
||||
}),
|
||||
),
|
||||
)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "error creating a connection")
|
||||
defer conn.Close()
|
||||
|
||||
client := pb.NewGRPCBinClient(conn)
|
||||
ctx := context.Background()
|
||||
|
||||
res, err := client.HeadersUnary(ctx, &pb.EmptyMessage{})
|
||||
assert.Nil(ginkgo.GinkgoT(), err)
|
||||
|
||||
metadata := res.GetMetadata()
|
||||
assert.Equal(ginkgo.GinkgoT(), metadata["content-type"].Values[0], "application/grpc")
|
||||
assert.Equal(ginkgo.GinkgoT(), metadata[":authority"].Values[0], host)
|
||||
})
|
||||
})
|
||||
|
|
@ -18,6 +18,7 @@ package settings
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
|
|
@ -29,11 +30,27 @@ import (
|
|||
var _ = framework.DescribeSetting("gzip", func() {
|
||||
f := framework.NewDefaultFramework("gzip")
|
||||
|
||||
host := "gzip"
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
f.NewHttpbunDeployment()
|
||||
f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBunService, 80, nil))
|
||||
})
|
||||
|
||||
ginkgo.It("should be disabled by default", func() {
|
||||
f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return !strings.Contains(cfg, "gzip on;")
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/xml").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Accept-Encoding", "gzip").
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
ContentEncoding()
|
||||
})
|
||||
|
||||
ginkgo.It("should be enabled with default settings", func() {
|
||||
|
|
@ -50,7 +67,16 @@ var _ = framework.DescribeSetting("gzip", func() {
|
|||
strings.Contains(cfg, fmt.Sprintf("gzip_types %s;", defaultCfg.GzipTypes)) &&
|
||||
strings.Contains(cfg, "gzip_proxied any;") &&
|
||||
strings.Contains(cfg, "gzip_vary on;")
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/xml").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Accept-Encoding", "gzip").
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
ContentEncoding("gzip")
|
||||
})
|
||||
|
||||
ginkgo.It("should set gzip_comp_level to 4", func() {
|
||||
|
|
@ -61,7 +87,16 @@ var _ = framework.DescribeSetting("gzip", func() {
|
|||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, "gzip on;") &&
|
||||
strings.Contains(cfg, "gzip_comp_level 4;")
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/xml").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Accept-Encoding", "gzip").
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
ContentEncoding("gzip")
|
||||
})
|
||||
|
||||
ginkgo.It("should set gzip_disable to msie6", func() {
|
||||
|
|
@ -72,28 +107,87 @@ var _ = framework.DescribeSetting("gzip", func() {
|
|||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, "gzip on;") &&
|
||||
strings.Contains(cfg, `gzip_disable "msie6";`)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/xml").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Accept-Encoding", "gzip").
|
||||
WithHeader("User-Agent", "Mozilla/4.8 [en] (Windows NT 5.1; U)").
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
ContentEncoding("gzip")
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/xml").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Accept-Encoding", "gzip").
|
||||
WithHeader("User-Agent", "Mozilla/45.0 (compatible; MSIE 6.0; Windows NT 5.1)").
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
ContentEncoding()
|
||||
})
|
||||
|
||||
ginkgo.It("should set gzip_min_length to 100", func() {
|
||||
f.UpdateNginxConfigMapData("use-gzip", "true")
|
||||
f.UpdateNginxConfigMapData("gzip-min-length", "100")
|
||||
f.UpdateNginxConfigMapData("gzip-types", "application/octet-stream")
|
||||
|
||||
f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, "gzip on;") &&
|
||||
strings.Contains(cfg, "gzip_min_length 100;")
|
||||
})
|
||||
strings.Contains(cfg, "gzip_min_length 100;") &&
|
||||
strings.Contains(cfg, "gzip_types application/octet-stream;")
|
||||
},
|
||||
)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/bytes/99").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Accept-Encoding", "gzip").
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
ContentType("application/octet-stream").
|
||||
ContentEncoding()
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/bytes/100").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Accept-Encoding", "gzip").
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
ContentType("application/octet-stream").
|
||||
ContentEncoding("gzip")
|
||||
})
|
||||
|
||||
ginkgo.It("should set gzip_types to application/javascript", func() {
|
||||
ginkgo.It("should set gzip_types to text/html", func() {
|
||||
f.UpdateNginxConfigMapData("use-gzip", "true")
|
||||
f.UpdateNginxConfigMapData("gzip-types", "application/javascript")
|
||||
f.UpdateNginxConfigMapData("gzip-types", "text/html")
|
||||
|
||||
f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, "gzip on;") &&
|
||||
strings.Contains(cfg, "gzip_types application/javascript;")
|
||||
})
|
||||
strings.Contains(cfg, "gzip_types text/html;")
|
||||
},
|
||||
)
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/xml").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Accept-Encoding", "gzip").
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
ContentType("application/xml").
|
||||
ContentEncoding()
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/html").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("Accept-Encoding", "gzip").
|
||||
Expect().
|
||||
Status(http.StatusOK).
|
||||
ContentType("text/html").
|
||||
ContentEncoding("gzip")
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ var _ = framework.DescribeSetting("hash size", func() {
|
|||
})
|
||||
|
||||
ginkgo.Context("Check server names hash size", func() {
|
||||
|
||||
ginkgo.It("should set server_names_hash_bucket_size", func() {
|
||||
f.UpdateNginxConfigMapData("server-name-hash-bucket-size", "512")
|
||||
|
||||
|
|
@ -52,11 +51,9 @@ var _ = framework.DescribeSetting("hash size", func() {
|
|||
return strings.Contains(server, "server_names_hash_max_size 4096;")
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
ginkgo.Context("Check proxy header hash size", func() {
|
||||
|
||||
ginkgo.It("should set proxy-headers-hash-bucket-size", func() {
|
||||
f.UpdateNginxConfigMapData("proxy-headers-hash-bucket-size", "512")
|
||||
|
||||
|
|
@ -72,11 +69,9 @@ var _ = framework.DescribeSetting("hash size", func() {
|
|||
return strings.Contains(server, "proxy_headers_hash_max_size 4096;")
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
ginkgo.Context("Check the variable hash size", func() {
|
||||
|
||||
ginkgo.It("should set variables-hash-bucket-size", func() {
|
||||
f.UpdateNginxConfigMapData("variables-hash-bucket-size", "512")
|
||||
|
||||
|
|
@ -92,11 +87,9 @@ var _ = framework.DescribeSetting("hash size", func() {
|
|||
return strings.Contains(server, "variables_hash_max_size 512;")
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
ginkgo.Context("Check the map hash size", func() {
|
||||
|
||||
ginkgo.It("should set vmap-hash-bucket-size", func() {
|
||||
f.UpdateNginxConfigMapData("map-hash-bucket-size", "512")
|
||||
|
||||
|
|
@ -104,7 +97,5 @@ var _ = framework.DescribeSetting("hash size", func() {
|
|||
return strings.Contains(server, "map_hash_bucket_size 512;")
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const barHost = "bar"
|
||||
|
||||
var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
||||
f := framework.NewDefaultFramework("ingress-class")
|
||||
|
||||
|
|
@ -66,7 +68,7 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
|
||||
ginkgo.Context("With default ingress class config", func() {
|
||||
ginkgo.It("should ignore Ingress with a different class annotation", func() {
|
||||
invalidHost := "foo"
|
||||
invalidHost := fooHost
|
||||
annotations := map[string]string{
|
||||
ingressclass.IngressKey: "testclass",
|
||||
}
|
||||
|
|
@ -75,7 +77,7 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
ing.Spec.IngressClassName = nil
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
validHost := "bar"
|
||||
validHost := barHost
|
||||
annotationClass := map[string]string{
|
||||
ingressclass.IngressKey: ingressclass.DefaultAnnotationValue,
|
||||
}
|
||||
|
|
@ -385,7 +387,6 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
ginkgo.Context("With specific ingress-class flags", func() {
|
||||
|
|
@ -411,13 +412,13 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should ignore Ingress with no class and accept the correctly configured Ingresses", func() {
|
||||
invalidHost := "bar"
|
||||
invalidHost := barHost
|
||||
|
||||
ing := framework.NewSingleIngress(invalidHost, "/", invalidHost, f.Namespace, framework.EchoService, 80, nil)
|
||||
ing.Spec.IngressClassName = nil
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
validHost := "foo"
|
||||
validHost := fooHost
|
||||
annotations := map[string]string{
|
||||
ingressclass.IngressKey: "testclass",
|
||||
}
|
||||
|
|
@ -455,7 +456,6 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
ginkgo.Context("With watch-ingress-without-class flag", func() {
|
||||
|
|
@ -480,13 +480,13 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should watch Ingress with no class and ignore ingress with a different class", func() {
|
||||
validHost := "bar"
|
||||
validHost := barHost
|
||||
|
||||
ing := framework.NewSingleIngress(validHost, "/", validHost, f.Namespace, framework.EchoService, 80, nil)
|
||||
ing.Spec.IngressClassName = nil
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
invalidHost := "foo"
|
||||
invalidHost := fooHost
|
||||
annotations := map[string]string{
|
||||
ingressclass.IngressKey: "testclass123",
|
||||
}
|
||||
|
|
@ -511,7 +511,6 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
ginkgo.Context("With ingress-class-by-name flag", func() {
|
||||
|
|
@ -579,11 +578,9 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
ginkgo.Context("Without IngressClass Cluster scoped Permission", func() {
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
icname := fmt.Sprintf("ic-%s", f.Namespace)
|
||||
|
||||
|
|
@ -629,8 +626,7 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should watch Ingress with correct annotation", func() {
|
||||
|
||||
validHost := "foo"
|
||||
validHost := fooHost
|
||||
annotations := map[string]string{
|
||||
ingressclass.IngressKey: "testclass",
|
||||
}
|
||||
|
|
@ -650,7 +646,6 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should ignore Ingress with only IngressClassName", func() {
|
||||
|
||||
invalidHost := "noclassforyou"
|
||||
|
||||
ing := framework.NewSingleIngress(invalidHost, "/", invalidHost, f.Namespace, framework.EchoService, 80, nil)
|
||||
|
|
@ -666,6 +661,5 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() {
|
|||
Expect().
|
||||
Status(http.StatusNotFound)
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
|
|
@ -50,7 +51,6 @@ var _ = framework.DescribeSetting("keep-alive keep-alive-requests", func() {
|
|||
f.WaitForNginxConfiguration(func(server string) bool {
|
||||
return strings.Contains(server, `keepalive_requests 200;`)
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -59,7 +59,8 @@ var _ = framework.DescribeSetting("keep-alive keep-alive-requests", func() {
|
|||
f.UpdateNginxConfigMapData("upstream-keepalive-connections", "128")
|
||||
|
||||
f.WaitForNginxConfiguration(func(server string) bool {
|
||||
match, _ := regexp.MatchString(`upstream\supstream_balancer\s\{[\s\S]*keepalive 128;`, server)
|
||||
match, err := regexp.MatchString(`upstream\supstream_balancer\s\{[\s\S]*keepalive 128;`, server)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "unexpected error matching the upstream keepalive time")
|
||||
return match
|
||||
})
|
||||
})
|
||||
|
|
@ -68,7 +69,8 @@ var _ = framework.DescribeSetting("keep-alive keep-alive-requests", func() {
|
|||
f.UpdateNginxConfigMapData("upstream-keepalive-timeout", "120")
|
||||
|
||||
f.WaitForNginxConfiguration(func(server string) bool {
|
||||
match, _ := regexp.MatchString(`upstream\supstream_balancer\s\{[\s\S]*keepalive_timeout\s*120s;`, server)
|
||||
match, err := regexp.MatchString(`upstream\supstream_balancer\s\{[\s\S]*keepalive_timeout\s*120s;`, server)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "unexpected error matching the upstream keepalive time")
|
||||
return match
|
||||
})
|
||||
})
|
||||
|
|
@ -77,7 +79,8 @@ var _ = framework.DescribeSetting("keep-alive keep-alive-requests", func() {
|
|||
f.UpdateNginxConfigMapData("upstream-keepalive-time", "75s")
|
||||
|
||||
f.WaitForNginxConfiguration(func(server string) bool {
|
||||
match, _ := regexp.MatchString(`upstream\supstream_balancer\s\{[\s\S]*keepalive_time\s*75s;`, server)
|
||||
match, err := regexp.MatchString(`upstream\supstream_balancer\s\{[\s\S]*keepalive_time\s*75s;`, server)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "unexpected error matching the upstream keepalive time")
|
||||
return match
|
||||
})
|
||||
})
|
||||
|
|
@ -86,7 +89,8 @@ var _ = framework.DescribeSetting("keep-alive keep-alive-requests", func() {
|
|||
f.UpdateNginxConfigMapData("upstream-keepalive-requests", "200")
|
||||
|
||||
f.WaitForNginxConfiguration(func(server string) bool {
|
||||
match, _ := regexp.MatchString(`upstream\supstream_balancer\s\{[\s\S]*keepalive_requests\s*200;`, server)
|
||||
match, err := regexp.MatchString(`upstream\supstream_balancer\s\{[\s\S]*keepalive_requests\s*200;`, server)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "unexpected error matching the upstream keepalive time")
|
||||
return match
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import (
|
|||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("[Flag] custom HTTP and HTTPS ports", func() {
|
||||
|
||||
host := "forwarded-headers"
|
||||
|
||||
f := framework.NewDefaultFramework("forwarded-port-headers", framework.WithHTTPBunEnabled())
|
||||
|
|
@ -44,7 +43,6 @@ var _ = framework.IngressNginxDescribe("[Flag] custom HTTP and HTTPS ports", fun
|
|||
|
||||
ginkgo.Context("with a plain HTTP ingress", func() {
|
||||
ginkgo.It("should set X-Forwarded-Port headers accordingly when listening on a non-default HTTP port", func() {
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
|
|
@ -64,9 +62,7 @@ var _ = framework.IngressNginxDescribe("[Flag] custom HTTP and HTTPS ports", fun
|
|||
})
|
||||
|
||||
ginkgo.Context("with a TLS enabled ingress", func() {
|
||||
|
||||
ginkgo.It("should set X-Forwarded-Port header to 443", func() {
|
||||
|
||||
ing := framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
|
|
@ -94,7 +90,6 @@ var _ = framework.IngressNginxDescribe("[Flag] custom HTTP and HTTPS ports", fun
|
|||
})
|
||||
|
||||
ginkgo.Context("when external authentication is configured", func() {
|
||||
|
||||
ginkgo.It("should set the X-Forwarded-Port header to 443", func() {
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", f.HTTPBunIP),
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ var _ = framework.DescribeSetting("log-format-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.Context("Check log-format-escape-json and log-format-escape-none", func() {
|
||||
|
||||
ginkgo.It("should not configure log-format escape by default", func() {
|
||||
f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
|
|
@ -78,7 +77,6 @@ var _ = framework.DescribeSetting("log-format-*", func() {
|
|||
})
|
||||
|
||||
ginkgo.Context("Check log-format-upstream with log-format-escape-json and log-format-escape-none", func() {
|
||||
|
||||
ginkgo.It("log-format-escape-json enabled", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"log-format-escape-json": "true",
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ import (
|
|||
|
||||
var _ = framework.IngressNginxDescribeSerial("[Flag] watch namespace selector", func() {
|
||||
f := framework.NewDefaultFramework("namespace-selector")
|
||||
notMatchedHost, matchedHost := "bar", "foo"
|
||||
notMatchedHost, matchedHost := barHost, fooHost
|
||||
var notMatchedNs string
|
||||
var matchedNs string
|
||||
|
||||
// create a test namespace, under which create an ingress and backend deployment
|
||||
prepareTestIngress := func(baseName string, host string, labels map[string]string) string {
|
||||
prepareTestIngress := func(host string, labels map[string]string) string {
|
||||
ns, err := framework.CreateKubeNamespaceWithLabel(f.BaseName, labels, f.KubeClientSet)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "creating test namespace")
|
||||
f.NewEchoDeployment(framework.WithDeploymentNamespace(ns))
|
||||
|
|
@ -49,8 +49,8 @@ var _ = framework.IngressNginxDescribeSerial("[Flag] watch namespace selector",
|
|||
}
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
notMatchedNs = prepareTestIngress(notMatchedHost, notMatchedHost, nil) // create namespace without label "foo=bar"
|
||||
matchedNs = prepareTestIngress(matchedHost, matchedHost, map[string]string{"foo": "bar"})
|
||||
notMatchedNs = prepareTestIngress(notMatchedHost, nil) // create namespace without label "foo=bar"
|
||||
matchedNs = prepareTestIngress(matchedHost, map[string]string{fooHost: barHost})
|
||||
})
|
||||
|
||||
ginkgo.AfterEach(func() {
|
||||
|
|
@ -59,9 +59,7 @@ var _ = framework.IngressNginxDescribeSerial("[Flag] watch namespace selector",
|
|||
})
|
||||
|
||||
ginkgo.Context("With specific watch-namespace-selector flags", func() {
|
||||
|
||||
ginkgo.It("should ingore Ingress of namespace without label foo=bar and accept those of namespace with label foo=bar", func() {
|
||||
|
||||
ginkgo.It("should ignore Ingress of namespace without label foo=bar and accept those of namespace with label foo=bar", func() {
|
||||
f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||
return !strings.Contains(cfg, "server_name bar") &&
|
||||
strings.Contains(cfg, "server_name foo")
|
||||
|
|
@ -86,7 +84,7 @@ var _ = framework.IngressNginxDescribeSerial("[Flag] watch namespace selector",
|
|||
if ns.Labels == nil {
|
||||
ns.Labels = make(map[string]string)
|
||||
}
|
||||
ns.Labels["foo"] = "bar"
|
||||
ns.Labels[fooHost] = barHost
|
||||
|
||||
_, err = f.KubeClientSet.CoreV1().Namespaces().Update(context.TODO(), ns, metav1.UpdateOptions{})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "labeling not matched namespace")
|
||||
|
|
@ -97,7 +95,7 @@ var _ = framework.IngressNginxDescribeSerial("[Flag] watch namespace selector",
|
|||
if ing.Labels == nil {
|
||||
ing.Labels = make(map[string]string)
|
||||
}
|
||||
ing.Labels["foo"] = "bar"
|
||||
ing.Labels[fooHost] = barHost
|
||||
|
||||
_, err = f.KubeClientSet.NetworkingV1().Ingresses(notMatchedNs).Update(context.TODO(), ing, metav1.UpdateOptions{})
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "updating ingress")
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ package settings
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
networking "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -34,7 +34,7 @@ var _ = framework.DescribeSetting("[Security] no-auth-locations", func() {
|
|||
f := framework.NewDefaultFramework("no-auth-locations")
|
||||
|
||||
setting := "no-auth-locations"
|
||||
username := "foo"
|
||||
username := fooHost
|
||||
password := "bar"
|
||||
secretName := "test-secret"
|
||||
host := "no-auth-locations"
|
||||
|
|
@ -100,7 +100,8 @@ func buildBasicAuthIngressWithSecondPath(host, namespace, secretName, pathName s
|
|||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: namespace,
|
||||
Annotations: map[string]string{"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||
"nginx.ingress.kubernetes.io/auth-secret": secretName,
|
||||
"nginx.ingress.kubernetes.io/auth-realm": "test auth",
|
||||
},
|
||||
|
|
@ -147,7 +148,6 @@ func buildBasicAuthIngressWithSecondPath(host, namespace, secretName, pathName s
|
|||
}
|
||||
|
||||
func buildSecret(username, password, name, namespace string) *corev1.Secret {
|
||||
//out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput()
|
||||
out, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "creating password")
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,5 @@ var _ = framework.DescribeSetting("Add no tls redirect locations", func() {
|
|||
f.WaitForNginxConfiguration(func(server string) bool {
|
||||
return strings.Contains(server, "force_no_ssl_redirect = true,")
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue