Merge branch 'master' into xff
This commit is contained in:
commit
b5bcb93a4b
1532 changed files with 65966 additions and 34963 deletions
|
|
@ -21,7 +21,6 @@
|
|||
"bodySize": "1m",
|
||||
"enableDynamicTlsRecords": true,
|
||||
"enableSpdy": false,
|
||||
"enableVtsStatus": true,
|
||||
"errorLogLevel": "notice",
|
||||
"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/plain text/x-component",
|
||||
"hsts": true,
|
||||
|
|
@ -46,7 +45,6 @@
|
|||
"useGzip": true,
|
||||
"useHttp2": true,
|
||||
"proxyStreamTimeout": "600s",
|
||||
"vtsStatusZoneSize": "10m",
|
||||
"workerProcesses": 1,
|
||||
"limitConnZoneVariable": "$the_real_ip"
|
||||
},
|
||||
|
|
@ -117,9 +115,7 @@
|
|||
"keyFilename": "",
|
||||
"caFilename": "",
|
||||
"pemSha": ""
|
||||
},
|
||||
"vtsDefaultFilterKey": "$uri $server_name"
|
||||
|
||||
}
|
||||
}, {
|
||||
"path": "/",
|
||||
"isDefBackend": true,
|
||||
|
|
|
|||
|
|
@ -32,11 +32,15 @@ import (
|
|||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
// TODO(elvinefendi) merge this with Affinity tests in test/e2e/lua/dynamic_configuration.go
|
||||
var _ = framework.IngressNginxDescribe("Annotations - Affinity", func() {
|
||||
f := framework.NewDefaultFramework("affinity")
|
||||
|
||||
BeforeEach(func() {
|
||||
err := f.NewEchoDeploymentWithReplicas(2)
|
||||
err := f.DisableDynamicConfiguration()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = f.NewEchoDeploymentWithReplicas(2)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
|
|
@ -105,7 +109,6 @@ var _ = framework.IngressNginxDescribe("Annotations - Affinity", func() {
|
|||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/affinity": "cookie",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-name": "SERVERID",
|
||||
"nginx.ingress.kubernetes.io/rewrite-target": "/something",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
|
|
@ -146,7 +149,120 @@ var _ = framework.IngressNginxDescribe("Annotations - Affinity", func() {
|
|||
|
||||
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||
Expect(body).Should(ContainSubstring(fmt.Sprintf("request_uri=http://%v:8080/something/", host)))
|
||||
Expect(body).Should(ContainSubstring(fmt.Sprintf("request_uri=http://%v:8080/", host)))
|
||||
Expect(resp.Header.Get("Set-Cookie")).Should(ContainSubstring("SERVERID="))
|
||||
})
|
||||
|
||||
It("should set the path to /something on the generated cookie", func() {
|
||||
host := "example.com"
|
||||
|
||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/affinity": "cookie",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-name": "SERVERID",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/something",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "proxy_pass http://sticky-"+f.IngressController.Namespace+"-http-svc-80;")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL+"/something").
|
||||
Set("Host", host).
|
||||
End()
|
||||
|
||||
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||
Expect(resp.Header.Get("Set-Cookie")).Should(ContainSubstring("Path=/something"))
|
||||
})
|
||||
|
||||
It("should set the path to / on the generated cookie if there's more than one rule referring to the same backend", func() {
|
||||
host := "example.com"
|
||||
|
||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/affinity": "cookie",
|
||||
"nginx.ingress.kubernetes.io/session-cookie-name": "SERVERID",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/something",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
{
|
||||
Path: "/somewhereelese",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "proxy_pass http://sticky-"+f.IngressController.Namespace+"-http-svc-80;")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL+"/something").
|
||||
Set("Host", host).
|
||||
End()
|
||||
|
||||
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||
Expect(resp.Header.Get("Set-Cookie")).Should(ContainSubstring("Path=/;"))
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package annotations
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
|
|
@ -27,7 +28,9 @@ import (
|
|||
"github.com/parnurzeal/gorequest"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
|
@ -265,6 +268,77 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
|||
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
|
||||
Context("when external authentication is configured", func() {
|
||||
host := "auth"
|
||||
|
||||
BeforeEach(func() {
|
||||
err := f.NewHttpbinDeployment()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var httpbinIP string
|
||||
err = wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
|
||||
e, err := f.KubeClientSet.CoreV1().Endpoints(f.IngressController.Namespace).Get("httpbin", metav1.GetOptions{})
|
||||
if errors.IsNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if len(e.Subsets) < 1 || len(e.Subsets[0].Addresses) < 1 {
|
||||
return false, nil
|
||||
}
|
||||
httpbinIP = e.Subsets[0].Addresses[0].IP
|
||||
return true, nil
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
bi, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbinIP),
|
||||
"nginx.ingress.kubernetes.io/auth-signin": "http://$host/auth/start",
|
||||
}))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(bi).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host, func(server string) bool {
|
||||
return Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should return status code 200 when signed in", func() {
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL).
|
||||
Retry(10, 1*time.Second, http.StatusNotFound).
|
||||
Set("Host", host).
|
||||
SetBasicAuth("user", "password").
|
||||
End()
|
||||
|
||||
for _, err := range errs {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||
})
|
||||
|
||||
It("should redirect to signin url when not signed in", func() {
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL).
|
||||
Retry(10, 1*time.Second, http.StatusNotFound).
|
||||
Set("Host", host).
|
||||
RedirectPolicy(func(req gorequest.Request, via []gorequest.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}).
|
||||
Param("a", "b").
|
||||
Param("c", "d").
|
||||
End()
|
||||
|
||||
for _, err := range errs {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusFound))
|
||||
Expect(resp.Header.Get("Location")).Should(Equal(fmt.Sprintf("http://%s/auth/start?rd=http://%s%s", host, host, url.QueryEscape("/?a=b&c=d"))))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// TODO: test Digest Auth
|
||||
|
|
|
|||
292
test/e2e/annotations/clientbodybuffersize.go
Normal file
292
test/e2e/annotations/clientbodybuffersize.go
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
Copyright 2018 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 (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
v1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("Annotations - Client-Body-Buffer-Size", func() {
|
||||
f := framework.NewDefaultFramework("proxy")
|
||||
|
||||
BeforeEach(func() {
|
||||
err := f.NewEchoDeploymentWithReplicas(2)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
})
|
||||
|
||||
It("should set client_body_buffer_size to 1000", func() {
|
||||
host := "proxy.foo.com"
|
||||
|
||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/client-body-buffer-size": "1000",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1000;"))
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should set client_body_buffer_size to 1K", func() {
|
||||
host := "proxy.foo.com"
|
||||
|
||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/client-body-buffer-size": "1K",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1K;"))
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should set client_body_buffer_size to 1k", func() {
|
||||
host := "proxy.foo.com"
|
||||
|
||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/client-body-buffer-size": "1k",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1k;"))
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should set client_body_buffer_size to 1M", func() {
|
||||
host := "proxy.foo.com"
|
||||
|
||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/client-body-buffer-size": "1M",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1M;"))
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should set client_body_buffer_size to 1M", func() {
|
||||
host := "proxy.foo.com"
|
||||
|
||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/client-body-buffer-size": "1M",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1M;"))
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should not set client_body_buffer_size to invalid 1b", func() {
|
||||
host := "proxy.foo.com"
|
||||
|
||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/client-body-buffer-size": "1b",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return Expect(server).ShouldNot(ContainSubstring("client_body_buffer_size 1b;"))
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
|
@ -18,10 +18,12 @@ package annotations
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/parnurzeal/gorequest"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
|
@ -49,10 +51,23 @@ var _ = framework.IngressNginxDescribe("Annotations - custom default-backend", f
|
|||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return Expect(server).Should(ContainSubstring(fmt.Sprintf("server_name %v", host))) &&
|
||||
Expect(server).Should(ContainSubstring("proxy_pass http://custom-default-backend"))
|
||||
return Expect(server).Should(ContainSubstring(fmt.Sprintf("server_name %v", host)))
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
uri := "/alma/armud"
|
||||
resp, body, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL+uri).
|
||||
Set("Host", host).
|
||||
End()
|
||||
|
||||
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||
|
||||
Expect(body).To(ContainSubstring("x-code=503"))
|
||||
Expect(body).To(ContainSubstring(fmt.Sprintf("x-ingress-name=%s", host)))
|
||||
Expect(body).To(ContainSubstring("x-service-name=invalid"))
|
||||
Expect(body).To(ContainSubstring(fmt.Sprintf("x-original-uri=%s", uri)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ var _ = framework.IngressNginxDescribe("Annotations - grpc", func() {
|
|||
host := "grpc"
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/grpc-backend": "true",
|
||||
"nginx.ingress.kubernetes.io/backend-protocol": "GRPC",
|
||||
}
|
||||
ing, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "fortune-teller", 50051, &annotations))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
|
|
|||
121
test/e2e/annotations/redirect.go
Normal file
121
test/e2e/annotations/redirect.go
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
Copyright 2018 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"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/parnurzeal/gorequest"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
func noRedirectPolicyFunc(gorequest.Request, []gorequest.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
|
||||
var _ = framework.IngressNginxDescribe("Annotations - Redirect", func() {
|
||||
f := framework.NewDefaultFramework("redirect")
|
||||
|
||||
BeforeEach(func() {
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
})
|
||||
|
||||
It("should respond with a standard redirect code", func() {
|
||||
By("setting permanent-redirect annotation")
|
||||
|
||||
host := "redirect"
|
||||
redirectPath := "/something"
|
||||
redirectURL := "http://redirect.example.com"
|
||||
|
||||
annotations := map[string]string{"nginx.ingress.kubernetes.io/permanent-redirect": redirectURL}
|
||||
|
||||
ing := framework.NewSingleIngress(host, redirectPath, host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||
_, err := f.EnsureIngress(ing)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, fmt.Sprintf("if ($uri ~* %s) {", redirectPath)) &&
|
||||
strings.Contains(server, fmt.Sprintf("return 301 %s;", redirectURL))
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("sending request to redirected URL path")
|
||||
|
||||
resp, body, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL+redirectPath).
|
||||
Set("Host", host).
|
||||
RedirectPolicy(noRedirectPolicyFunc).
|
||||
End()
|
||||
|
||||
Expect(errs).To(BeNil())
|
||||
Expect(resp.StatusCode).Should(BeNumerically("==", http.StatusMovedPermanently))
|
||||
Expect(resp.Header.Get("Location")).Should(Equal(redirectURL))
|
||||
Expect(body).Should(ContainSubstring("nginx/"))
|
||||
})
|
||||
|
||||
It("should respond with a custom redirect code", func() {
|
||||
By("setting permanent-redirect-code annotation")
|
||||
|
||||
host := "redirect"
|
||||
redirectPath := "/something"
|
||||
redirectURL := "http://redirect.example.com"
|
||||
redirectCode := http.StatusFound
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/permanent-redirect": redirectURL,
|
||||
"nginx.ingress.kubernetes.io/permanent-redirect-code": strconv.Itoa(redirectCode),
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, redirectPath, host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||
_, err := f.EnsureIngress(ing)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, fmt.Sprintf("if ($uri ~* %s) {", redirectPath)) &&
|
||||
strings.Contains(server, fmt.Sprintf("return %d %s;", redirectCode, redirectURL))
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("sending request to redirected URL path")
|
||||
|
||||
resp, body, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL+redirectPath).
|
||||
Set("Host", host).
|
||||
RedirectPolicy(noRedirectPolicyFunc).
|
||||
End()
|
||||
|
||||
Expect(errs).To(BeNil())
|
||||
Expect(resp.StatusCode).Should(BeNumerically("==", redirectCode))
|
||||
Expect(resp.Header.Get("Location")).Should(Equal(redirectURL))
|
||||
Expect(body).Should(ContainSubstring("nginx/"))
|
||||
})
|
||||
})
|
||||
120
test/e2e/annotations/rewrite.go
Normal file
120
test/e2e/annotations/rewrite.go
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
Copyright 2017 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"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/parnurzeal/gorequest"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("Annotations - Rewrite", func() {
|
||||
f := framework.NewDefaultFramework("rewrite")
|
||||
|
||||
BeforeEach(func() {
|
||||
err := f.NewEchoDeploymentWithReplicas(1)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
})
|
||||
|
||||
It("should rewrite request URL", func() {
|
||||
By("setting rewrite-target annotation")
|
||||
|
||||
host := "rewrite.foo.com"
|
||||
annotations := map[string]string{"nginx.ingress.kubernetes.io/rewrite-target": "/"}
|
||||
expectBodyRequestURI := fmt.Sprintf("request_uri=http://%v:8080/", host)
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/something", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||
_, err := f.EnsureIngress(ing)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "rewrite (?i)/something/(.*) /$1 break;") &&
|
||||
strings.Contains(server, "rewrite (?i)/something / break;")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("sending request to Ingress rule path (lowercase)")
|
||||
|
||||
resp, body, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL+"/something").
|
||||
Set("Host", host).
|
||||
End()
|
||||
|
||||
Expect(len(errs)).Should(Equal(0))
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||
Expect(body).Should(ContainSubstring(expectBodyRequestURI))
|
||||
|
||||
By("sending request to Ingress rule path (mixed case)")
|
||||
|
||||
resp, body, errs = gorequest.New().
|
||||
Get(f.IngressController.HTTPURL+"/SomeThing").
|
||||
Set("Host", host).
|
||||
End()
|
||||
|
||||
Expect(len(errs)).Should(Equal(0))
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||
Expect(body).Should(ContainSubstring(expectBodyRequestURI))
|
||||
})
|
||||
|
||||
It("should write rewrite logs", func() {
|
||||
By("setting enable-rewrite-log annotation")
|
||||
|
||||
host := "rewrite.bar.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/rewrite-target": "/",
|
||||
"nginx.ingress.kubernetes.io/enable-rewrite-log": "true",
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/something", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||
_, err := f.EnsureIngress(ing)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "rewrite_log on;")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL+"/something").
|
||||
Set("Host", host).
|
||||
End()
|
||||
|
||||
Expect(len(errs)).Should(Equal(0))
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||
|
||||
logs, err := f.NginxLogs()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(logs).To(ContainSubstring(`"(?i)/something" matches "/something", client:`))
|
||||
Expect(logs).To(ContainSubstring(`rewritten data: "/", args: "",`))
|
||||
})
|
||||
})
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
Copyright 2017 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 (
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/parnurzeal/gorequest"
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("Annotations - Rewrite Log", func() {
|
||||
f := framework.NewDefaultFramework("rewrite-log")
|
||||
|
||||
BeforeEach(func() {
|
||||
err := f.NewEchoDeploymentWithReplicas(2)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
})
|
||||
|
||||
It("should write rewrite logs", func() {
|
||||
host := "rewrite.bar.com"
|
||||
|
||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
Annotations: map[string]string{
|
||||
"nginx.ingress.kubernetes.io/rewrite-target": "/",
|
||||
"nginx.ingress.kubernetes.io/enable-rewrite-log": "true",
|
||||
},
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: "/something",
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: "http-svc",
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "rewrite_log on;")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL+"/something").
|
||||
Set("Host", host).
|
||||
End()
|
||||
|
||||
Expect(len(errs)).Should(Equal(0))
|
||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
logs, err := f.NginxLogs()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(logs).To(ContainSubstring(`"/something" matches "/something", client:`))
|
||||
Expect(logs).To(ContainSubstring(`rewritten data: "/", args: "",`))
|
||||
})
|
||||
})
|
||||
1664
test/e2e/dind-cluster-v1.11.sh
Executable file
1664
test/e2e/dind-cluster-v1.11.sh
Executable file
File diff suppressed because it is too large
Load diff
23
test/e2e/down.sh
Executable file
23
test/e2e/down.sh
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 2017 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.
|
||||
|
||||
SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||
|
||||
export PATH="$HOME/.kubeadm-dind-cluster:$SCRIPT_ROOT/build:$PATH"
|
||||
|
||||
dind-cluster-v1.11.sh down
|
||||
dind-cluster-v1.11.sh clean
|
||||
|
||||
|
|
@ -33,6 +33,7 @@ import (
|
|||
_ "k8s.io/ingress-nginx/test/e2e/annotations"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/defaultbackend"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/lua"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/servicebackend"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/settings"
|
||||
_ "k8s.io/ingress-nginx/test/e2e/ssl"
|
||||
)
|
||||
|
|
@ -52,3 +53,9 @@ func RunE2ETests(t *testing.T) {
|
|||
glog.Infof("Starting e2e run %q on Ginkgo node %d", framework.RunID, config.GinkgoConfig.ParallelNode)
|
||||
ginkgo.RunSpecs(t, "nginx-ingress-controller e2e suite")
|
||||
}
|
||||
|
||||
var _ = ginkgo.SynchronizedAfterSuite(func() {
|
||||
// Run on all Ginkgo nodes
|
||||
framework.Logf("Running AfterSuite actions on all nodes")
|
||||
framework.RunCleanupActions()
|
||||
}, func() {})
|
||||
|
|
|
|||
|
|
@ -37,35 +37,45 @@ func (f *Framework) NewEchoDeployment() error {
|
|||
// NewEchoDeploymentWithReplicas creates a new deployment of the echoserver image in a particular namespace. Number of
|
||||
// replicas is configurable
|
||||
func (f *Framework) NewEchoDeploymentWithReplicas(replicas int32) error {
|
||||
return f.NewDeployment("http-svc", "gcr.io/kubernetes-e2e-test-images/echoserver:2.1", 8080, replicas)
|
||||
}
|
||||
|
||||
// NewHttpbinDeployment creates a new single replica deployment of the httpbin image in a particular namespace.
|
||||
func (f *Framework) NewHttpbinDeployment() error {
|
||||
return f.NewDeployment("httpbin", "kennethreitz/httpbin", 80, 1)
|
||||
}
|
||||
|
||||
// NewDeployment creates a new deployment in a particular namespace.
|
||||
func (f *Framework) NewDeployment(name, image string, port int32, replicas int32) error {
|
||||
deployment := &extensions.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "http-svc",
|
||||
Name: name,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
},
|
||||
Spec: extensions.DeploymentSpec{
|
||||
Replicas: NewInt32(replicas),
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"app": "http-svc",
|
||||
"app": name,
|
||||
},
|
||||
},
|
||||
Template: corev1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"app": "http-svc",
|
||||
"app": name,
|
||||
},
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
TerminationGracePeriodSeconds: NewInt64(0),
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "http-svc",
|
||||
Image: "gcr.io/google_containers/echoserver:1.10",
|
||||
Name: name,
|
||||
Image: image,
|
||||
Env: []corev1.EnvVar{},
|
||||
Ports: []corev1.ContainerPort{
|
||||
{
|
||||
Name: "http",
|
||||
ContainerPort: 8080,
|
||||
ContainerPort: port,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -81,7 +91,7 @@ func (f *Framework) NewEchoDeploymentWithReplicas(replicas int32) error {
|
|||
}
|
||||
|
||||
if d == nil {
|
||||
return fmt.Errorf("unexpected error creating deployement for echoserver")
|
||||
return fmt.Errorf("unexpected error creating deployement %s", name)
|
||||
}
|
||||
|
||||
err = WaitForPodsReady(f.KubeClientSet, 5*time.Minute, int(replicas), f.IngressController.Namespace, metav1.ListOptions{
|
||||
|
|
@ -93,7 +103,7 @@ func (f *Framework) NewEchoDeploymentWithReplicas(replicas int32) error {
|
|||
|
||||
service := &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "http-svc",
|
||||
Name: name,
|
||||
Namespace: f.IngressController.Namespace,
|
||||
},
|
||||
Spec: corev1.ServiceSpec{
|
||||
|
|
@ -101,12 +111,12 @@ func (f *Framework) NewEchoDeploymentWithReplicas(replicas int32) error {
|
|||
{
|
||||
Name: "http",
|
||||
Port: 80,
|
||||
TargetPort: intstr.FromInt(8080),
|
||||
TargetPort: intstr.FromInt(int(port)),
|
||||
Protocol: "TCP",
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{
|
||||
"app": "http-svc",
|
||||
"app": name,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -117,7 +127,7 @@ func (f *Framework) NewEchoDeploymentWithReplicas(replicas int32) error {
|
|||
}
|
||||
|
||||
if s == nil {
|
||||
return fmt.Errorf("unexpected error creating service for echoserver deployment")
|
||||
return fmt.Errorf("unexpected error creating service %s", name)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -50,22 +50,10 @@ func (f *Framework) ExecCommand(pod *v1.Pod, command string) (string, error) {
|
|||
|
||||
// NewIngressController deploys a new NGINX Ingress controller in a namespace
|
||||
func (f *Framework) NewIngressController(namespace string) error {
|
||||
var (
|
||||
execOut bytes.Buffer
|
||||
execErr bytes.Buffer
|
||||
)
|
||||
|
||||
cmd := exec.Command("./wait-for-nginx.sh", namespace)
|
||||
cmd.Stdout = &execOut
|
||||
cmd.Stderr = &execErr
|
||||
|
||||
err := cmd.Run()
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not execute: %v", err)
|
||||
}
|
||||
|
||||
if execErr.Len() > 0 {
|
||||
return fmt.Errorf("stderr: %v", execErr.String())
|
||||
return fmt.Errorf("Unexpected error waiting for ingress controller deployment: %v.\nLogs:\n%v", err, string(out))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ package framework
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -112,13 +112,11 @@ func (f *Framework) BeforeEach() {
|
|||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("Building NGINX HTTP URL")
|
||||
HTTPURL, err := f.GetNginxURL(HTTP)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
f.IngressController.HTTPURL = HTTPURL
|
||||
|
||||
By("Building NGINX HTTPS URL")
|
||||
HTTPSURL, err := f.GetNginxURL(HTTPS)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
|
@ -135,6 +133,13 @@ func (f *Framework) AfterEach() {
|
|||
By("Waiting for test namespace to no longer exist")
|
||||
err := DeleteKubeNamespace(f.KubeClientSet, f.IngressController.Namespace)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
if CurrentGinkgoTestDescription().Failed {
|
||||
log, err := f.NginxLogs()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
By("Dumping NGINX logs after a failure running a test")
|
||||
Logf("%v", log)
|
||||
}
|
||||
}
|
||||
|
||||
// IngressNginxDescribe wrapper function for ginkgo describe. Adds namespacing.
|
||||
|
|
@ -145,11 +150,7 @@ func IngressNginxDescribe(text string, body func()) bool {
|
|||
// GetNginxIP returns the IP address of the minikube cluster
|
||||
// where the NGINX ingress controller is running
|
||||
func (f *Framework) GetNginxIP() (string, error) {
|
||||
out, err := exec.Command("minikube", "ip").Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(string(out)), nil
|
||||
return os.Getenv("NODE_IP"), nil
|
||||
}
|
||||
|
||||
// GetNginxPort returns the number of TCP port where NGINX is running
|
||||
|
|
@ -426,3 +427,19 @@ func NewSingleIngress(name, path, host, ns, service string, port int, annotation
|
|||
|
||||
return ing
|
||||
}
|
||||
|
||||
// DisableDynamicConfiguration disables dynamic configuration
|
||||
func (f *Framework) DisableDynamicConfiguration() error {
|
||||
return UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "nginx-ingress-controller", 1,
|
||||
func(deployment *appsv1beta1.Deployment) error {
|
||||
args := deployment.Spec.Template.Spec.Containers[0].Args
|
||||
args = append(args, "--enable-dynamic-configuration=false")
|
||||
deployment.Spec.Template.Spec.Containers[0].Args = args
|
||||
_, err := f.KubeClientSet.AppsV1beta1().Deployments(f.IngressController.Namespace).Update(deployment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ func fileInFS(file string, fs file.Filesystem) wait.ConditionFunc {
|
|||
}
|
||||
|
||||
if stat == nil {
|
||||
return false, fmt.Errorf("file %v does not exists", file)
|
||||
return false, fmt.Errorf("file %v does not exist", file)
|
||||
}
|
||||
|
||||
if stat.Size() > 0 {
|
||||
|
|
|
|||
|
|
@ -27,23 +27,28 @@ import (
|
|||
. "github.com/onsi/gomega"
|
||||
"github.com/parnurzeal/gorequest"
|
||||
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
const (
|
||||
logDynamicConfigSuccess = "Dynamic reconfiguration succeeded"
|
||||
logDynamicConfigFailure = "Dynamic reconfiguration failed"
|
||||
logRequireBackendReload = "Configuration changes detected, backend reload required"
|
||||
logBackendReloadSuccess = "Backend successfully reloaded"
|
||||
logSkipBackendReload = "Changes handled by the dynamic configuration, skipping backend reload"
|
||||
logInitialConfigSync = "Initial synchronization of the NGINX configuration"
|
||||
waitForLuaSync = 2 * time.Second
|
||||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
||||
f := framework.NewDefaultFramework("dynamic-configuration")
|
||||
|
||||
BeforeEach(func() {
|
||||
err := enableDynamicConfiguration(f.IngressController.Namespace, f.KubeClientSet)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = f.NewEchoDeploymentWithReplicas(1)
|
||||
err := f.NewEchoDeploymentWithReplicas(1)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
host := "foo.com"
|
||||
|
|
@ -57,8 +62,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// give some time for Lua to sync the backend
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(waitForLuaSync)
|
||||
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL).
|
||||
|
|
@ -69,8 +73,16 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
|
||||
log, err := f.NginxLogs()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(log).ToNot(ContainSubstring("could not dynamically reconfigure"))
|
||||
Expect(log).To(ContainSubstring("first sync of Nginx configuration"))
|
||||
Expect(log).ToNot(ContainSubstring(logDynamicConfigFailure))
|
||||
Expect(log).To(ContainSubstring(logDynamicConfigSuccess))
|
||||
})
|
||||
|
||||
It("should set nameservers for Lua", func() {
|
||||
err := f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||
r := regexp.MustCompile(`configuration.nameservers = { [".,0-9a-zA-Z]+ }`)
|
||||
return r.MatchString(cfg)
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
Context("when only backends change", func() {
|
||||
|
|
@ -85,7 +97,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
replicas := 2
|
||||
err := framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "http-svc", replicas, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(waitForLuaSync)
|
||||
|
||||
log, err := f.NginxLogs()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
|
@ -94,14 +106,14 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
restOfLogs := log[index:]
|
||||
|
||||
By("POSTing new backends to Lua endpoint")
|
||||
Expect(restOfLogs).To(ContainSubstring("dynamic reconfiguration succeeded"))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring("could not dynamically reconfigure"))
|
||||
Expect(restOfLogs).To(ContainSubstring(logDynamicConfigSuccess))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring(logDynamicConfigFailure))
|
||||
|
||||
By("skipping Nginx reload")
|
||||
Expect(restOfLogs).ToNot(ContainSubstring("backend reload required"))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring("ingress backend successfully reloaded"))
|
||||
Expect(restOfLogs).To(ContainSubstring("skipping reload"))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring("first sync of Nginx configuration"))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring(logRequireBackendReload))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring(logBackendReloadSuccess))
|
||||
Expect(restOfLogs).To(ContainSubstring(logSkipBackendReload))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring(logInitialConfigSync))
|
||||
})
|
||||
|
||||
It("should be able to update endpoints even when the update POST size(request body) > size(client_body_buffer_size)", func() {
|
||||
|
|
@ -116,7 +128,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
replicas = 4
|
||||
err = framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "http-svc", replicas, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(waitForLuaSync)
|
||||
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL).
|
||||
|
|
@ -155,7 +167,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
ingress.ObjectMeta.Annotations["nginx.ingress.kubernetes.io/load-balance"] = "round_robin"
|
||||
_, err = f.KubeClientSet.ExtensionsV1beta1().Ingresses(f.IngressController.Namespace).Update(ingress)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(waitForLuaSync)
|
||||
|
||||
log, err := f.NginxLogs()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
|
@ -164,14 +176,14 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
restOfLogs := log[index:]
|
||||
|
||||
By("POSTing new backends to Lua endpoint")
|
||||
Expect(restOfLogs).To(ContainSubstring("dynamic reconfiguration succeeded"))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring("could not dynamically reconfigure"))
|
||||
Expect(restOfLogs).To(ContainSubstring(logDynamicConfigSuccess))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring(logDynamicConfigFailure))
|
||||
|
||||
By("skipping Nginx reload")
|
||||
Expect(restOfLogs).ToNot(ContainSubstring("backend reload required"))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring("ingress backend successfully reloaded"))
|
||||
Expect(restOfLogs).To(ContainSubstring("skipping reload"))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring("first sync of Nginx configuration"))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring(logRequireBackendReload))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring(logBackendReloadSuccess))
|
||||
Expect(restOfLogs).To(ContainSubstring(logSkipBackendReload))
|
||||
Expect(restOfLogs).ToNot(ContainSubstring(logInitialConfigSync))
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -208,10 +220,10 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
Expect(log).ToNot(BeEmpty())
|
||||
|
||||
By("reloading Nginx")
|
||||
Expect(log).To(ContainSubstring("ingress backend successfully reloaded"))
|
||||
Expect(log).To(ContainSubstring(logBackendReloadSuccess))
|
||||
|
||||
By("POSTing new backends to Lua endpoint")
|
||||
Expect(log).To(ContainSubstring("dynamic reconfiguration succeeded"))
|
||||
Expect(log).To(ContainSubstring(logDynamicConfigSuccess))
|
||||
|
||||
By("still be proxying requests through Lua balancer")
|
||||
err = f.WaitForNginxServer("foo.com",
|
||||
|
|
@ -231,7 +243,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
|
||||
err = framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "http-svc", 2, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
time.Sleep(10 * time.Second)
|
||||
time.Sleep(waitForLuaSync)
|
||||
|
||||
resp, body, errs := gorequest.New().
|
||||
Get(fmt.Sprintf("%s?a-unique-request-uri", f.IngressController.HTTPURL)).
|
||||
|
|
@ -275,7 +287,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
By("Increasing the number of service replicas")
|
||||
err = framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "http-svc", 2, nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(waitForLuaSync)
|
||||
|
||||
By("Making a first request")
|
||||
host := "foo.com"
|
||||
|
|
@ -331,7 +343,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
}
|
||||
_, err = f.KubeClientSet.ExtensionsV1beta1().Ingresses(f.IngressController.Namespace).Update(ingress)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(waitForLuaSync)
|
||||
|
||||
By("Making a request")
|
||||
host := "foo.com"
|
||||
|
|
@ -349,21 +361,6 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
|||
})
|
||||
})
|
||||
|
||||
func enableDynamicConfiguration(namespace string, kubeClientSet kubernetes.Interface) error {
|
||||
return framework.UpdateDeployment(kubeClientSet, namespace, "nginx-ingress-controller", 1,
|
||||
func(deployment *appsv1beta1.Deployment) error {
|
||||
args := deployment.Spec.Template.Spec.Containers[0].Args
|
||||
args = append(args, "--enable-dynamic-configuration")
|
||||
deployment.Spec.Template.Spec.Containers[0].Args = args
|
||||
_, err := kubeClientSet.AppsV1beta1().Deployments(namespace).Update(deployment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func ensureIngress(f *framework.Framework, host string) (*extensions.Ingress, error) {
|
||||
return f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &map[string]string{
|
||||
"nginx.ingress.kubernetes.io/load-balance": "ewma",
|
||||
|
|
|
|||
170
test/e2e/servicebackend/service_backend.go
Normal file
170
test/e2e/servicebackend/service_backend.go
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
Copyright 2018 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 servicebackend
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/parnurzeal/gorequest"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("Service backend - 503", func() {
|
||||
f := framework.NewDefaultFramework("service-backend")
|
||||
|
||||
BeforeEach(func() {
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
})
|
||||
|
||||
It("should return 503 when backend service does not exist", func() {
|
||||
host := "nonexistent.svc.com"
|
||||
|
||||
bi := buildIngressWithNonexistentService(host, f.IngressController.Namespace, "/")
|
||||
ing, err := f.EnsureIngress(bi)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "return 503;")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL).
|
||||
Set("Host", host).
|
||||
End()
|
||||
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||
Expect(resp.StatusCode).Should(Equal(503))
|
||||
})
|
||||
|
||||
It("should return 503 when all backend service endpoints are unavailable", func() {
|
||||
host := "unavailable.svc.com"
|
||||
|
||||
bi, bs := buildIngressWithUnavailableServiceEndpoints(host, f.IngressController.Namespace, "/")
|
||||
|
||||
svc, err := f.EnsureService(bs)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(svc).NotTo(BeNil())
|
||||
|
||||
ing, err := f.EnsureIngress(bi)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
err = f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, "return 503;")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
resp, _, errs := gorequest.New().
|
||||
Get(f.IngressController.HTTPURL).
|
||||
Set("Host", host).
|
||||
End()
|
||||
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||
Expect(resp.StatusCode).Should(Equal(503))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
func buildIngressWithNonexistentService(host, namespace, path string) *v1beta1.Ingress {
|
||||
backendService := "nonexistent-svc"
|
||||
return &v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: path,
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: backendService,
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func buildIngressWithUnavailableServiceEndpoints(host, namespace, path string) (*v1beta1.Ingress, *corev1.Service) {
|
||||
backendService := "unavailable-svc"
|
||||
return &v1beta1.Ingress{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: v1beta1.IngressSpec{
|
||||
Rules: []v1beta1.IngressRule{
|
||||
{
|
||||
Host: host,
|
||||
IngressRuleValue: v1beta1.IngressRuleValue{
|
||||
HTTP: &v1beta1.HTTPIngressRuleValue{
|
||||
Paths: []v1beta1.HTTPIngressPath{
|
||||
{
|
||||
Path: path,
|
||||
Backend: v1beta1.IngressBackend{
|
||||
ServiceName: backendService,
|
||||
ServicePort: intstr.FromInt(80),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, &corev1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: backendService,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: corev1.ServiceSpec{Ports: []corev1.ServicePort{
|
||||
{
|
||||
Name: "tcp",
|
||||
Port: 80,
|
||||
TargetPort: intstr.FromInt(80),
|
||||
Protocol: "TCP",
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{
|
||||
"app": backendService,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
91
test/e2e/settings/configmap_change.go
Normal file
91
test/e2e/settings/configmap_change.go
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Copyright 2018 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 (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("Configmap change", func() {
|
||||
f := framework.NewDefaultFramework("configmap-change")
|
||||
|
||||
BeforeEach(func() {
|
||||
err := f.NewEchoDeployment()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
})
|
||||
|
||||
It("should reload after an update in the configuration", func() {
|
||||
host := "configmap-change"
|
||||
|
||||
ing, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ing).NotTo(BeNil())
|
||||
|
||||
wlKey := "whitelist-source-range"
|
||||
wlValue := "1.1.1.1"
|
||||
|
||||
By("adding a whitelist-source-range")
|
||||
|
||||
err = f.UpdateNginxConfigMapData(wlKey, wlValue)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
checksumRegex := regexp.MustCompile("Configuration checksum:\\s+(\\d+)")
|
||||
checksum := ""
|
||||
|
||||
err = f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
// before returning, extract the current checksum
|
||||
match := checksumRegex.FindStringSubmatch(cfg)
|
||||
if len(match) > 0 {
|
||||
checksum = match[1]
|
||||
}
|
||||
|
||||
return strings.Contains(cfg, "geo $the_real_ip $deny_") &&
|
||||
strings.Contains(cfg, "1.1.1.1 0")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(checksum).NotTo(BeEmpty())
|
||||
|
||||
By("changing error-log-level")
|
||||
|
||||
err = f.UpdateNginxConfigMapData("error-log-level", "debug")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
newChecksum := ""
|
||||
err = f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
match := checksumRegex.FindStringSubmatch(cfg)
|
||||
if len(match) > 0 {
|
||||
newChecksum = match[1]
|
||||
}
|
||||
|
||||
return strings.ContainsAny(cfg, "error_log /var/log/nginx/error.log debug;")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(checksum).NotTo(BeEquivalentTo(newChecksum))
|
||||
})
|
||||
})
|
||||
43
test/e2e/settings/main_snippet.go
Normal file
43
test/e2e/settings/main_snippet.go
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2018 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"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("Main Snippet", func() {
|
||||
f := framework.NewDefaultFramework("main-snippet")
|
||||
mainSnippet := "main-snippet"
|
||||
|
||||
It("should add value of main-snippet setting to nginx config", func() {
|
||||
expectedComment := "# main snippet"
|
||||
err := f.UpdateNginxConfigMapData(mainSnippet, expectedComment)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, expectedComment)
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
})
|
||||
64
test/e2e/settings/multi_accept.go
Normal file
64
test/e2e/settings/multi_accept.go
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright 2018 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"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.IngressNginxDescribe("Multi Accept", func() {
|
||||
multiAccept := "enable-multi-accept"
|
||||
f := framework.NewDefaultFramework(multiAccept)
|
||||
|
||||
It("should be enabled by default", func() {
|
||||
expectedDirective := "multi_accept on;"
|
||||
err := f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, expectedDirective)
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should be enabled when set to true", func() {
|
||||
expectedDirective := "multi_accept on;"
|
||||
err := f.UpdateNginxConfigMapData(multiAccept, "true")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, expectedDirective)
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should be disabled when set to false", func() {
|
||||
expectedDirective := "multi_accept off;"
|
||||
err := f.UpdateNginxConfigMapData(multiAccept, "false")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, expectedDirective)
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
|
@ -51,7 +51,7 @@ var _ = framework.IngressNginxDescribe("Server Tokens", func() {
|
|||
err = f.WaitForNginxConfiguration(
|
||||
func(cfg string) bool {
|
||||
return strings.Contains(cfg, "server_tokens off") &&
|
||||
strings.Contains(cfg, "more_set_headers \"Server: \"")
|
||||
strings.Contains(cfg, "more_clear_headers Server;")
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
|
|
|||
|
|
@ -14,41 +14,37 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
export JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'
|
||||
set -e
|
||||
|
||||
echo "downloading kubectl..."
|
||||
curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/$KUBERNETES_VERSION/bin/linux/amd64/kubectl && \
|
||||
chmod +x kubectl && sudo mv kubectl /usr/local/bin/
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
echo "downloading minikube..."
|
||||
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && \
|
||||
chmod +x minikube && \
|
||||
sudo mv minikube /usr/local/bin/
|
||||
if test -e kubectl; then
|
||||
echo "skipping download of kubectl"
|
||||
else
|
||||
echo "downloading kubectl..."
|
||||
curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.11.0/bin/linux/amd64/kubectl && \
|
||||
chmod +x kubectl && sudo mv kubectl /usr/local/bin/
|
||||
fi
|
||||
|
||||
echo "starting minikube..."
|
||||
# Using a lower value for sync-frequency to speed up the tests (during the cleanup of resources inside a namespace)
|
||||
mkdir -p ${HOME}/.kube
|
||||
touch ${HOME}/.kube/config
|
||||
export KUBECONFIG=${HOME}/.kube/config
|
||||
|
||||
export MINIKUBE_WANTUPDATENOTIFICATION=false
|
||||
export MINIKUBE_WANTREPORTERRORPROMPT=false
|
||||
export MINIKUBE_HOME=$HOME
|
||||
mkdir $HOME/.kube || true
|
||||
touch $HOME/.kube/config
|
||||
echo "starting Kubernetes cluster..."
|
||||
$DIR/dind-cluster-v1.11.sh up
|
||||
|
||||
export KUBECONFIG=$HOME/.kube/config
|
||||
kubectl config use-context dind
|
||||
|
||||
# --vm-driver=none, use host docker (avoid docker-in-docker)
|
||||
# --bootstrapper=localkube, works around https://github.com/kubernetes/minikube/issues/2704
|
||||
sudo -E minikube start \
|
||||
--bootstrapper=localkube \
|
||||
--vm-driver=none \
|
||||
--kubernetes-version=$KUBERNETES_VERSION \
|
||||
--extra-config=kubelet.sync-frequency=1s \
|
||||
--extra-config=apiserver.authorization-mode=RBAC
|
||||
echo "Kubernetes cluster:"
|
||||
kubectl get nodes -o wide
|
||||
|
||||
minikube update-context
|
||||
export TAG=dev
|
||||
export ARCH=amd64
|
||||
export REGISTRY=${REGISTRY:-ingress-controller}
|
||||
|
||||
echo "waiting for kubernetes cluster"
|
||||
until kubectl get nodes -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True";
|
||||
do
|
||||
sleep 1;
|
||||
done
|
||||
echo "building container..."
|
||||
make -C ${DIR}/../../ build container
|
||||
|
||||
echo "copying docker image to cluster..."
|
||||
DEV_IMAGE=${REGISTRY}/nginx-ingress-controller:${TAG}
|
||||
${DIR}/dind-cluster-v1.11.sh copy-image ${DEV_IMAGE}
|
||||
|
|
|
|||
|
|
@ -14,11 +14,29 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -e
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
export NAMESPACE=$1
|
||||
|
||||
echo "deploying NGINX Ingress controller in namespace $NAMESPACE"
|
||||
|
||||
function on_exit {
|
||||
local error_code="$?"
|
||||
|
||||
test $error_code == 0 && return;
|
||||
|
||||
echo "Obtaining ingress controller pod logs..."
|
||||
kubectl logs -l app=ingress-nginx -n $NAMESPACE
|
||||
}
|
||||
trap on_exit EXIT
|
||||
|
||||
sed "s@\${NAMESPACE}@${NAMESPACE}@" $DIR/../manifests/ingress-controller/mandatory.yaml | kubectl apply --namespace=$NAMESPACE -f -
|
||||
cat $DIR/../manifests/ingress-controller/service-nodeport.yaml | kubectl apply --namespace=$NAMESPACE -f -
|
||||
|
||||
# wait for the deployment and fail if there is an error before starting the execution of any test
|
||||
kubectl rollout status \
|
||||
--request-timeout=3m \
|
||||
--namespace $NAMESPACE \
|
||||
deployment nginx-ingress-controller
|
||||
|
|
|
|||
|
|
@ -260,6 +260,14 @@ spec:
|
|||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
securityContext:
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
# www-data -> 33
|
||||
runAsUser: 33
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
|
|
@ -284,5 +292,3 @@ spec:
|
|||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
securityContext:
|
||||
privileged: true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue