merge from master
This commit is contained in:
commit
ce6e564f82
86 changed files with 1448 additions and 3530 deletions
4
Makefile
4
Makefile
|
@ -52,7 +52,7 @@ GOBUILD_FLAGS :=
|
||||||
|
|
||||||
ALL_ARCH = amd64 arm arm64 ppc64le
|
ALL_ARCH = amd64 arm arm64 ppc64le
|
||||||
|
|
||||||
QEMUVERSION = v2.12.0-1
|
QEMUVERSION = v3.0.0
|
||||||
|
|
||||||
BUSTED_ARGS =-v --pattern=_test
|
BUSTED_ARGS =-v --pattern=_test
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ IMAGE = $(REGISTRY)/$(IMGNAME)
|
||||||
MULTI_ARCH_IMG = $(IMAGE)-$(ARCH)
|
MULTI_ARCH_IMG = $(IMAGE)-$(ARCH)
|
||||||
|
|
||||||
# Set default base image dynamically for each arch
|
# Set default base image dynamically for each arch
|
||||||
BASEIMAGE?=quay.io/kubernetes-ingress-controller/nginx-$(ARCH):0.65
|
BASEIMAGE?=quay.io/kubernetes-ingress-controller/nginx-$(ARCH):0.66
|
||||||
|
|
||||||
ifeq ($(ARCH),arm)
|
ifeq ($(ARCH),arm)
|
||||||
QEMUARCH=arm
|
QEMUARCH=arm
|
||||||
|
|
|
@ -41,19 +41,6 @@ fi
|
||||||
|
|
||||||
SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
|
SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||||
|
|
||||||
mkdir -p ${SCRIPT_ROOT}/test/binaries
|
|
||||||
|
|
||||||
TEST_BINARIES=$( cd "${SCRIPT_ROOT}/test/binaries" ; pwd -P )
|
|
||||||
|
|
||||||
export PATH=${TEST_BINARIES}:$PATH
|
|
||||||
|
|
||||||
if ! [ -x "$(command -v kubectl)" ]; then
|
|
||||||
echo "downloading kubectl..."
|
|
||||||
curl -sSLo ${TEST_BINARIES}/kubectl \
|
|
||||||
https://storage.googleapis.com/kubernetes-release/release/v1.11.0/bin/linux/amd64/kubectl
|
|
||||||
chmod +x ${TEST_BINARIES}/kubectl
|
|
||||||
fi
|
|
||||||
|
|
||||||
ginkgo build ./test/e2e
|
ginkgo build ./test/e2e
|
||||||
|
|
||||||
exec -- \
|
exec -- \
|
||||||
|
|
|
@ -40,7 +40,7 @@ if [ "$missing" = true ];then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
E2E_IMAGE=quay.io/kubernetes-ingress-controller/e2e:v10102018-dcc6495
|
E2E_IMAGE=quay.io/kubernetes-ingress-controller/e2e:v10292018-240c7274b
|
||||||
|
|
||||||
DOCKER_OPTS=${DOCKER_OPTS:-""}
|
DOCKER_OPTS=${DOCKER_OPTS:-""}
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,8 @@ Takes the form "namespace/name".`)
|
||||||
Configured inside the NGINX status server. All requests received on the port
|
Configured inside the NGINX status server. All requests received on the port
|
||||||
defined by the healthz-port parameter are forwarded internally to this path.`)
|
defined by the healthz-port parameter are forwarded internally to this path.`)
|
||||||
|
|
||||||
|
healthCheckTimeout = flags.Duration("health-check-timeout", 10, `Time limit, in seconds, for a probe to health-check-path to succeed.`)
|
||||||
|
|
||||||
updateStatus = flags.Bool("update-status", true,
|
updateStatus = flags.Bool("update-status", true,
|
||||||
`Update the load-balancer status of Ingress objects this controller satisfies.
|
`Update the load-balancer status of Ingress objects this controller satisfies.
|
||||||
Requires setting the publish-service parameter to a valid Service reference.`)
|
Requires setting the publish-service parameter to a valid Service reference.`)
|
||||||
|
@ -217,6 +219,7 @@ Feature backed by OpenResty Lua libraries. Requires that OCSP stapling is not en
|
||||||
ConfigMapName: *configMap,
|
ConfigMapName: *configMap,
|
||||||
DefaultSSLCertificate: *defSSLCertificate,
|
DefaultSSLCertificate: *defSSLCertificate,
|
||||||
DefaultHealthzURL: *defHealthzURL,
|
DefaultHealthzURL: *defHealthzURL,
|
||||||
|
HealthCheckTimeout: *healthCheckTimeout,
|
||||||
PublishService: *publishSvc,
|
PublishService: *publishSvc,
|
||||||
PublishStatusAddress: *publishStatusAddress,
|
PublishStatusAddress: *publishStatusAddress,
|
||||||
ForceNamespaceIsolation: *forceIsolation,
|
ForceNamespaceIsolation: *forceIsolation,
|
||||||
|
|
|
@ -94,7 +94,7 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO (antoineco): compare with error types from k8s.io/apimachinery/pkg/api/errors
|
// TODO (antoineco): compare with error types from k8s.io/apimachinery/pkg/api/errors
|
||||||
if strings.Contains(err.Error(), "cannot get services in the namespace") {
|
if strings.Contains(err.Error(), "cannot get services in the namespace") {
|
||||||
glog.Fatalf("✖ The cluster seems to be running with a restrictive Authorization mode and the Ingress controller does not have the required permissions to operate normally.")
|
glog.Fatal("✖ The cluster seems to be running with a restrictive Authorization mode and the Ingress controller does not have the required permissions to operate normally.")
|
||||||
}
|
}
|
||||||
glog.Fatalf("No service with name %v found: %v", conf.DefaultService, err)
|
glog.Fatalf("No service with name %v found: %v", conf.DefaultService, err)
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ func handleSigterm(ngx *controller.NGINXController, exit exiter) {
|
||||||
signalChan := make(chan os.Signal, 1)
|
signalChan := make(chan os.Signal, 1)
|
||||||
signal.Notify(signalChan, syscall.SIGTERM)
|
signal.Notify(signalChan, syscall.SIGTERM)
|
||||||
<-signalChan
|
<-signalChan
|
||||||
glog.Infof("Received SIGTERM, shutting down")
|
glog.Info("Received SIGTERM, shutting down")
|
||||||
|
|
||||||
exitCode := 0
|
exitCode := 0
|
||||||
if err := ngx.Stop(); err != nil {
|
if err := ngx.Stop(); err != nil {
|
||||||
|
@ -168,7 +168,7 @@ func handleSigterm(ngx *controller.NGINXController, exit exiter) {
|
||||||
exitCode = 1
|
exitCode = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.Infof("Handled quit, awaiting Pod deletion")
|
glog.Info("Handled quit, awaiting Pod deletion")
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
glog.Infof("Exiting with %v", exitCode)
|
glog.Infof("Exiting with %v", exitCode)
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
## Contents
|
## Contents
|
||||||
|
|
||||||
- [Generic Deployment](#generic-deployment)
|
- [Prerequisite Generic Deployment Command](#prerequisite-generic-deployment-command)
|
||||||
- [Mandatory command](#mandatory-command)
|
|
||||||
- [Provider Specific Steps](#provider-specific-steps)
|
- [Provider Specific Steps](#provider-specific-steps)
|
||||||
- [Docker for Mac](#docker-for-mac)
|
- [Docker for Mac](#docker-for-mac)
|
||||||
- [minikube](#minikube)
|
- [minikube](#minikube)
|
||||||
|
@ -159,7 +158,7 @@ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/mast
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
For extended notes regarding deployments on bare-metal, see [Bare-metal considerations](./baremetal/).
|
For extended notes regarding deployments on bare-metal, see [Bare-metal considerations](./baremetal.md/).
|
||||||
|
|
||||||
### Verify installation
|
### Verify installation
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ It is possible to enable Client-Certificate Authentication by adding additional
|
||||||
Before getting started you must have the following Certificates Setup:
|
Before getting started you must have the following Certificates Setup:
|
||||||
|
|
||||||
1. CA certificate and Key(Intermediate Certs need to be in CA)
|
1. CA certificate and Key(Intermediate Certs need to be in CA)
|
||||||
2. Server Certificate(Signed by CA) and Key (CN should be equal the the hostname you will use)
|
2. Server Certificate(Signed by CA) and Key (CN should be equal the hostname you will use)
|
||||||
3. Client Certificate(Signed by CA) and Key
|
3. Client Certificate(Signed by CA) and Key
|
||||||
|
|
||||||
## Creating Certificate Secrets
|
## Creating Certificate Secrets
|
||||||
|
|
|
@ -10,7 +10,7 @@ They are set in the container spec of the `nginx-ingress-controller` Deployment
|
||||||
| `--annotations-prefix string` | Prefix of the Ingress annotations specific to the NGINX controller. (default "nginx.ingress.kubernetes.io") |
|
| `--annotations-prefix string` | Prefix of the Ingress annotations specific to the NGINX controller. (default "nginx.ingress.kubernetes.io") |
|
||||||
| `--apiserver-host string` | Address of the Kubernetes API server. Takes the form "protocol://address:port". If not specified, it is assumed the program runs inside a Kubernetes cluster and local discovery is attempted. |
|
| `--apiserver-host string` | Address of the Kubernetes API server. Takes the form "protocol://address:port". If not specified, it is assumed the program runs inside a Kubernetes cluster and local discovery is attempted. |
|
||||||
| `--configmap string` | Name of the ConfigMap containing custom global configurations for the controller. |
|
| `--configmap string` | Name of the ConfigMap containing custom global configurations for the controller. |
|
||||||
| `--default-backend-service string` | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form "namespace/name". The controller configures NGINX to forward requests to the first port of this Service. If not specified, 404 page will be returned diretly from Nginx.|
|
| `--default-backend-service string` | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form "namespace/name". The controller configures NGINX to forward requests to the first port of this Service. If not specified, a 404 page will be returned directly from NGINX.|
|
||||||
| `--default-server-port int` | When `default-backend-service` is not specified or specified service does not have any endpoint, a local endpoint with this port will be used to serve 404 page from inside Nginx. |
|
| `--default-server-port int` | When `default-backend-service` is not specified or specified service does not have any endpoint, a local endpoint with this port will be used to serve 404 page from inside Nginx. |
|
||||||
| `--default-ssl-certificate string` | Secret containing a SSL certificate to be used by the default HTTPS server (catch-all). Takes the form "namespace/name". |
|
| `--default-ssl-certificate string` | Secret containing a SSL certificate to be used by the default HTTPS server (catch-all). Takes the form "namespace/name". |
|
||||||
| `--election-id string` | Election id to use for Ingress status updates. (default "ingress-controller-leader") |
|
| `--election-id string` | Election id to use for Ingress status updates. (default "ingress-controller-leader") |
|
||||||
|
|
|
@ -80,6 +80,9 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-debug](#lua-resty-waf)|"true" or "false"|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-debug](#lua-resty-waf)|"true" or "false"|
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-ignore-rulesets](#lua-resty-waf)|string|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-ignore-rulesets](#lua-resty-waf)|string|
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-extra-rules](#lua-resty-waf)|string|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-extra-rules](#lua-resty-waf)|string|
|
||||||
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-allow-unknown-content-types](#lua-resty-waf)|"true" or "false"|
|
||||||
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-score-threshold](#lua-resty-waf)|number|
|
||||||
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-process-multipart-body](#lua-resty-waf)|"true" or "false"|
|
||||||
|[nginx.ingress.kubernetes.io/enable-influxdb](#influxdb)|"true" or "false"|
|
|[nginx.ingress.kubernetes.io/enable-influxdb](#influxdb)|"true" or "false"|
|
||||||
|[nginx.ingress.kubernetes.io/influxdb-measurement](#influxdb)|string|
|
|[nginx.ingress.kubernetes.io/influxdb-measurement](#influxdb)|string|
|
||||||
|[nginx.ingress.kubernetes.io/influxdb-port](#influxdb)|string|
|
|[nginx.ingress.kubernetes.io/influxdb-port](#influxdb)|string|
|
||||||
|
@ -558,6 +561,32 @@ It is also possible to configure custom WAF rules per ingress using the `nginx.i
|
||||||
nginx.ingress.kubernetes.io/lua-resty-waf-extra-rules: '[=[ { "access": [ { "actions": { "disrupt" : "DENY" }, "id": 10001, "msg": "my custom rule", "operator": "STR_CONTAINS", "pattern": "foo", "vars": [ { "parse": [ "values", 1 ], "type": "REQUEST_ARGS" } ] } ], "body_filter": [], "header_filter":[] } ]=]'
|
nginx.ingress.kubernetes.io/lua-resty-waf-extra-rules: '[=[ { "access": [ { "actions": { "disrupt" : "DENY" }, "id": 10001, "msg": "my custom rule", "operator": "STR_CONTAINS", "pattern": "foo", "vars": [ { "parse": [ "values", 1 ], "type": "REQUEST_ARGS" } ] } ], "body_filter": [], "header_filter":[] } ]=]'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Since the default allowed contents were `"text/html", "text/json", "application/json"`
|
||||||
|
We can enable the following annotation for allow all contents type:
|
||||||
|
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
nginx.ingress.kubernetes.io/lua-resty-waf-allow-unknown-content-types: "true"
|
||||||
|
```
|
||||||
|
|
||||||
|
The default score of lua-resty-waf is 5, which usually triggered if hitting 2 default rules, you can modify the score threshold with following annotation:
|
||||||
|
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
nginx.ingress.kubernetes.io/lua-resty-waf-score-threshold: "10"
|
||||||
|
```
|
||||||
|
|
||||||
|
When you enabled HTTPS in the endpoint and since resty-lua will return 500 error when processing "multipart" contents
|
||||||
|
Reference for this [issue](https://github.com/p0pr0ck5/lua-resty-waf/issues/166)
|
||||||
|
|
||||||
|
By default, it will be "true"
|
||||||
|
|
||||||
|
You may enable the following annotation for work around:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
nginx.ingress.kubernetes.io/lua-resty-waf-process-multipart-body: "false"
|
||||||
|
```
|
||||||
|
|
||||||
For details on how to write WAF rules, please refer to [https://github.com/p0pr0ck5/lua-resty-waf](https://github.com/p0pr0ck5/lua-resty-waf).
|
For details on how to write WAF rules, please refer to [https://github.com/p0pr0ck5/lua-resty-waf](https://github.com/p0pr0ck5/lua-resty-waf).
|
||||||
|
|
||||||
[configmap]: ./configmap.md
|
[configmap]: ./configmap.md
|
||||||
|
|
|
@ -86,6 +86,7 @@ The following table shows a configuration option's name, type, and the default v
|
||||||
|[proxy-protocol-header-timeout](#proxy-protocol-header-timeout)|string|"5s"|
|
|[proxy-protocol-header-timeout](#proxy-protocol-header-timeout)|string|"5s"|
|
||||||
|[use-gzip](#use-gzip)|bool|"true"|
|
|[use-gzip](#use-gzip)|bool|"true"|
|
||||||
|[use-geoip](#use-geoip)|bool|"true"|
|
|[use-geoip](#use-geoip)|bool|"true"|
|
||||||
|
|[use-geoip2](#use-geoip2)|bool|"false"|
|
||||||
|[enable-brotli](#enable-brotli)|bool|"false"|
|
|[enable-brotli](#enable-brotli)|bool|"false"|
|
||||||
|[brotli-level](#brotli-level)|int|4|
|
|[brotli-level](#brotli-level)|int|4|
|
||||||
|[brotli-types](#brotli-types)|string|"application/xml+rss 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"|
|
|[brotli-types](#brotli-types)|string|"application/xml+rss 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"|
|
||||||
|
@ -498,6 +499,13 @@ The default mime type list to compress is: `application/atom+xml application/jav
|
||||||
Enables or disables ["geoip" module](http://nginx.org/en/docs/http/ngx_http_geoip_module.html) that creates variables with values depending on the client IP address, using the precompiled MaxMind databases.
|
Enables or disables ["geoip" module](http://nginx.org/en/docs/http/ngx_http_geoip_module.html) that creates variables with values depending on the client IP address, using the precompiled MaxMind databases.
|
||||||
_**default:**_ true
|
_**default:**_ true
|
||||||
|
|
||||||
|
> __Note:__ MaxMind legacy databases are discontinued and will not receive updates after 2019-01-02, cf. [discontinuation notice](https://support.maxmind.com/geolite-legacy-discontinuation-notice/). Consider [use-geoip2](#use-geoip2) below.
|
||||||
|
|
||||||
|
## use-geoip2
|
||||||
|
|
||||||
|
Enables the [geoip2 module](https://github.com/leev/ngx_http_geoip2_module) for NGINX.
|
||||||
|
_**default:**_ false
|
||||||
|
|
||||||
## enable-brotli
|
## enable-brotli
|
||||||
|
|
||||||
Enables or disables compression of HTTP responses using the ["brotli" module](https://github.com/google/ngx_brotli).
|
Enables or disables compression of HTTP responses using the ["brotli" module](https://github.com/google/ngx_brotli).
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
Anytime we reference a TLS secret, we mean a PEM-encoded X.509, RSA (2048) secret.
|
Anytime we reference a TLS secret, we mean a PEM-encoded X.509, RSA (2048) secret.
|
||||||
|
|
||||||
You can generate a self-signed certificate and private key with with:
|
You can generate a self-signed certificate and private key with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=${HOST}/O=${HOST}"`
|
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=${HOST}/O=${HOST}"`
|
||||||
|
|
|
@ -20,7 +20,7 @@ set -o pipefail
|
||||||
|
|
||||||
SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
|
SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||||
|
|
||||||
INPUT="namespace.yaml configmap.yaml tcp-services-configmap.yaml udp-services-configmap.yaml rbac.yaml with-rbac.yaml"
|
INPUT="namespace.yaml configmap.yaml rbac.yaml with-rbac.yaml"
|
||||||
MANIFEST=$(cd ${SCRIPT_ROOT}/deploy; cat ${INPUT})
|
MANIFEST=$(cd ${SCRIPT_ROOT}/deploy; cat ${INPUT})
|
||||||
|
|
||||||
echo "${MANIFEST}" > ${SCRIPT_ROOT}/deploy/mandatory.yaml
|
echo "${MANIFEST}" > ${SCRIPT_ROOT}/deploy/mandatory.yaml
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
FROM quay.io/kubernetes-ingress-controller/nginx-amd64:0.63
|
FROM quay.io/kubernetes-ingress-controller/nginx-amd64:0.66
|
||||||
|
|
||||||
RUN clean-install \
|
RUN clean-install \
|
||||||
g++ \
|
g++ \
|
||||||
|
@ -61,3 +61,7 @@ RUN luarocks install luacheck \
|
||||||
|
|
||||||
RUN go get github.com/onsi/ginkgo/ginkgo \
|
RUN go get github.com/onsi/ginkgo/ginkgo \
|
||||||
&& go get golang.org/x/lint/golint
|
&& go get golang.org/x/lint/golint
|
||||||
|
|
||||||
|
RUN curl -Lo /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kubectl \
|
||||||
|
&& chmod +x /usr/local/bin/kubectl
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
# 0.0.0 shouldn't clobber any released builds
|
# 0.0.0 shouldn't clobber any released builds
|
||||||
TAG ?= 0.65
|
TAG ?= 0.66
|
||||||
REGISTRY ?= quay.io/kubernetes-ingress-controller
|
REGISTRY ?= quay.io/kubernetes-ingress-controller
|
||||||
ARCH ?= $(shell go env GOARCH)
|
ARCH ?= $(shell go env GOARCH)
|
||||||
DOCKER ?= docker
|
DOCKER ?= docker
|
||||||
|
@ -26,7 +26,7 @@ ifeq ($(GOHOSTOS),darwin)
|
||||||
SED_I=sed -i ''
|
SED_I=sed -i ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
QEMUVERSION=v2.12.0-1
|
QEMUVERSION=v3.0.0
|
||||||
|
|
||||||
IMGNAME = nginx
|
IMGNAME = nginx
|
||||||
IMAGE = $(REGISTRY)/$(IMGNAME)
|
IMAGE = $(REGISTRY)/$(IMGNAME)
|
||||||
|
|
|
@ -14,6 +14,7 @@ This custom nginx image contains:
|
||||||
- [zipkin-cpp-opentracing](https://github.com/rnburn/zipkin-cpp-opentracing)
|
- [zipkin-cpp-opentracing](https://github.com/rnburn/zipkin-cpp-opentracing)
|
||||||
- [ModSecurity-nginx](https://github.com/SpiderLabs/ModSecurity-nginx) (only supported in x86_64)
|
- [ModSecurity-nginx](https://github.com/SpiderLabs/ModSecurity-nginx) (only supported in x86_64)
|
||||||
- [brotli](https://github.com/google/brotli)
|
- [brotli](https://github.com/google/brotli)
|
||||||
|
- [geoip2](https://github.com/leev/ngx_http_geoip2_module)
|
||||||
|
|
||||||
**How to use this image:**
|
**How to use this image:**
|
||||||
This image provides a default configuration file with no backend servers.
|
This image provides a default configuration file with no backend servers.
|
||||||
|
|
|
@ -29,13 +29,13 @@ export NGINX_OPENTRACING_VERSION=0.6.0
|
||||||
export OPENTRACING_CPP_VERSION=1.5.0
|
export OPENTRACING_CPP_VERSION=1.5.0
|
||||||
export ZIPKIN_CPP_VERSION=0.5.2
|
export ZIPKIN_CPP_VERSION=0.5.2
|
||||||
export JAEGER_VERSION=ba0fa3fa6dbb01995d996f988a897e272100bf95
|
export JAEGER_VERSION=ba0fa3fa6dbb01995d996f988a897e272100bf95
|
||||||
export MODSECURITY_VERSION=37b76e88df4bce8a9846345c27271d7e6ce1acfb
|
export MODSECURITY_VERSION=56cfa4e4805bb6134b97143052a9b48919cc294f
|
||||||
export LUA_NGX_VERSION=e94f2e5d64daa45ff396e262d8dab8e56f5f10e0
|
export LUA_NGX_VERSION=e94f2e5d64daa45ff396e262d8dab8e56f5f10e0
|
||||||
export LUA_UPSTREAM_VERSION=0.07
|
export LUA_UPSTREAM_VERSION=0.07
|
||||||
export NGINX_INFLUXDB_VERSION=f20cfb2458c338f162132f5a21eb021e2cbe6383
|
export NGINX_INFLUXDB_VERSION=0e2cb6cbf850a29c81e44be9e33d9a15d45c50e8
|
||||||
export GEOIP2_VERSION=3.0
|
export GEOIP2_VERSION=3.2
|
||||||
export NGINX_AJP_VERSION=bf6cd93f2098b59260de8d494f0f4b1f11a84627
|
export NGINX_AJP_VERSION=bf6cd93f2098b59260de8d494f0f4b1f11a84627
|
||||||
export LUAJIT_VERSION=8e35a1932250b0313c06393061f332c760efdf40
|
export LUAJIT_VERSION=c58fe79b870f1934479bf14fe8035fc3d9fdfde2
|
||||||
|
|
||||||
export BUILD_PATH=/tmp/build
|
export BUILD_PATH=/tmp/build
|
||||||
|
|
||||||
|
@ -53,10 +53,6 @@ get_src()
|
||||||
rm -rf "$f"
|
rm -rf "$f"
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ ${ARCH} == "ppc64le" ]]; then
|
|
||||||
clean-install software-properties-common
|
|
||||||
fi
|
|
||||||
|
|
||||||
apt-get update && apt-get dist-upgrade -y
|
apt-get update && apt-get dist-upgrade -y
|
||||||
|
|
||||||
# install required packages to build
|
# install required packages to build
|
||||||
|
@ -94,8 +90,15 @@ clean-install \
|
||||||
dumb-init \
|
dumb-init \
|
||||||
gdb \
|
gdb \
|
||||||
valgrind \
|
valgrind \
|
||||||
|
bc \
|
||||||
|| exit 1
|
|| exit 1
|
||||||
|
|
||||||
|
if [[ ${ARCH} == "ppc64le" ]]; then
|
||||||
|
wget http://ftp.us.debian.org/debian/pool/main/a/apt/libapt-pkg5.0_1.7.0_ppc64el.deb
|
||||||
|
dpkg -i libapt-pkg5.0_1.7.0_ppc64el.deb
|
||||||
|
clean-install python3-apt python3-software-properties software-properties-common
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ${ARCH} == "x86_64" ]]; then
|
if [[ ${ARCH} == "x86_64" ]]; then
|
||||||
ln -s /usr/lib/x86_64-linux-gnu/liblua5.1.so /usr/lib/liblua.so
|
ln -s /usr/lib/x86_64-linux-gnu/liblua5.1.so /usr/lib/liblua.so
|
||||||
ln -s /usr/lib/x86_64-linux-gnu /usr/lib/lua-platform-path
|
ln -s /usr/lib/x86_64-linux-gnu /usr/lib/lua-platform-path
|
||||||
|
@ -125,12 +128,23 @@ function geoip_get {
|
||||||
wget -O $GEOIP_FOLDER/$1 $2 || { echo "Could not download $1, exiting." ; exit 1; }
|
wget -O $GEOIP_FOLDER/$1 $2 || { echo "Could not download $1, exiting." ; exit 1; }
|
||||||
gunzip $GEOIP_FOLDER/$1
|
gunzip $GEOIP_FOLDER/$1
|
||||||
}
|
}
|
||||||
|
function geoip2_get {
|
||||||
|
wget -O $GEOIP_FOLDER/$1.tar.gz $2 || { echo "Could not download $1, exiting." ; exit 1; }
|
||||||
|
mkdir $GEOIP_FOLDER/$1 && tar xf $GEOIP_FOLDER/$1.tar.gz -C $GEOIP_FOLDER/$1 --strip-components 1 && mv $GEOIP_FOLDER/$1/$1.mmdb $GEOIP_FOLDER/$1.mmdb && rm -rf $GEOIP_FOLDER/$1
|
||||||
|
}
|
||||||
|
|
||||||
|
geoip_get "GeoIPASNum.dat.gz" "http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz"
|
||||||
|
geoip_get "GeoIP.dat.gz" "https://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz"
|
||||||
|
geoip_get "GeoLiteCity.dat.gz" "https://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz"
|
||||||
|
geoip2_get "GeoLite2-City" "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz"
|
||||||
|
geoip2_get "GeoLite2-ASN" "http://geolite.maxmind.com/download/geoip/database/GeoLite2-ASN.tar.gz"
|
||||||
|
|
||||||
|
if [[ (${ARCH} == "ppc64le") ]]; then
|
||||||
|
echo "deb http://deb.debian.org/debian experimental main" >> /etc/apt/sources.list
|
||||||
|
apt-get update
|
||||||
|
apt-get -t experimental install -y luajit
|
||||||
|
fi
|
||||||
|
|
||||||
geoip_get "GeoIPASNum.dat.gz" "http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz"
|
|
||||||
geoip_get "GeoIP.dat.gz" "https://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz"
|
|
||||||
geoip_get "GeoLite2-City.mmdb.gz" "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz"
|
|
||||||
geoip_get "GeoLite2-ASN.mmdb.gz" "http://geolite.maxmind.com/download/geoip/database/GeoLite2-ASN.tar.gz"
|
|
||||||
geoip_get "GeoLiteCity.dat.gz" "https://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz"
|
|
||||||
|
|
||||||
mkdir --verbose -p "$BUILD_PATH"
|
mkdir --verbose -p "$BUILD_PATH"
|
||||||
cd "$BUILD_PATH"
|
cd "$BUILD_PATH"
|
||||||
|
@ -163,7 +177,7 @@ get_src 4455ca507936bc4b658ded10a90d8ebbbd61c58f06207be565a4ffdc885687b5 \
|
||||||
get_src 30affaf0f3a84193f7127cc0135da91773ce45d902414082273dae78914f73df \
|
get_src 30affaf0f3a84193f7127cc0135da91773ce45d902414082273dae78914f73df \
|
||||||
"https://github.com/rnburn/zipkin-cpp-opentracing/archive/v$ZIPKIN_CPP_VERSION.tar.gz"
|
"https://github.com/rnburn/zipkin-cpp-opentracing/archive/v$ZIPKIN_CPP_VERSION.tar.gz"
|
||||||
|
|
||||||
get_src fe7d3188e097d68f1942d46c4adba262d9ddcf433409ebc15bb5355bfb001a4a \
|
get_src a75e3c0249c8ce4313d21b43d3cf3dcd89518dd6582ef7c6697cb7fe6ef5a84e \
|
||||||
"https://github.com/SpiderLabs/ModSecurity-nginx/archive/$MODSECURITY_VERSION.tar.gz"
|
"https://github.com/SpiderLabs/ModSecurity-nginx/archive/$MODSECURITY_VERSION.tar.gz"
|
||||||
|
|
||||||
get_src b68286966f292fb552511b71bd8bc11af8f12c8aa760372d1437ac8760cb2f25 \
|
get_src b68286966f292fb552511b71bd8bc11af8f12c8aa760372d1437ac8760cb2f25 \
|
||||||
|
@ -202,13 +216,13 @@ get_src a77bf0d7cf6a9ba017d0dc973b1a58f13e48242dd3849c5e99c07d250667c44c \
|
||||||
get_src d81b33129c6fb5203b571fa4d8394823bf473d8872c0357a1d0f14420b1483bd \
|
get_src d81b33129c6fb5203b571fa4d8394823bf473d8872c0357a1d0f14420b1483bd \
|
||||||
"https://github.com/cloudflare/lua-resty-cookie/archive/v0.1.0.tar.gz"
|
"https://github.com/cloudflare/lua-resty-cookie/archive/v0.1.0.tar.gz"
|
||||||
|
|
||||||
get_src 5a4485be0031d285f2bdf59afb1f7b8f3cef4c476595ed66f1258206e1b5c3ac \
|
get_src 21dab7625a028d4560d0215c4bc3b82f6153344f933abb99dc9fd5f0d19519ab \
|
||||||
"https://github.com/openresty/luajit2/archive/$LUAJIT_VERSION.tar.gz"
|
"https://github.com/openresty/luajit2/archive/$LUAJIT_VERSION.tar.gz"
|
||||||
|
|
||||||
get_src 1897d7677d99c1cedeb95b2eb00652a4a7e8e604304c3053a93bd3ba7dd82884 \
|
get_src c673fcee37c1c4794f921b6710b09e8a0e1e58117aa788f798507d033f737192 \
|
||||||
"https://github.com/influxdata/nginx-influxdb-module/archive/$NGINX_INFLUXDB_VERSION.tar.gz"
|
"https://github.com/influxdata/nginx-influxdb-module/archive/$NGINX_INFLUXDB_VERSION.tar.gz"
|
||||||
|
|
||||||
get_src 65a191688348a05d8d92b2e7ce9c6eb8cb8322205c34637da582a1205864133d \
|
get_src 15bd1005228cf2c869a6f09e8c41a6aaa6846e4936c473106786ae8ac860fab7 \
|
||||||
"https://github.com/leev/ngx_http_geoip2_module/archive/$GEOIP2_VERSION.tar.gz"
|
"https://github.com/leev/ngx_http_geoip2_module/archive/$GEOIP2_VERSION.tar.gz"
|
||||||
|
|
||||||
get_src 5f629a50ba22347c441421091da70fdc2ac14586619934534e5a0f8a1390a950 \
|
get_src 5f629a50ba22347c441421091da70fdc2ac14586619934534e5a0f8a1390a950 \
|
||||||
|
@ -221,21 +235,44 @@ export MAKEFLAGS=-j${CORES}
|
||||||
export CTEST_BUILD_FLAGS=${MAKEFLAGS}
|
export CTEST_BUILD_FLAGS=${MAKEFLAGS}
|
||||||
export HUNTER_JOBS_NUMBER=${CORES}
|
export HUNTER_JOBS_NUMBER=${CORES}
|
||||||
|
|
||||||
|
OPENSSL_DIR="$BUILD_PATH/openssl"
|
||||||
|
mkdir -p $OPENSSL_DIR
|
||||||
|
cd $OPENSSL_DIR
|
||||||
|
|
||||||
|
# Install Openssl 1.1.1 from source
|
||||||
|
wget http://http.debian.net/debian/pool/main/o/openssl/openssl_1.1.1-1.dsc
|
||||||
|
wget http://http.debian.net/debian/pool/main/o/openssl/openssl_1.1.1.orig.tar.gz
|
||||||
|
wget http://http.debian.net/debian/pool/main/o/openssl/openssl_1.1.1.orig.tar.gz.asc
|
||||||
|
wget http://http.debian.net/debian/pool/main/o/openssl/openssl_1.1.1-1.debian.tar.xz
|
||||||
|
|
||||||
|
tar zxpvf openssl_1.1.1.orig.tar.gz
|
||||||
|
cd openssl-1.1.1/
|
||||||
|
tar xpvf ../openssl_1.1.1-1.debian.tar.xz
|
||||||
|
|
||||||
|
dpkg-buildpackage -rfakeroot
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
dpkg -i openssl_1.1.1-1_*.deb libssl1.1_1.1.1-1_*.deb libssl-dev_1.1.1-1_*.deb
|
||||||
|
|
||||||
|
# Install luajit from openresty fork
|
||||||
export LUAJIT_LIB=/usr/local/lib
|
export LUAJIT_LIB=/usr/local/lib
|
||||||
|
export LUA_LIB_DIR="$LUAJIT_LIB/lua"
|
||||||
|
|
||||||
# luajit is available only as deb package on ppc64le
|
# luajit is available only as deb package on ppc64le
|
||||||
if [[ (${ARCH} == "ppc64le") ]]; then
|
if [[ (${ARCH} != "ppc64le") ]]; then
|
||||||
clean-install luajit
|
|
||||||
else
|
|
||||||
cd "$BUILD_PATH/luajit2-$LUAJIT_VERSION"
|
cd "$BUILD_PATH/luajit2-$LUAJIT_VERSION"
|
||||||
make CCDEBUG=-g
|
make CCDEBUG=-g
|
||||||
make install
|
make install
|
||||||
|
|
||||||
export LUAJIT_INC=/usr/local/include/luajit-2.1
|
export LUAJIT_INC=/usr/local/include/luajit-2.1
|
||||||
export LUA_LIB_DIR="$LUAJIT_LIB/lua"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Installing luarocks packages
|
# Installing luarocks packages
|
||||||
|
if [[ ${ARCH} == "x86_64" ]]; then
|
||||||
|
export PCRE_DIR=/usr/lib/x86_64-linux-gnu
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ${ARCH} == "armv7l" ]]; then
|
if [[ ${ARCH} == "armv7l" ]]; then
|
||||||
export PCRE_DIR=/usr/lib/armhf-linux-gnu
|
export PCRE_DIR=/usr/lib/armhf-linux-gnu
|
||||||
fi
|
fi
|
||||||
|
@ -248,7 +285,8 @@ if [[ ${ARCH} == "ppc64le" ]]; then
|
||||||
export PCRE_DIR=/usr/lib/powerpc64le-linux-gnu
|
export PCRE_DIR=/usr/lib/powerpc64le-linux-gnu
|
||||||
fi
|
fi
|
||||||
|
|
||||||
luarocks install lrexlib-pcre 2.7.2-1
|
cd "$BUILD_PATH"
|
||||||
|
luarocks install lrexlib-pcre 2.7.2-1 PCRE_LIBDIR=${PCRE_DIR}
|
||||||
|
|
||||||
cd "$BUILD_PATH/lua-resty-core-0.1.15"
|
cd "$BUILD_PATH/lua-resty-core-0.1.15"
|
||||||
make install
|
make install
|
||||||
|
@ -326,14 +364,14 @@ EOF
|
||||||
mkdir .build
|
mkdir .build
|
||||||
cd .build
|
cd .build
|
||||||
|
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||||
-DBUILD_TESTING=OFF \
|
-DBUILD_TESTING=OFF \
|
||||||
-DJAEGERTRACING_BUILD_EXAMPLES=OFF \
|
-DJAEGERTRACING_BUILD_EXAMPLES=OFF \
|
||||||
-DJAEGERTRACING_BUILD_CROSSDOCK=OFF \
|
-DJAEGERTRACING_BUILD_CROSSDOCK=OFF \
|
||||||
-DJAEGERTRACING_COVERAGE=OFF \
|
-DJAEGERTRACING_COVERAGE=OFF \
|
||||||
-DJAEGERTRACING_PLUGIN=ON \
|
-DJAEGERTRACING_PLUGIN=ON \
|
||||||
-DHUNTER_CONFIGURATION_TYPES=Release \
|
-DHUNTER_CONFIGURATION_TYPES=Release \
|
||||||
-DJAEGERTRACING_WITH_YAML_CPP=ON ..
|
-DJAEGERTRACING_WITH_YAML_CPP=ON ..
|
||||||
|
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
|
@ -356,10 +394,10 @@ EOF
|
||||||
mkdir .build
|
mkdir .build
|
||||||
cd .build
|
cd .build
|
||||||
|
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||||
-DBUILD_SHARED_LIBS=ON \
|
-DBUILD_SHARED_LIBS=ON \
|
||||||
-DBUILD_PLUGIN=ON \
|
-DBUILD_PLUGIN=ON \
|
||||||
-DBUILD_TESTING=OFF ..
|
-DBUILD_TESTING=OFF ..
|
||||||
|
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
|
@ -375,9 +413,7 @@ git submodule update
|
||||||
cd "$BUILD_PATH"
|
cd "$BUILD_PATH"
|
||||||
git clone -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
|
git clone -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
|
||||||
cd ModSecurity/
|
cd ModSecurity/
|
||||||
# TODO: use a tag once 3.0.3 is released
|
git checkout 973c1f1028429452308bcbce7df8a6283dc59ffe
|
||||||
# checkout v3.0.3
|
|
||||||
# git checkout
|
|
||||||
git submodule init
|
git submodule init
|
||||||
git submodule update
|
git submodule update
|
||||||
sh build.sh
|
sh build.sh
|
||||||
|
|
|
@ -27,6 +27,9 @@ import (
|
||||||
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
"k8s.io/ingress-nginx/internal/ingress/resolver"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// HTTP protocol
|
||||||
|
const HTTP = "HTTP"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
validProtocols = regexp.MustCompile(`^(HTTP|HTTPS|AJP|GRPC|GRPCS)$`)
|
validProtocols = regexp.MustCompile(`^(HTTP|HTTPS|AJP|GRPC|GRPCS)$`)
|
||||||
)
|
)
|
||||||
|
@ -44,18 +47,18 @@ func NewParser(r resolver.Resolver) parser.IngressAnnotation {
|
||||||
// rule used to indicate the backend protocol.
|
// rule used to indicate the backend protocol.
|
||||||
func (a backendProtocol) Parse(ing *extensions.Ingress) (interface{}, error) {
|
func (a backendProtocol) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||||
if ing.GetAnnotations() == nil {
|
if ing.GetAnnotations() == nil {
|
||||||
return "HTTP", nil
|
return HTTP, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
proto, err := parser.GetStringAnnotation("backend-protocol", ing)
|
proto, err := parser.GetStringAnnotation("backend-protocol", ing)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "HTTP", nil
|
return HTTP, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
proto = strings.TrimSpace(strings.ToUpper(proto))
|
proto = strings.TrimSpace(strings.ToUpper(proto))
|
||||||
if !validProtocols.MatchString(proto) {
|
if !validProtocols.MatchString(proto) {
|
||||||
glog.Warningf("Protocol %v is not a valid value for the backend-protocol annotation. Using HTTP as protocol", proto)
|
glog.Warningf("Protocol %v is not a valid value for the backend-protocol annotation. Using HTTP as protocol", proto)
|
||||||
return "HTTP", nil
|
return HTTP, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return proto, nil
|
return proto, nil
|
||||||
|
|
|
@ -31,10 +31,13 @@ var luaRestyWAFModes = map[string]bool{"ACTIVE": true, "INACTIVE": true, "SIMULA
|
||||||
|
|
||||||
// Config returns lua-resty-waf configuration for an Ingress rule
|
// Config returns lua-resty-waf configuration for an Ingress rule
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
Debug bool `json:"debug"`
|
Debug bool `json:"debug"`
|
||||||
IgnoredRuleSets []string `json:"ignored-rulesets"`
|
IgnoredRuleSets []string `json:"ignored-rulesets"`
|
||||||
ExtraRulesetString string `json:"extra-ruleset-string"`
|
ExtraRulesetString string `json:"extra-ruleset-string"`
|
||||||
|
ScoreThreshold int `json:"score-threshold"`
|
||||||
|
AllowUnknownContentTypes bool `json:"allow-unknown-content-types"`
|
||||||
|
ProcessMultipartBody bool `json:"process-multipart-body"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equal tests for equality between two Config types
|
// Equal tests for equality between two Config types
|
||||||
|
@ -57,6 +60,15 @@ func (e1 *Config) Equal(e2 *Config) bool {
|
||||||
if e1.ExtraRulesetString != e2.ExtraRulesetString {
|
if e1.ExtraRulesetString != e2.ExtraRulesetString {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if e1.ScoreThreshold != e2.ScoreThreshold {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if e1.AllowUnknownContentTypes != e2.AllowUnknownContentTypes {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if e1.ProcessMultipartBody != e2.ProcessMultipartBody {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -95,10 +107,22 @@ func (a luarestywaf) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||||
// TODO(elvinefendi) maybe validate the ruleset string here
|
// TODO(elvinefendi) maybe validate the ruleset string here
|
||||||
extraRulesetString, _ := parser.GetStringAnnotation("lua-resty-waf-extra-rules", ing)
|
extraRulesetString, _ := parser.GetStringAnnotation("lua-resty-waf-extra-rules", ing)
|
||||||
|
|
||||||
|
scoreThreshold, _ := parser.GetIntAnnotation("lua-resty-waf-score-threshold", ing)
|
||||||
|
|
||||||
|
allowUnknownContentTypes, _ := parser.GetBoolAnnotation("lua-resty-waf-allow-unknown-content-types", ing)
|
||||||
|
|
||||||
|
processMultipartBody, err := parser.GetBoolAnnotation("lua-resty-waf-process-multipart-body", ing)
|
||||||
|
if err != nil {
|
||||||
|
processMultipartBody = true
|
||||||
|
}
|
||||||
|
|
||||||
return &Config{
|
return &Config{
|
||||||
Mode: mode,
|
Mode: mode,
|
||||||
Debug: debug,
|
Debug: debug,
|
||||||
IgnoredRuleSets: ignoredRuleSets,
|
IgnoredRuleSets: ignoredRuleSets,
|
||||||
ExtraRulesetString: extraRulesetString,
|
ExtraRulesetString: extraRulesetString,
|
||||||
|
ScoreThreshold: scoreThreshold,
|
||||||
|
AllowUnknownContentTypes: allowUnknownContentTypes,
|
||||||
|
ProcessMultipartBody: processMultipartBody,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,9 @@ func TestParse(t *testing.T) {
|
||||||
luaRestyWAFAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf")
|
luaRestyWAFAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf")
|
||||||
luaRestyWAFDebugAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-debug")
|
luaRestyWAFDebugAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-debug")
|
||||||
luaRestyWAFIgnoredRuleSetsAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-ignore-rulesets")
|
luaRestyWAFIgnoredRuleSetsAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-ignore-rulesets")
|
||||||
|
luaRestyWAFScoreThresholdAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-score-threshold")
|
||||||
|
luaRestyWAFAllowUnknownContentTypesAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-allow-unknown-content-types")
|
||||||
|
luaRestyWAFProcessMultipartBody := parser.GetAnnotationWithPrefix("lua-resty-waf-process-multipart-body")
|
||||||
|
|
||||||
ap := NewParser(&resolver.Mock{})
|
ap := NewParser(&resolver.Mock{})
|
||||||
if ap == nil {
|
if ap == nil {
|
||||||
|
@ -43,21 +46,25 @@ func TestParse(t *testing.T) {
|
||||||
{nil, &Config{}},
|
{nil, &Config{}},
|
||||||
{map[string]string{}, &Config{}},
|
{map[string]string{}, &Config{}},
|
||||||
|
|
||||||
{map[string]string{luaRestyWAFAnnotation: "active"}, &Config{Mode: "ACTIVE", Debug: false, IgnoredRuleSets: []string{}}},
|
{map[string]string{luaRestyWAFAnnotation: "active"}, &Config{Mode: "ACTIVE", Debug: false, IgnoredRuleSets: []string{}, ProcessMultipartBody: true}},
|
||||||
{map[string]string{luaRestyWAFDebugAnnotation: "true"}, &Config{Debug: false}},
|
{map[string]string{luaRestyWAFDebugAnnotation: "true"}, &Config{Debug: false}},
|
||||||
|
|
||||||
{map[string]string{luaRestyWAFAnnotation: "active", luaRestyWAFDebugAnnotation: "true"}, &Config{Mode: "ACTIVE", Debug: true, IgnoredRuleSets: []string{}}},
|
{map[string]string{luaRestyWAFAnnotation: "active", luaRestyWAFDebugAnnotation: "true"}, &Config{Mode: "ACTIVE", Debug: true, IgnoredRuleSets: []string{}, ProcessMultipartBody: true}},
|
||||||
{map[string]string{luaRestyWAFAnnotation: "active", luaRestyWAFDebugAnnotation: "false"}, &Config{Mode: "ACTIVE", Debug: false, IgnoredRuleSets: []string{}}},
|
{map[string]string{luaRestyWAFAnnotation: "active", luaRestyWAFDebugAnnotation: "false"}, &Config{Mode: "ACTIVE", Debug: false, IgnoredRuleSets: []string{}, ProcessMultipartBody: true}},
|
||||||
{map[string]string{luaRestyWAFAnnotation: "inactive", luaRestyWAFDebugAnnotation: "true"}, &Config{Mode: "INACTIVE", Debug: true, IgnoredRuleSets: []string{}}},
|
{map[string]string{luaRestyWAFAnnotation: "inactive", luaRestyWAFDebugAnnotation: "true"}, &Config{Mode: "INACTIVE", Debug: true, IgnoredRuleSets: []string{}, ProcessMultipartBody: true}},
|
||||||
|
|
||||||
{map[string]string{
|
{map[string]string{
|
||||||
luaRestyWAFAnnotation: "active",
|
luaRestyWAFAnnotation: "active",
|
||||||
luaRestyWAFDebugAnnotation: "true",
|
luaRestyWAFDebugAnnotation: "true",
|
||||||
luaRestyWAFIgnoredRuleSetsAnnotation: "ruleset1, ruleset2 ruleset3, another.ruleset"},
|
luaRestyWAFIgnoredRuleSetsAnnotation: "ruleset1, ruleset2 ruleset3, another.ruleset",
|
||||||
&Config{Mode: "ACTIVE", Debug: true, IgnoredRuleSets: []string{"ruleset1", "ruleset2", "ruleset3", "another.ruleset"}}},
|
luaRestyWAFScoreThresholdAnnotation: "10",
|
||||||
|
luaRestyWAFAllowUnknownContentTypesAnnotation: "true"},
|
||||||
|
&Config{Mode: "ACTIVE", Debug: true, IgnoredRuleSets: []string{"ruleset1", "ruleset2", "ruleset3", "another.ruleset"}, ScoreThreshold: 10, AllowUnknownContentTypes: true, ProcessMultipartBody: true}},
|
||||||
|
|
||||||
{map[string]string{luaRestyWAFAnnotation: "siMulate", luaRestyWAFDebugAnnotation: "true"}, &Config{Mode: "SIMULATE", Debug: true, IgnoredRuleSets: []string{}}},
|
{map[string]string{luaRestyWAFAnnotation: "siMulate", luaRestyWAFDebugAnnotation: "true"}, &Config{Mode: "SIMULATE", Debug: true, IgnoredRuleSets: []string{}, ProcessMultipartBody: true}},
|
||||||
{map[string]string{luaRestyWAFAnnotation: "siMulateX", luaRestyWAFDebugAnnotation: "true"}, &Config{Debug: false}},
|
{map[string]string{luaRestyWAFAnnotation: "siMulateX", luaRestyWAFDebugAnnotation: "true"}, &Config{Debug: false}},
|
||||||
|
|
||||||
|
{map[string]string{luaRestyWAFAnnotation: "active", luaRestyWAFProcessMultipartBody: "false"}, &Config{Mode: "ACTIVE", ProcessMultipartBody: false, IgnoredRuleSets: []string{}}},
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := &extensions.Ingress{
|
ing := &extensions.Ingress{
|
||||||
|
|
|
@ -39,7 +39,7 @@ type Config struct {
|
||||||
// AppRoot defines the Application Root that the Controller must redirect if it's in '/' context
|
// AppRoot defines the Application Root that the Controller must redirect if it's in '/' context
|
||||||
AppRoot string `json:"appRoot"`
|
AppRoot string `json:"appRoot"`
|
||||||
// UseRegex indicates whether or not the locations use regex paths
|
// UseRegex indicates whether or not the locations use regex paths
|
||||||
UseRegex bool `json:useRegex`
|
UseRegex bool `json:"useRegex"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equal tests for equality between two Redirect types
|
// Equal tests for equality between two Redirect types
|
||||||
|
|
|
@ -191,7 +191,7 @@ func TestUseRegex(t *testing.T) {
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Errorf("expected a App Context")
|
t.Errorf("expected a App Context")
|
||||||
}
|
}
|
||||||
if redirect.UseRegex != true {
|
if !redirect.UseRegex {
|
||||||
t.Errorf("Unexpected value got in UseRegex")
|
t.Errorf("Unexpected value got in UseRegex")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,8 @@ func (n NGINXController) Name() string {
|
||||||
func (n *NGINXController) Check(_ *http.Request) error {
|
func (n *NGINXController) Check(_ *http.Request) error {
|
||||||
|
|
||||||
url := fmt.Sprintf("http://127.0.0.1:%v%v", n.cfg.ListenPorts.Status, ngxHealthPath)
|
url := fmt.Sprintf("http://127.0.0.1:%v%v", n.cfg.ListenPorts.Status, ngxHealthPath)
|
||||||
statusCode, err := simpleGet(url)
|
timeout := n.cfg.HealthCheckTimeout
|
||||||
|
statusCode, err := simpleGet(url, timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -48,7 +49,7 @@ func (n *NGINXController) Check(_ *http.Request) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
url = fmt.Sprintf("http://127.0.0.1:%v/is-dynamic-lb-initialized", n.cfg.ListenPorts.Status)
|
url = fmt.Sprintf("http://127.0.0.1:%v/is-dynamic-lb-initialized", n.cfg.ListenPorts.Status)
|
||||||
statusCode, err = simpleGet(url)
|
statusCode, err = simpleGet(url, timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -75,9 +76,9 @@ func (n *NGINXController) Check(_ *http.Request) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func simpleGet(url string) (int, error) {
|
func simpleGet(url string, timeout time.Duration) (int, error) {
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Timeout: 10 * time.Second,
|
Timeout: timeout * time.Second,
|
||||||
Transport: &http.Transport{DisableKeepAlives: true},
|
Transport: &http.Transport{DisableKeepAlives: true},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,10 +102,10 @@ type Configuration struct {
|
||||||
// By default access logs go to /var/log/nginx/access.log
|
// By default access logs go to /var/log/nginx/access.log
|
||||||
AccessLogPath string `json:"access-log-path,omitempty"`
|
AccessLogPath string `json:"access-log-path,omitempty"`
|
||||||
|
|
||||||
// WorkerCpuAffinity bind nginx worker processes to CPUs this will improve response latency
|
// WorkerCPUAffinity bind nginx worker processes to CPUs this will improve response latency
|
||||||
// http://nginx.org/en/docs/ngx_core_module.html#worker_cpu_affinity
|
// http://nginx.org/en/docs/ngx_core_module.html#worker_cpu_affinity
|
||||||
// By default this is disabled
|
// By default this is disabled
|
||||||
WorkerCpuAffinity string `json:"worker-cpu-affinity,omitempty"`
|
WorkerCPUAffinity string `json:"worker-cpu-affinity,omitempty"`
|
||||||
// ErrorLogPath sets the path of the error logs
|
// ErrorLogPath sets the path of the error logs
|
||||||
// http://nginx.org/en/docs/ngx_core_module.html#error_log
|
// http://nginx.org/en/docs/ngx_core_module.html#error_log
|
||||||
// By default error logs go to /var/log/nginx/error.log
|
// By default error logs go to /var/log/nginx/error.log
|
||||||
|
@ -347,6 +347,10 @@ type Configuration struct {
|
||||||
// http://nginx.org/en/docs/http/ngx_http_geoip_module.html
|
// http://nginx.org/en/docs/http/ngx_http_geoip_module.html
|
||||||
UseGeoIP bool `json:"use-geoip,omitempty"`
|
UseGeoIP bool `json:"use-geoip,omitempty"`
|
||||||
|
|
||||||
|
// UseGeoIP2 enables the geoip2 module for NGINX
|
||||||
|
// By default this is disabled
|
||||||
|
UseGeoIP2 bool `json:"use-geoip2,omitempty"`
|
||||||
|
|
||||||
// Enables or disables the use of the NGINX Brotli Module for compression
|
// Enables or disables the use of the NGINX Brotli Module for compression
|
||||||
// https://github.com/google/ngx_brotli
|
// https://github.com/google/ngx_brotli
|
||||||
EnableBrotli bool `json:"enable-brotli,omitempty"`
|
EnableBrotli bool `json:"enable-brotli,omitempty"`
|
||||||
|
@ -438,11 +442,11 @@ type Configuration struct {
|
||||||
|
|
||||||
// If the request does not have a request-id, should we generate a random value?
|
// If the request does not have a request-id, should we generate a random value?
|
||||||
// Default: true
|
// Default: true
|
||||||
GenerateRequestId bool `json:"generate-request-id,omitempty"`
|
GenerateRequestID bool `json:"generate-request-id,omitempty"`
|
||||||
|
|
||||||
// Adds an X-Original-Uri header with the original request URI to the backend request
|
// Adds an X-Original-Uri header with the original request URI to the backend request
|
||||||
// Default: true
|
// Default: true
|
||||||
ProxyAddOriginalUriHeader bool `json:"proxy-add-original-uri-header"`
|
ProxyAddOriginalURIHeader bool `json:"proxy-add-original-uri-header"`
|
||||||
|
|
||||||
// EnableOpentracing enables the nginx Opentracing extension
|
// EnableOpentracing enables the nginx Opentracing extension
|
||||||
// https://github.com/opentracing-contrib/nginx-opentracing
|
// https://github.com/opentracing-contrib/nginx-opentracing
|
||||||
|
@ -570,7 +574,7 @@ func NewDefault() Configuration {
|
||||||
cfg := Configuration{
|
cfg := Configuration{
|
||||||
AllowBackendServerHeader: false,
|
AllowBackendServerHeader: false,
|
||||||
AccessLogPath: "/var/log/nginx/access.log",
|
AccessLogPath: "/var/log/nginx/access.log",
|
||||||
WorkerCpuAffinity: "",
|
WorkerCPUAffinity: "",
|
||||||
ErrorLogPath: "/var/log/nginx/error.log",
|
ErrorLogPath: "/var/log/nginx/error.log",
|
||||||
BlockCIDRs: defBlockEntity,
|
BlockCIDRs: defBlockEntity,
|
||||||
BlockUserAgents: defBlockEntity,
|
BlockUserAgents: defBlockEntity,
|
||||||
|
@ -587,8 +591,8 @@ func NewDefault() Configuration {
|
||||||
UseForwardedHeaders: true,
|
UseForwardedHeaders: true,
|
||||||
ForwardedForHeader: "X-Forwarded-For",
|
ForwardedForHeader: "X-Forwarded-For",
|
||||||
ComputeFullForwardedFor: false,
|
ComputeFullForwardedFor: false,
|
||||||
ProxyAddOriginalUriHeader: true,
|
ProxyAddOriginalURIHeader: true,
|
||||||
GenerateRequestId: true,
|
GenerateRequestID: true,
|
||||||
HTTP2MaxFieldSize: "4k",
|
HTTP2MaxFieldSize: "4k",
|
||||||
HTTP2MaxHeaderSize: "16k",
|
HTTP2MaxHeaderSize: "16k",
|
||||||
HTTP2MaxRequests: 1000,
|
HTTP2MaxRequests: 1000,
|
||||||
|
@ -630,6 +634,7 @@ func NewDefault() Configuration {
|
||||||
EnableBrotli: false,
|
EnableBrotli: false,
|
||||||
UseGzip: true,
|
UseGzip: true,
|
||||||
UseGeoIP: true,
|
UseGeoIP: true,
|
||||||
|
UseGeoIP2: false,
|
||||||
WorkerProcesses: strconv.Itoa(runtime.NumCPU()),
|
WorkerProcesses: strconv.Itoa(runtime.NumCPU()),
|
||||||
WorkerShutdownTimeout: "10s",
|
WorkerShutdownTimeout: "10s",
|
||||||
LoadBalanceAlgorithm: defaultLoadBalancerAlgorithm,
|
LoadBalanceAlgorithm: defaultLoadBalancerAlgorithm,
|
||||||
|
|
|
@ -61,6 +61,7 @@ type Configuration struct {
|
||||||
ForceNamespaceIsolation bool
|
ForceNamespaceIsolation bool
|
||||||
|
|
||||||
DefaultHealthzURL string
|
DefaultHealthzURL string
|
||||||
|
HealthCheckTimeout time.Duration
|
||||||
DefaultSSLCertificate string
|
DefaultSSLCertificate string
|
||||||
|
|
||||||
// +optional
|
// +optional
|
||||||
|
|
|
@ -18,7 +18,6 @@ package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -257,7 +256,7 @@ func (n *NGINXController) Start() {
|
||||||
n.store.Run(n.stopCh)
|
n.store.Run(n.stopCh)
|
||||||
|
|
||||||
if n.syncStatus != nil {
|
if n.syncStatus != nil {
|
||||||
go n.syncStatus.Run(context.Background())
|
go n.syncStatus.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := nginxExecCommand()
|
cmd := nginxExecCommand()
|
||||||
|
@ -812,12 +811,7 @@ func configureCertificates(pcfg *ingress.Configuration, port int) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("http://localhost:%d/configuration/servers", port)
|
url := fmt.Sprintf("http://localhost:%d/configuration/servers", port)
|
||||||
err := post(url, servers)
|
return post(url, servers)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func post(url string, data interface{}) error {
|
func post(url string, data interface{}) error {
|
||||||
|
|
|
@ -90,7 +90,7 @@ func TestMergeConfigMapToStruct(t *testing.T) {
|
||||||
def.WorkerShutdownTimeout = "99s"
|
def.WorkerShutdownTimeout = "99s"
|
||||||
def.NginxStatusIpv4Whitelist = []string{"127.0.0.1", "10.0.0.0/24"}
|
def.NginxStatusIpv4Whitelist = []string{"127.0.0.1", "10.0.0.0/24"}
|
||||||
def.NginxStatusIpv6Whitelist = []string{"::1", "2001::/16"}
|
def.NginxStatusIpv6Whitelist = []string{"::1", "2001::/16"}
|
||||||
def.ProxyAddOriginalUriHeader = false
|
def.ProxyAddOriginalURIHeader = false
|
||||||
|
|
||||||
hash, err := hashstructure.Hash(def, &hashstructure.HashOptions{
|
hash, err := hashstructure.Hash(def, &hashstructure.HashOptions{
|
||||||
TagName: "json",
|
TagName: "json",
|
||||||
|
|
|
@ -209,8 +209,6 @@ func buildLuaSharedDictionaries(s interface{}, disableLuaRestyWAF bool) string {
|
||||||
"lua_shared_dict configuration_data 5M",
|
"lua_shared_dict configuration_data 5M",
|
||||||
"lua_shared_dict certificate_data 16M",
|
"lua_shared_dict certificate_data 16M",
|
||||||
"lua_shared_dict locks 512k",
|
"lua_shared_dict locks 512k",
|
||||||
"lua_shared_dict balancer_ewma 1M",
|
|
||||||
"lua_shared_dict balancer_ewma_last_touched_at 1M",
|
|
||||||
"lua_shared_dict sticky_sessions 1M",
|
"lua_shared_dict sticky_sessions 1M",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,19 +722,6 @@ func buildUpstreamName(loc interface{}) string {
|
||||||
return upstreamName
|
return upstreamName
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Needs Unit Tests
|
|
||||||
func isSticky(host string, loc *ingress.Location, stickyLocations map[string][]string) bool {
|
|
||||||
if _, ok := stickyLocations[host]; ok {
|
|
||||||
for _, sl := range stickyLocations[host] {
|
|
||||||
if sl == loc.Path {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildNextUpstream(i, r interface{}) string {
|
func buildNextUpstream(i, r interface{}) string {
|
||||||
nextUpstream, ok := i.(string)
|
nextUpstream, ok := i.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -171,7 +171,7 @@ func NewSocketCollector(pod, namespace, class string) (*SocketCollector, error)
|
||||||
bytesSent: prometheus.NewHistogramVec(
|
bytesSent: prometheus.NewHistogramVec(
|
||||||
prometheus.HistogramOpts{
|
prometheus.HistogramOpts{
|
||||||
Name: "bytes_sent",
|
Name: "bytes_sent",
|
||||||
Help: "The the number of bytes sent to a client",
|
Help: "The number of bytes sent to a client",
|
||||||
Namespace: PrometheusNamespace,
|
Namespace: PrometheusNamespace,
|
||||||
Buckets: prometheus.ExponentialBuckets(10, 10, 7), // 7 buckets, exponential factor of 10.
|
Buckets: prometheus.ExponentialBuckets(10, 10, 7), // 7 buckets, exponential factor of 10.
|
||||||
ConstLabels: constLabels,
|
ConstLabels: constLabels,
|
||||||
|
|
|
@ -51,7 +51,7 @@ const (
|
||||||
|
|
||||||
// Sync ...
|
// Sync ...
|
||||||
type Sync interface {
|
type Sync interface {
|
||||||
Run(ctx context.Context)
|
Run()
|
||||||
Shutdown()
|
Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,22 +93,102 @@ type statusSync struct {
|
||||||
pod *k8s.PodInfo
|
pod *k8s.PodInfo
|
||||||
|
|
||||||
elector *leaderelection.LeaderElector
|
elector *leaderelection.LeaderElector
|
||||||
|
|
||||||
// workqueue used to keep in sync the status IP/s
|
// workqueue used to keep in sync the status IP/s
|
||||||
// in the Ingress rules
|
// in the Ingress rules
|
||||||
syncQueue *task.Queue
|
syncQueue *task.Queue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run starts the loop to keep the status in sync
|
// Run starts the loop to keep the status in sync
|
||||||
func (s statusSync) Run(ctx context.Context) {
|
func (s statusSync) Run() {
|
||||||
s.elector.Run(ctx)
|
// we need to use the defined ingress class to allow multiple leaders
|
||||||
|
// in order to update information about ingress status
|
||||||
|
electionID := fmt.Sprintf("%v-%v", s.Config.ElectionID, s.Config.DefaultIngressClass)
|
||||||
|
if s.Config.IngressClass != "" {
|
||||||
|
electionID = fmt.Sprintf("%v-%v", s.Config.ElectionID, s.Config.IngressClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
// start a new context
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
var cancelContext context.CancelFunc
|
||||||
|
|
||||||
|
var newLeaderCtx = func(ctx context.Context) context.CancelFunc {
|
||||||
|
// allow to cancel the context in case we stop being the leader
|
||||||
|
leaderCtx, cancel := context.WithCancel(ctx)
|
||||||
|
go s.elector.Run(leaderCtx)
|
||||||
|
return cancel
|
||||||
|
}
|
||||||
|
|
||||||
|
var stopCh chan struct{}
|
||||||
|
callbacks := leaderelection.LeaderCallbacks{
|
||||||
|
OnStartedLeading: func(ctx context.Context) {
|
||||||
|
glog.V(2).Infof("I am the new status update leader")
|
||||||
|
stopCh = make(chan struct{})
|
||||||
|
go s.syncQueue.Run(time.Second, stopCh)
|
||||||
|
// trigger initial sync
|
||||||
|
s.syncQueue.EnqueueTask(task.GetDummyObject("sync status"))
|
||||||
|
// when this instance is the leader we need to enqueue
|
||||||
|
// an item to trigger the update of the Ingress status.
|
||||||
|
wait.PollUntil(updateInterval, func() (bool, error) {
|
||||||
|
s.syncQueue.EnqueueTask(task.GetDummyObject("sync status"))
|
||||||
|
return false, nil
|
||||||
|
}, stopCh)
|
||||||
|
},
|
||||||
|
OnStoppedLeading: func() {
|
||||||
|
glog.V(2).Infof("I am not status update leader anymore")
|
||||||
|
close(stopCh)
|
||||||
|
|
||||||
|
// cancel the context
|
||||||
|
cancelContext()
|
||||||
|
|
||||||
|
cancelContext = newLeaderCtx(ctx)
|
||||||
|
},
|
||||||
|
OnNewLeader: func(identity string) {
|
||||||
|
glog.Infof("new leader elected: %v", identity)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcaster := record.NewBroadcaster()
|
||||||
|
hostname, _ := os.Hostname()
|
||||||
|
|
||||||
|
recorder := broadcaster.NewRecorder(scheme.Scheme, apiv1.EventSource{
|
||||||
|
Component: "ingress-leader-elector",
|
||||||
|
Host: hostname,
|
||||||
|
})
|
||||||
|
|
||||||
|
lock := resourcelock.ConfigMapLock{
|
||||||
|
ConfigMapMeta: metav1.ObjectMeta{Namespace: s.pod.Namespace, Name: electionID},
|
||||||
|
Client: s.Config.Client.CoreV1(),
|
||||||
|
LockConfig: resourcelock.ResourceLockConfig{
|
||||||
|
Identity: s.pod.Name,
|
||||||
|
EventRecorder: recorder,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ttl := 30 * time.Second
|
||||||
|
var err error
|
||||||
|
s.elector, err = leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{
|
||||||
|
Lock: &lock,
|
||||||
|
LeaseDuration: ttl,
|
||||||
|
RenewDeadline: ttl / 2,
|
||||||
|
RetryPeriod: ttl / 4,
|
||||||
|
Callbacks: callbacks,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
glog.Fatalf("unexpected error starting leader election: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelContext = newLeaderCtx(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown stop the sync. In case the instance is the leader it will remove the current IP
|
// Shutdown stop the sync. In case the instance is the leader it will remove the current IP
|
||||||
// if there is no other instances running.
|
// if there is no other instances running.
|
||||||
func (s statusSync) Shutdown() {
|
func (s statusSync) Shutdown() {
|
||||||
go s.syncQueue.Shutdown()
|
go s.syncQueue.Shutdown()
|
||||||
|
|
||||||
// remove IP from Ingress
|
// remove IP from Ingress
|
||||||
if !s.elector.IsLeader() {
|
if s.elector != nil && !s.elector.IsLeader() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +226,10 @@ func (s *statusSync) sync(key interface{}) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.elector != nil && !s.elector.IsLeader() {
|
||||||
|
return fmt.Errorf("i am not the current leader. Skiping status update")
|
||||||
|
}
|
||||||
|
|
||||||
addrs, err := s.runningAddresses()
|
addrs, err := s.runningAddresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -173,66 +257,6 @@ func NewStatusSyncer(config Config) Sync {
|
||||||
}
|
}
|
||||||
st.syncQueue = task.NewCustomTaskQueue(st.sync, st.keyfunc)
|
st.syncQueue = task.NewCustomTaskQueue(st.sync, st.keyfunc)
|
||||||
|
|
||||||
// we need to use the defined ingress class to allow multiple leaders
|
|
||||||
// in order to update information about ingress status
|
|
||||||
electionID := fmt.Sprintf("%v-%v", config.ElectionID, config.DefaultIngressClass)
|
|
||||||
if config.IngressClass != "" {
|
|
||||||
electionID = fmt.Sprintf("%v-%v", config.ElectionID, config.IngressClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
var stopCh chan struct{}
|
|
||||||
callbacks := leaderelection.LeaderCallbacks{
|
|
||||||
OnStartedLeading: func(ctx context.Context) {
|
|
||||||
glog.V(2).Infof("I am the new status update leader")
|
|
||||||
stopCh = make(chan struct{})
|
|
||||||
go st.syncQueue.Run(time.Second, stopCh)
|
|
||||||
// when this instance is the leader we need to enqueue
|
|
||||||
// an item to trigger the update of the Ingress status.
|
|
||||||
wait.PollUntil(updateInterval, func() (bool, error) {
|
|
||||||
st.syncQueue.EnqueueTask(task.GetDummyObject("sync status"))
|
|
||||||
return false, nil
|
|
||||||
}, stopCh)
|
|
||||||
},
|
|
||||||
OnStoppedLeading: func() {
|
|
||||||
glog.V(2).Infof("I am not status update leader anymore")
|
|
||||||
close(stopCh)
|
|
||||||
},
|
|
||||||
OnNewLeader: func(identity string) {
|
|
||||||
glog.Infof("new leader elected: %v", identity)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
broadcaster := record.NewBroadcaster()
|
|
||||||
hostname, _ := os.Hostname()
|
|
||||||
|
|
||||||
recorder := broadcaster.NewRecorder(scheme.Scheme, apiv1.EventSource{
|
|
||||||
Component: "ingress-leader-elector",
|
|
||||||
Host: hostname,
|
|
||||||
})
|
|
||||||
|
|
||||||
lock := resourcelock.ConfigMapLock{
|
|
||||||
ConfigMapMeta: metav1.ObjectMeta{Namespace: pod.Namespace, Name: electionID},
|
|
||||||
Client: config.Client.CoreV1(),
|
|
||||||
LockConfig: resourcelock.ResourceLockConfig{
|
|
||||||
Identity: pod.Name,
|
|
||||||
EventRecorder: recorder,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
ttl := 30 * time.Second
|
|
||||||
le, err := leaderelection.NewLeaderElector(leaderelection.LeaderElectionConfig{
|
|
||||||
Lock: &lock,
|
|
||||||
LeaseDuration: ttl,
|
|
||||||
RenewDeadline: ttl / 2,
|
|
||||||
RetryPeriod: ttl / 4,
|
|
||||||
Callbacks: callbacks,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
glog.Fatalf("unexpected error starting leader election: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
st.elector = le
|
|
||||||
return st
|
return st
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +357,13 @@ func (s *statusSync) updateStatus(newIngressPoint []apiv1.LoadBalancerIngress) {
|
||||||
sort.SliceStable(newIngressPoint, lessLoadBalancerIngress(newIngressPoint))
|
sort.SliceStable(newIngressPoint, lessLoadBalancerIngress(newIngressPoint))
|
||||||
|
|
||||||
for _, ing := range ings {
|
for _, ing := range ings {
|
||||||
|
curIPs := ing.Status.LoadBalancer.Ingress
|
||||||
|
sort.SliceStable(curIPs, lessLoadBalancerIngress(curIPs))
|
||||||
|
if ingressSliceEqual(curIPs, newIngressPoint) {
|
||||||
|
glog.V(3).Infof("skipping update of Ingress %v/%v (no change)", ing.Namespace, ing.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
batch.Queue(runUpdate(ing, newIngressPoint, s.Client))
|
batch.Queue(runUpdate(ing, newIngressPoint, s.Client))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,14 +378,6 @@ func runUpdate(ing *extensions.Ingress, status []apiv1.LoadBalancerIngress,
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
curIPs := ing.Status.LoadBalancer.Ingress
|
|
||||||
sort.SliceStable(curIPs, lessLoadBalancerIngress(curIPs))
|
|
||||||
|
|
||||||
if ingressSliceEqual(status, curIPs) {
|
|
||||||
glog.V(3).Infof("skipping update of Ingress %v/%v (no change)", ing.Namespace, ing.Name)
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ingClient := client.ExtensionsV1beta1().Ingresses(ing.Namespace)
|
ingClient := client.ExtensionsV1beta1().Ingresses(ing.Namespace)
|
||||||
|
|
||||||
currIng, err := ingClient.Get(ing.Name, metav1.GetOptions{})
|
currIng, err := ingClient.Get(ing.Name, metav1.GetOptions{})
|
||||||
|
@ -398,5 +421,6 @@ func ingressSliceEqual(lhs, rhs []apiv1.LoadBalancerIngress) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||||
package status
|
package status
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -298,7 +297,7 @@ func TestStatusActions(t *testing.T) {
|
||||||
fk := fkSync.(statusSync)
|
fk := fkSync.(statusSync)
|
||||||
|
|
||||||
// start it and wait for the election and syn actions
|
// start it and wait for the election and syn actions
|
||||||
go fk.Run(context.Background())
|
go fk.Run()
|
||||||
// wait for the election
|
// wait for the election
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
// execute sync
|
// execute sync
|
||||||
|
|
|
@ -5,38 +5,17 @@
|
||||||
-- /finagle-core/src/main/scala/com/twitter/finagle/loadbalancer/PeakEwma.scala
|
-- /finagle-core/src/main/scala/com/twitter/finagle/loadbalancer/PeakEwma.scala
|
||||||
|
|
||||||
|
|
||||||
local resty_lock = require("resty.lock")
|
|
||||||
local util = require("util")
|
local util = require("util")
|
||||||
local split = require("util.split")
|
local split = require("util.split")
|
||||||
|
|
||||||
local DECAY_TIME = 10 -- this value is in seconds
|
local DECAY_TIME = 10 -- this value is in seconds
|
||||||
local LOCK_KEY = ":ewma_key"
|
|
||||||
local PICK_SET_SIZE = 2
|
local PICK_SET_SIZE = 2
|
||||||
|
|
||||||
local ewma_lock = resty_lock:new("locks", {timeout = 0, exptime = 0.1})
|
local balancer_ewma = {}
|
||||||
|
local balancer_ewma_last_touched_at = {}
|
||||||
|
|
||||||
local _M = { name = "ewma" }
|
local _M = { name = "ewma" }
|
||||||
|
|
||||||
local function lock(upstream)
|
|
||||||
local _, err = ewma_lock:lock(upstream .. LOCK_KEY)
|
|
||||||
if err then
|
|
||||||
if err ~= "timeout" then
|
|
||||||
ngx.log(ngx.ERR, string.format("EWMA Balancer failed to lock: %s", tostring(err)))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return err
|
|
||||||
end
|
|
||||||
|
|
||||||
local function unlock()
|
|
||||||
local ok, err = ewma_lock:unlock()
|
|
||||||
if not ok then
|
|
||||||
ngx.log(ngx.ERR, string.format("EWMA Balancer failed to unlock: %s", tostring(err)))
|
|
||||||
end
|
|
||||||
|
|
||||||
return err
|
|
||||||
end
|
|
||||||
|
|
||||||
local function decay_ewma(ewma, last_touched_at, rtt, now)
|
local function decay_ewma(ewma, last_touched_at, rtt, now)
|
||||||
local td = now - last_touched_at
|
local td = now - last_touched_at
|
||||||
td = (td > 0) and td or 0
|
td = (td > 0) and td or 0
|
||||||
|
@ -47,40 +26,18 @@ local function decay_ewma(ewma, last_touched_at, rtt, now)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_or_update_ewma(upstream, rtt, update)
|
local function get_or_update_ewma(upstream, rtt, update)
|
||||||
local lock_err = nil
|
local ewma = balancer_ewma[upstream] or 0
|
||||||
if update then
|
|
||||||
lock_err = lock(upstream)
|
|
||||||
end
|
|
||||||
local ewma = ngx.shared.balancer_ewma:get(upstream) or 0
|
|
||||||
if lock_err ~= nil then
|
|
||||||
return ewma, lock_err
|
|
||||||
end
|
|
||||||
|
|
||||||
local now = ngx.now()
|
local now = ngx.now()
|
||||||
local last_touched_at = ngx.shared.balancer_ewma_last_touched_at:get(upstream) or 0
|
local last_touched_at = balancer_ewma_last_touched_at[upstream] or 0
|
||||||
ewma = decay_ewma(ewma, last_touched_at, rtt, now)
|
ewma = decay_ewma(ewma, last_touched_at, rtt, now)
|
||||||
|
|
||||||
if not update then
|
if not update then
|
||||||
return ewma, nil
|
return ewma, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local success, err, forcible = ngx.shared.balancer_ewma_last_touched_at:set(upstream, now)
|
balancer_ewma_last_touched_at[upstream] = now
|
||||||
if not success then
|
balancer_ewma[upstream] = ewma
|
||||||
ngx.log(ngx.WARN, "balancer_ewma_last_touched_at:set failed " .. err)
|
|
||||||
end
|
|
||||||
if forcible then
|
|
||||||
ngx.log(ngx.WARN, "balancer_ewma_last_touched_at:set valid items forcibly overwritten")
|
|
||||||
end
|
|
||||||
|
|
||||||
success, err, forcible = ngx.shared.balancer_ewma:set(upstream, ewma)
|
|
||||||
if not success then
|
|
||||||
ngx.log(ngx.WARN, "balancer_ewma:set failed " .. err)
|
|
||||||
end
|
|
||||||
if forcible then
|
|
||||||
ngx.log(ngx.WARN, "balancer_ewma:set valid items forcibly overwritten")
|
|
||||||
end
|
|
||||||
|
|
||||||
unlock()
|
|
||||||
return ewma, nil
|
return ewma, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -153,8 +110,8 @@ function _M.sync(self, backend)
|
||||||
self.peers = backend.endpoints
|
self.peers = backend.endpoints
|
||||||
|
|
||||||
-- TODO: Reset state of EWMA per backend
|
-- TODO: Reset state of EWMA per backend
|
||||||
ngx.shared.balancer_ewma:flush_all()
|
balancer_ewma = {}
|
||||||
ngx.shared.balancer_ewma_last_touched_at:flush_all()
|
balancer_ewma_last_touched_at = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
function _M.new(self, backend)
|
function _M.new(self, backend)
|
||||||
|
|
|
@ -94,22 +94,17 @@ local function set_cookie(self, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function pick_random(instance)
|
|
||||||
local index = math.random(instance.npoints)
|
|
||||||
return instance:next(index)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _M.balance(self)
|
function _M.balance(self)
|
||||||
local cookie, err = ck:new()
|
local cookie, err = ck:new()
|
||||||
if not cookie then
|
if not cookie then
|
||||||
ngx.log(ngx.ERR, err)
|
ngx.log(ngx.ERR, "error while initializing cookie: " .. tostring(err))
|
||||||
return pick_random(self.instance)
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local key = cookie:get(self.cookie_name)
|
local key = cookie:get(self.cookie_name)
|
||||||
if not key then
|
if not key then
|
||||||
local tmp_endpoint_string = pick_random(self.instance)
|
local random_str = string.format("%s.%s", ngx.now(), ngx.worker.pid())
|
||||||
key = encrypted_endpoint_string(self, tmp_endpoint_string)
|
key = encrypted_endpoint_string(self, random_str)
|
||||||
set_cookie(self, key)
|
set_cookie(self, key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,6 @@ describe("Balancer ewma", function()
|
||||||
local instance = balancer_ewma:new(backend)
|
local instance = balancer_ewma:new(backend)
|
||||||
|
|
||||||
local stats = { ["10.184.7.40:8080"] = 0.5, ["10.184.97.100:8080"] = 0.3 }
|
local stats = { ["10.184.7.40:8080"] = 0.5, ["10.184.97.100:8080"] = 0.3 }
|
||||||
ngx.shared.balancer_ewma.get = function(self, key) return stats[key] end
|
|
||||||
local t = ngx.now()-10
|
|
||||||
ngx.shared.balancer_ewma_last_touched_at.get = function(self, key) return t end
|
|
||||||
|
|
||||||
|
|
||||||
local peer = instance:balance()
|
local peer = instance:balance()
|
||||||
assert.equal("10.184.97.100:8080", peer)
|
assert.equal("10.184.97.100:8080", peer)
|
||||||
|
@ -52,13 +48,7 @@ describe("Balancer ewma", function()
|
||||||
endpoints = { { address = "10.184.7.40", port = "8080", maxFails = 0, failTimeout = 0 } }
|
endpoints = { { address = "10.184.7.40", port = "8080", maxFails = 0, failTimeout = 0 } }
|
||||||
}
|
}
|
||||||
|
|
||||||
local s1 = spy.on(ngx.shared.balancer_ewma, "flush_all")
|
|
||||||
local s2 = spy.on(ngx.shared.balancer_ewma_last_touched_at, "flush_all")
|
|
||||||
|
|
||||||
instance:sync(new_backend)
|
instance:sync(new_backend)
|
||||||
|
|
||||||
assert.spy(s1).was_not_called()
|
|
||||||
assert.spy(s2).was_not_called()
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("updates endpoints", function()
|
it("updates endpoints", function()
|
||||||
|
@ -77,13 +67,7 @@ describe("Balancer ewma", function()
|
||||||
local new_backend = util.deepcopy(backend)
|
local new_backend = util.deepcopy(backend)
|
||||||
new_backend.endpoints[1].maxFails = 3
|
new_backend.endpoints[1].maxFails = 3
|
||||||
|
|
||||||
local s1 = spy.on(ngx.shared.balancer_ewma, "flush_all")
|
|
||||||
local s2 = spy.on(ngx.shared.balancer_ewma_last_touched_at, "flush_all")
|
|
||||||
|
|
||||||
instance:sync(new_backend)
|
instance:sync(new_backend)
|
||||||
|
|
||||||
assert.spy(s1).was_called()
|
|
||||||
assert.spy(s2).was_called()
|
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -116,7 +116,8 @@ describe("Sticky", function()
|
||||||
local cookie_instance = {
|
local cookie_instance = {
|
||||||
set = function(self, payload)
|
set = function(self, payload)
|
||||||
assert.equal(payload.key, test_backend.sessionAffinityConfig.cookieSessionAffinity.name)
|
assert.equal(payload.key, test_backend.sessionAffinityConfig.cookieSessionAffinity.name)
|
||||||
assert.equal(payload.value, util[test_backend_hash_fn .. "_digest"](test_backend_endpoint))
|
local expected_len = #util[test_backend_hash_fn .. "_digest"]("anything")
|
||||||
|
assert.equal(#payload.value, expected_len)
|
||||||
assert.equal(payload.path, ngx.var.location_path)
|
assert.equal(payload.path, ngx.var.location_path)
|
||||||
assert.equal(payload.domain, nil)
|
assert.equal(payload.domain, nil)
|
||||||
assert.equal(payload.httponly, true)
|
assert.equal(payload.httponly, true)
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
# setup custom paths that do not require root access
|
# setup custom paths that do not require root access
|
||||||
pid /tmp/nginx.pid;
|
pid /tmp/nginx.pid;
|
||||||
|
|
||||||
|
{{ if $cfg.UseGeoIP2 }}
|
||||||
|
load_module /etc/nginx/modules/ngx_http_geoip2_module.so;
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
{{ if $cfg.EnableModsecurity }}
|
{{ if $cfg.EnableModsecurity }}
|
||||||
load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;
|
load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -23,8 +27,8 @@ load_module /etc/nginx/modules/ngx_http_opentracing_module.so;
|
||||||
daemon off;
|
daemon off;
|
||||||
|
|
||||||
worker_processes {{ $cfg.WorkerProcesses }};
|
worker_processes {{ $cfg.WorkerProcesses }};
|
||||||
{{ if gt (len $cfg.WorkerCpuAffinity) 0 }}
|
{{ if gt (len $cfg.WorkerCPUAffinity) 0 }}
|
||||||
worker_cpu_affinity {{ $cfg.WorkerCpuAffinity }};
|
worker_cpu_affinity {{ $cfg.WorkerCPUAffinity }};
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ if ne .MaxOpenFiles 0 }}
|
{{ if ne .MaxOpenFiles 0 }}
|
||||||
|
@ -123,6 +127,26 @@ http {
|
||||||
geoip_proxy_recursive on;
|
geoip_proxy_recursive on;
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if $cfg.UseGeoIP2 }}
|
||||||
|
# https://github.com/leev/ngx_http_geoip2_module#example-usage
|
||||||
|
|
||||||
|
geoip2 /etc/nginx/geoip/GeoLite2-City.mmdb {
|
||||||
|
$geoip2_city_country_code source=$the_real_ip country iso_code;
|
||||||
|
$geoip2_city_country_name source=$the_real_ip country names en;
|
||||||
|
$geoip2_city source=$the_real_ip city names en;
|
||||||
|
$geoip2_postal_code source=$the_real_ip postal code;
|
||||||
|
$geoip2_dma_code source=$the_real_ip location metro_code;
|
||||||
|
$geoip2_latitude source=$the_real_ip location latitude;
|
||||||
|
$geoip2_longitude source=$the_real_ip location longitude;
|
||||||
|
$geoip2_region_code source=$the_real_ip subdivisions 0 iso_code;
|
||||||
|
$geoip2_region_name source=$the_real_ip subdivisions 0 names en;
|
||||||
|
}
|
||||||
|
|
||||||
|
geoip2 /etc/nginx/geoip/GeoLite2-ASN.mmdb {
|
||||||
|
$geoip2_asn source=$the_real_ip autonomous_system_number;
|
||||||
|
}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
aio threads;
|
aio threads;
|
||||||
aio_write on;
|
aio_write on;
|
||||||
|
|
||||||
|
@ -322,7 +346,7 @@ http {
|
||||||
# If no such header is provided, it can provide a random value.
|
# If no such header is provided, it can provide a random value.
|
||||||
map $http_x_request_id $req_id {
|
map $http_x_request_id $req_id {
|
||||||
default $http_x_request_id;
|
default $http_x_request_id;
|
||||||
{{ if $cfg.GenerateRequestId }}
|
{{ if $cfg.GenerateRequestID }}
|
||||||
"" $request_id;
|
"" $request_id;
|
||||||
{{ end }}
|
{{ end }}
|
||||||
}
|
}
|
||||||
|
@ -891,9 +915,23 @@ stream {
|
||||||
|
|
||||||
waf:set_option("mode", "{{ $location.LuaRestyWAF.Mode }}")
|
waf:set_option("mode", "{{ $location.LuaRestyWAF.Mode }}")
|
||||||
waf:set_option("storage_zone", "waf_storage")
|
waf:set_option("storage_zone", "waf_storage")
|
||||||
|
|
||||||
|
{{ if $location.LuaRestyWAF.AllowUnknownContentTypes }}
|
||||||
|
waf:set_option("allow_unknown_content_types", true)
|
||||||
|
{{ else }}
|
||||||
waf:set_option("allowed_content_types", { "text/html", "text/json", "application/json" })
|
waf:set_option("allowed_content_types", { "text/html", "text/json", "application/json" })
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
waf:set_option("event_log_level", ngx.WARN)
|
waf:set_option("event_log_level", ngx.WARN)
|
||||||
|
|
||||||
|
{{ if gt $location.LuaRestyWAF.ScoreThreshold 0 }}
|
||||||
|
waf:set_option("score_threshold", {{ $location.LuaRestyWAF.ScoreThreshold }})
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if not $location.LuaRestyWAF.ProcessMultipartBody }}
|
||||||
|
waf:set_option("process_multipart_body", false)
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
{{ if $location.LuaRestyWAF.Debug }}
|
{{ if $location.LuaRestyWAF.Debug }}
|
||||||
waf:set_option("debug", true)
|
waf:set_option("debug", true)
|
||||||
waf:set_option("event_log_request_arguments", true)
|
waf:set_option("event_log_request_arguments", true)
|
||||||
|
@ -1077,7 +1115,7 @@ stream {
|
||||||
{{ $proxySetHeader }} X-Forwarded-Host $best_http_host;
|
{{ $proxySetHeader }} X-Forwarded-Host $best_http_host;
|
||||||
{{ $proxySetHeader }} X-Forwarded-Port $pass_port;
|
{{ $proxySetHeader }} X-Forwarded-Port $pass_port;
|
||||||
{{ $proxySetHeader }} X-Forwarded-Proto $pass_access_scheme;
|
{{ $proxySetHeader }} X-Forwarded-Proto $pass_access_scheme;
|
||||||
{{ if $all.Cfg.ProxyAddOriginalUriHeader }}
|
{{ if $all.Cfg.ProxyAddOriginalURIHeader }}
|
||||||
{{ $proxySetHeader }} X-Original-URI $request_uri;
|
{{ $proxySetHeader }} X-Original-URI $request_uri;
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ $proxySetHeader }} X-Scheme $pass_access_scheme;
|
{{ $proxySetHeader }} X-Scheme $pass_access_scheme;
|
||||||
|
@ -1135,7 +1173,6 @@ stream {
|
||||||
proxy_set_header X-Service-Port $service_port;
|
proxy_set_header X-Service-Port $service_port;
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ if not (empty $location.Backend) }}
|
|
||||||
{{ buildProxyPass $server.Hostname $all.Backends $location }}
|
{{ buildProxyPass $server.Hostname $all.Backends $location }}
|
||||||
{{ if (or (eq $location.Proxy.ProxyRedirectFrom "default") (eq $location.Proxy.ProxyRedirectFrom "off")) }}
|
{{ if (or (eq $location.Proxy.ProxyRedirectFrom "default") (eq $location.Proxy.ProxyRedirectFrom "off")) }}
|
||||||
proxy_redirect {{ $location.Proxy.ProxyRedirectFrom }};
|
proxy_redirect {{ $location.Proxy.ProxyRedirectFrom }};
|
||||||
|
@ -1143,10 +1180,6 @@ stream {
|
||||||
proxy_redirect {{ $location.Proxy.ProxyRedirectFrom }} {{ $location.Proxy.ProxyRedirectTo }};
|
proxy_redirect {{ $location.Proxy.ProxyRedirectFrom }} {{ $location.Proxy.ProxyRedirectTo }};
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ else }}
|
{{ else }}
|
||||||
# No endpoints available for the request
|
|
||||||
return 503;
|
|
||||||
{{ end }}
|
|
||||||
{{ else }}
|
|
||||||
# Location denied. Reason: {{ $location.Denied | printf "%q" }}
|
# Location denied. Reason: {{ $location.Denied | printf "%q" }}
|
||||||
return 503;
|
return 503;
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
@ -16,23 +16,27 @@ limitations under the License.
|
||||||
|
|
||||||
package annotations
|
package annotations
|
||||||
|
|
||||||
/*
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "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 - Affinity/Sticky Sessions", func() {
|
||||||
// TODO(elvinefendi) merge this with Affinity tests in test/e2e/lua/dynamic_configuration.go
|
|
||||||
var _ = framework.IngressNginxDescribe("Annotations - Affinity", func() {
|
|
||||||
f := framework.NewDefaultFramework("affinity")
|
f := framework.NewDefaultFramework("affinity")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.DisableDynamicConfiguration()
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.NewEchoDeploymentWithReplicas(2)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -46,16 +50,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Affinity", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "proxy_pass http://sticky-"+f.IngressController.Namespace+"-http-svc-80;")
|
return strings.Contains(server, fmt.Sprintf("server_name %s ;", host))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -67,36 +67,6 @@ var _ = framework.IngressNginxDescribe("Annotations - Affinity", func() {
|
||||||
Expect(resp.Header.Get("Set-Cookie")).Should(ContainSubstring("SERVERID="))
|
Expect(resp.Header.Get("Set-Cookie")).Should(ContainSubstring("SERVERID="))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should redirect to '/something' with enabled affinity", func() {
|
|
||||||
host := "example.com"
|
|
||||||
annotations := map[string]string{
|
|
||||||
"nginx.ingress.kubernetes.io/affinity": "cookie",
|
|
||||||
"nginx.ingress.kubernetes.io/session-cookie-name": "SERVERID",
|
|
||||||
}
|
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", 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, "proxy_pass http://sticky-"+f.IngressController.Namespace+"-http-svc-80;")
|
|
||||||
})
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, body, errs := gorequest.New().
|
|
||||||
Get(f.IngressController.HTTPURL).
|
|
||||||
Set("Host", host).
|
|
||||||
End()
|
|
||||||
|
|
||||||
Expect(len(errs)).Should(BeNumerically("==", 0))
|
|
||||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
|
||||||
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() {
|
It("should set the path to /something on the generated cookie", func() {
|
||||||
host := "example.com"
|
host := "example.com"
|
||||||
annotations := map[string]string{
|
annotations := map[string]string{
|
||||||
|
@ -105,16 +75,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Affinity", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/something", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/something", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "proxy_pass http://sticky-"+f.IngressController.Namespace+"-http-svc-80;")
|
return strings.Contains(server, fmt.Sprintf("server_name %s ;", host))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL+"/something").
|
Get(f.IngressController.HTTPURL+"/something").
|
||||||
|
@ -126,14 +92,14 @@ var _ = framework.IngressNginxDescribe("Annotations - Affinity", func() {
|
||||||
Expect(resp.Header.Get("Set-Cookie")).Should(ContainSubstring("Path=/something"))
|
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() {
|
It("does not set the path to / on the generated cookie if there's more than one rule referring to the same backend", func() {
|
||||||
host := "example.com"
|
host := "example.com"
|
||||||
annotations := map[string]string{
|
annotations := map[string]string{
|
||||||
"nginx.ingress.kubernetes.io/affinity": "cookie",
|
"nginx.ingress.kubernetes.io/affinity": "cookie",
|
||||||
"nginx.ingress.kubernetes.io/session-cookie-name": "SERVERID",
|
"nginx.ingress.kubernetes.io/session-cookie-name": "SERVERID",
|
||||||
}
|
}
|
||||||
|
|
||||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
f.EnsureIngress(&v1beta1.Ingress{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: host,
|
Name: host,
|
||||||
Namespace: f.IngressController.Namespace,
|
Namespace: f.IngressController.Namespace,
|
||||||
|
@ -168,14 +134,10 @@ var _ = framework.IngressNginxDescribe("Annotations - Affinity", func() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "proxy_pass http://sticky-"+f.IngressController.Namespace+"-http-svc-80;")
|
return strings.Contains(server, fmt.Sprintf("server_name %s ;", host))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL+"/something").
|
Get(f.IngressController.HTTPURL+"/something").
|
||||||
|
@ -184,7 +146,15 @@ var _ = framework.IngressNginxDescribe("Annotations - Affinity", func() {
|
||||||
|
|
||||||
Expect(len(errs)).Should(BeNumerically("==", 0))
|
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||||
Expect(resp.Header.Get("Set-Cookie")).Should(ContainSubstring("Path=/;"))
|
Expect(resp.Header.Get("Set-Cookie")).Should(ContainSubstring("Path=/something;"))
|
||||||
|
|
||||||
|
resp, _, errs = gorequest.New().
|
||||||
|
Get(f.IngressController.HTTPURL+"/somewhereelese").
|
||||||
|
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=/somewhereelese;"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
*/
|
|
||||||
|
|
|
@ -31,8 +31,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Alias", func() {
|
||||||
f := framework.NewDefaultFramework("alias")
|
f := framework.NewDefaultFramework("alias")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -43,17 +42,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Alias", func() {
|
||||||
annotations := map[string]string{}
|
annotations := map[string]string{}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("server_name foo")) &&
|
return Expect(server).Should(ContainSubstring("server_name foo")) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -81,17 +76,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Alias", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("server_name foo")) &&
|
return Expect(server).Should(ContainSubstring("server_name foo")) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
hosts := []string{"foo", "bar"}
|
hosts := []string{"foo", "bar"}
|
||||||
for _, host := range hosts {
|
for _, host := range hosts {
|
||||||
|
|
66
test/e2e/annotations/approot.go
Normal file
66
test/e2e/annotations/approot.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
"github.com/parnurzeal/gorequest"
|
||||||
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = framework.IngressNginxDescribe("Annotations - Approot", func() {
|
||||||
|
f := framework.NewDefaultFramework("approot")
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should redirect to /foo", func() {
|
||||||
|
host := "approot.bar.com"
|
||||||
|
|
||||||
|
annotations := map[string]string{
|
||||||
|
"nginx.ingress.kubernetes.io/app-root": "/foo",
|
||||||
|
}
|
||||||
|
|
||||||
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
|
f.WaitForNginxServer(host,
|
||||||
|
func(server string) bool {
|
||||||
|
return Expect(server).Should(ContainSubstring(`if ($uri = /) {`)) &&
|
||||||
|
Expect(server).Should(ContainSubstring(`return 302 /foo;`))
|
||||||
|
})
|
||||||
|
|
||||||
|
resp, _, errs := gorequest.New().
|
||||||
|
Get(f.IngressController.HTTPURL).
|
||||||
|
Retry(10, 1*time.Second, http.StatusNotFound).
|
||||||
|
RedirectPolicy(noRedirectPolicyFunc).
|
||||||
|
Set("Host", host).
|
||||||
|
End()
|
||||||
|
|
||||||
|
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||||
|
Expect(resp.StatusCode).Should(Equal(http.StatusFound))
|
||||||
|
Expect(resp.Header.Get("Location")).Should(Equal("http://approot.bar.com/foo"))
|
||||||
|
})
|
||||||
|
})
|
|
@ -25,6 +25,7 @@ import (
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/parnurzeal/gorequest"
|
"github.com/parnurzeal/gorequest"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
@ -39,8 +40,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
f := framework.NewDefaultFramework("auth")
|
f := framework.NewDefaultFramework("auth")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -50,17 +50,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
host := "auth"
|
host := "auth"
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -82,17 +78,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
||||||
Expect(server).Should(ContainSubstring("return 503"))
|
Expect(server).Should(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -108,10 +100,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
It("should return status code 401 when authentication is configured but Authorization header is not configured", func() {
|
It("should return status code 401 when authentication is configured but Authorization header is not configured", func() {
|
||||||
host := "auth"
|
host := "auth"
|
||||||
|
|
||||||
s, err := f.EnsureSecret(buildSecret("foo", "bar", "test", f.IngressController.Namespace))
|
s := f.EnsureSecret(buildSecret("foo", "bar", "test", f.IngressController.Namespace))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(s).NotTo(BeNil())
|
|
||||||
Expect(s.ObjectMeta).NotTo(BeNil())
|
|
||||||
|
|
||||||
annotations := map[string]string{
|
annotations := map[string]string{
|
||||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||||
|
@ -120,17 +109,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -146,10 +131,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
It("should return status code 401 when authentication is configured and Authorization header is sent with invalid credentials", func() {
|
It("should return status code 401 when authentication is configured and Authorization header is sent with invalid credentials", func() {
|
||||||
host := "auth"
|
host := "auth"
|
||||||
|
|
||||||
s, err := f.EnsureSecret(buildSecret("foo", "bar", "test", f.IngressController.Namespace))
|
s := f.EnsureSecret(buildSecret("foo", "bar", "test", f.IngressController.Namespace))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(s).NotTo(BeNil())
|
|
||||||
Expect(s.ObjectMeta).NotTo(BeNil())
|
|
||||||
|
|
||||||
annotations := map[string]string{
|
annotations := map[string]string{
|
||||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||||
|
@ -158,17 +140,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -185,10 +163,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
It("should return status code 200 when authentication is configured and Authorization header is sent", func() {
|
It("should return status code 200 when authentication is configured and Authorization header is sent", func() {
|
||||||
host := "auth"
|
host := "auth"
|
||||||
|
|
||||||
s, err := f.EnsureSecret(buildSecret("foo", "bar", "test", f.IngressController.Namespace))
|
s := f.EnsureSecret(buildSecret("foo", "bar", "test", f.IngressController.Namespace))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(s).NotTo(BeNil())
|
|
||||||
Expect(s.ObjectMeta).NotTo(BeNil())
|
|
||||||
|
|
||||||
annotations := map[string]string{
|
annotations := map[string]string{
|
||||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||||
|
@ -197,17 +172,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -223,7 +194,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
It("should return status code 500 when authentication is configured with invalid content and Authorization header is sent", func() {
|
It("should return status code 500 when authentication is configured with invalid content and Authorization header is sent", func() {
|
||||||
host := "auth"
|
host := "auth"
|
||||||
|
|
||||||
s, err := f.EnsureSecret(
|
s := f.EnsureSecret(
|
||||||
&corev1.Secret{
|
&corev1.Secret{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
|
@ -236,9 +207,6 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
Type: corev1.SecretTypeOpaque,
|
Type: corev1.SecretTypeOpaque,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(s).NotTo(BeNil())
|
|
||||||
Expect(s.ObjectMeta).NotTo(BeNil())
|
|
||||||
|
|
||||||
annotations := map[string]string{
|
annotations := map[string]string{
|
||||||
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
"nginx.ingress.kubernetes.io/auth-type": "basic",
|
||||||
|
@ -247,17 +215,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
return Expect(server).Should(ContainSubstring("server_name auth")) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -274,11 +238,10 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
host := "auth"
|
host := "auth"
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewHttpbinDeployment()
|
f.NewHttpbinDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
var httpbinIP string
|
var httpbinIP string
|
||||||
err = wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
|
err := wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
|
||||||
e, err := f.KubeClientSet.CoreV1().Endpoints(f.IngressController.Namespace).Get("httpbin", metav1.GetOptions{})
|
e, err := f.KubeClientSet.CoreV1().Endpoints(f.IngressController.Namespace).Get("httpbin", metav1.GetOptions{})
|
||||||
if errors.IsNotFound(err) {
|
if errors.IsNotFound(err) {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@ -300,15 +263,11 @@ var _ = framework.IngressNginxDescribe("Annotations - Auth", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host, func(server string) bool {
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host, func(server string) bool {
|
|
||||||
return Expect(server).ShouldNot(ContainSubstring("return 503"))
|
return Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should return status code 200 when signed in", func() {
|
It("should return status code 200 when signed in", func() {
|
||||||
|
|
|
@ -19,20 +19,20 @@ package annotations
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"github.com/parnurzeal/gorequest"
|
"github.com/parnurzeal/gorequest"
|
||||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = framework.IngressNginxDescribe("Annotations - AuthTLS", func() {
|
var _ = framework.IngressNginxDescribe("Annotations - AuthTLS", func() {
|
||||||
f := framework.NewDefaultFramework("authtls")
|
f := framework.NewDefaultFramework("authtls")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -54,10 +54,7 @@ var _ = framework.IngressNginxDescribe("Annotations - AuthTLS", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngressWithTLS(host, "/", host, nameSpace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngressWithTLS(host, "/", host, nameSpace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
// Since we can use the same certificate-chain for tls as well as mutual-auth, we will check all values
|
// Since we can use the same certificate-chain for tls as well as mutual-auth, we will check all values
|
||||||
sslCertDirective := fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", nameSpace, host)
|
sslCertDirective := fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", nameSpace, host)
|
||||||
|
@ -67,11 +64,14 @@ var _ = framework.IngressNginxDescribe("Annotations - AuthTLS", func() {
|
||||||
sslVerify := "ssl_verify_client on;"
|
sslVerify := "ssl_verify_client on;"
|
||||||
sslVerifyDepth := "ssl_verify_depth 1;"
|
sslVerifyDepth := "ssl_verify_depth 1;"
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, sslCertDirective) && strings.Contains(server, sslKeyDirective) && strings.Contains(server, sslClientCertDirective) && strings.Contains(server, sslVerify) && strings.Contains(server, sslVerifyDepth)
|
return strings.Contains(server, sslCertDirective) &&
|
||||||
|
strings.Contains(server, sslKeyDirective) &&
|
||||||
|
strings.Contains(server, sslClientCertDirective) &&
|
||||||
|
strings.Contains(server, sslVerify) &&
|
||||||
|
strings.Contains(server, sslVerifyDepth)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
// Send Request without Client Certs
|
// Send Request without Client Certs
|
||||||
req := gorequest.New()
|
req := gorequest.New()
|
||||||
|
@ -112,10 +112,7 @@ var _ = framework.IngressNginxDescribe("Annotations - AuthTLS", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngressWithTLS(host, "/", host, nameSpace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngressWithTLS(host, "/", host, nameSpace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
// Since we can use the same certificate-chain for tls as well as mutual-auth, we will check all values
|
// Since we can use the same certificate-chain for tls as well as mutual-auth, we will check all values
|
||||||
sslCertDirective := fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", nameSpace, host)
|
sslCertDirective := fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", nameSpace, host)
|
||||||
|
@ -125,11 +122,10 @@ var _ = framework.IngressNginxDescribe("Annotations - AuthTLS", func() {
|
||||||
sslVerify := "ssl_verify_client off;"
|
sslVerify := "ssl_verify_client off;"
|
||||||
sslVerifyDepth := "ssl_verify_depth 2;"
|
sslVerifyDepth := "ssl_verify_depth 2;"
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, sslCertDirective) && strings.Contains(server, sslKeyDirective) && strings.Contains(server, sslClientCertDirective) && strings.Contains(server, sslVerify) && strings.Contains(server, sslVerifyDepth)
|
return strings.Contains(server, sslCertDirective) && strings.Contains(server, sslKeyDirective) && strings.Contains(server, sslClientCertDirective) && strings.Contains(server, sslVerify) && strings.Contains(server, sslVerifyDepth)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
// Send Request without Client Certs
|
// Send Request without Client Certs
|
||||||
req := gorequest.New()
|
req := gorequest.New()
|
||||||
|
@ -163,9 +159,7 @@ var _ = framework.IngressNginxDescribe("Annotations - AuthTLS", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngressWithTLS(host, "/", host, nameSpace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngressWithTLS(host, "/", host, nameSpace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
// Since we can use the same certificate-chain for tls as well as mutual-auth, we will check all values
|
// Since we can use the same certificate-chain for tls as well as mutual-auth, we will check all values
|
||||||
sslCertDirective := fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", nameSpace, host)
|
sslCertDirective := fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", nameSpace, host)
|
||||||
|
@ -177,11 +171,16 @@ var _ = framework.IngressNginxDescribe("Annotations - AuthTLS", func() {
|
||||||
sslErrorPage := fmt.Sprintf("error_page 495 496 = %s;", f.IngressController.HTTPURL+errorPath)
|
sslErrorPage := fmt.Sprintf("error_page 495 496 = %s;", f.IngressController.HTTPURL+errorPath)
|
||||||
sslUpstreamClientCert := "proxy_set_header ssl-client-cert $ssl_client_escaped_cert;"
|
sslUpstreamClientCert := "proxy_set_header ssl-client-cert $ssl_client_escaped_cert;"
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, sslCertDirective) && strings.Contains(server, sslKeyDirective) && strings.Contains(server, sslClientCertDirective) && strings.Contains(server, sslVerify) && strings.Contains(server, sslVerifyDepth) && strings.Contains(server, sslErrorPage) && strings.Contains(server, sslUpstreamClientCert)
|
return strings.Contains(server, sslCertDirective) &&
|
||||||
|
strings.Contains(server, sslKeyDirective) &&
|
||||||
|
strings.Contains(server, sslClientCertDirective) &&
|
||||||
|
strings.Contains(server, sslVerify) &&
|
||||||
|
strings.Contains(server, sslVerifyDepth) &&
|
||||||
|
strings.Contains(server, sslErrorPage) &&
|
||||||
|
strings.Contains(server, sslUpstreamClientCert)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
// Send Request without Client Certs
|
// Send Request without Client Certs
|
||||||
req := gorequest.New()
|
req := gorequest.New()
|
||||||
|
|
|
@ -26,8 +26,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Backendprotocol", func() {
|
||||||
f := framework.NewDefaultFramework("backendprotocol")
|
f := framework.NewDefaultFramework("backendprotocol")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -40,16 +39,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Backendprotocol", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("proxy_pass https://upstream_balancer;"))
|
return Expect(server).Should(ContainSubstring("proxy_pass https://upstream_balancer;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set backend protocol to grpc://", func() {
|
It("should set backend protocol to grpc://", func() {
|
||||||
|
@ -59,16 +54,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Backendprotocol", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("grpc_pass grpc://upstream_balancer;"))
|
return Expect(server).Should(ContainSubstring("grpc_pass grpc://upstream_balancer;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set backend protocol to grpcs://", func() {
|
It("should set backend protocol to grpcs://", func() {
|
||||||
|
@ -78,16 +69,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Backendprotocol", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("grpc_pass grpcs://upstream_balancer;"))
|
return Expect(server).Should(ContainSubstring("grpc_pass grpcs://upstream_balancer;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set backend protocol to ''", func() {
|
It("should set backend protocol to ''", func() {
|
||||||
|
@ -97,15 +84,11 @@ var _ = framework.IngressNginxDescribe("Annotations - Backendprotocol", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("ajp_pass upstream_balancer;"))
|
return Expect(server).Should(ContainSubstring("ajp_pass upstream_balancer;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -26,8 +26,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Client-Body-Buffer-Size",
|
||||||
f := framework.NewDefaultFramework("clientbodybuffersize")
|
f := framework.NewDefaultFramework("clientbodybuffersize")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -40,16 +39,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Client-Body-Buffer-Size",
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1000;"))
|
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1000;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set client_body_buffer_size to 1K", func() {
|
It("should set client_body_buffer_size to 1K", func() {
|
||||||
|
@ -59,16 +54,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Client-Body-Buffer-Size",
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1K;"))
|
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1K;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set client_body_buffer_size to 1k", func() {
|
It("should set client_body_buffer_size to 1k", func() {
|
||||||
|
@ -78,16 +69,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Client-Body-Buffer-Size",
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1k;"))
|
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1k;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set client_body_buffer_size to 1m", func() {
|
It("should set client_body_buffer_size to 1m", func() {
|
||||||
|
@ -97,16 +84,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Client-Body-Buffer-Size",
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1m;"))
|
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1m;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set client_body_buffer_size to 1M", func() {
|
It("should set client_body_buffer_size to 1M", func() {
|
||||||
|
@ -116,16 +99,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Client-Body-Buffer-Size",
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("client_body_buffer_size 1M;"))
|
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() {
|
It("should not set client_body_buffer_size to invalid 1b", func() {
|
||||||
|
@ -135,15 +114,11 @@ var _ = framework.IngressNginxDescribe("Annotations - Client-Body-Buffer-Size",
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).ShouldNot(ContainSubstring("client_body_buffer_size 1b;"))
|
return Expect(server).ShouldNot(ContainSubstring("client_body_buffer_size 1b;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -31,8 +31,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Connection", func() {
|
||||||
f := framework.NewDefaultFramework("connection")
|
f := framework.NewDefaultFramework("connection")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -45,16 +44,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Connection", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring(`proxy_set_header Connection keep-alive;`))
|
return Expect(server).Should(ContainSubstring(`proxy_set_header Connection keep-alive;`))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
|
|
@ -17,10 +17,11 @@ limitations under the License.
|
||||||
package annotations
|
package annotations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"github.com/parnurzeal/gorequest"
|
"github.com/parnurzeal/gorequest"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
)
|
)
|
||||||
|
@ -29,8 +30,7 @@ var _ = framework.IngressNginxDescribe("Annotations - CORS", func() {
|
||||||
f := framework.NewDefaultFramework("cors")
|
f := framework.NewDefaultFramework("cors")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -43,40 +43,32 @@ var _ = framework.IngressNginxDescribe("Annotations - CORS", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS';"))
|
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS';"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Origin: *';"))
|
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Origin: *';"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';"))
|
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Max-Age: 1728000';"))
|
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Max-Age: 1728000';"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Credentials: true';"))
|
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Credentials: true';"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
uri := "/"
|
uri := "/"
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
|
@ -95,16 +87,12 @@ var _ = framework.IngressNginxDescribe("Annotations - CORS", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Methods: POST, GET';"))
|
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Methods: POST, GET';"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set cors max-age", func() {
|
It("should set cors max-age", func() {
|
||||||
|
@ -115,16 +103,12 @@ var _ = framework.IngressNginxDescribe("Annotations - CORS", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Max-Age: 200';"))
|
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Max-Age: 200';"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should disable cors allow credentials", func() {
|
It("should disable cors allow credentials", func() {
|
||||||
|
@ -135,16 +119,12 @@ var _ = framework.IngressNginxDescribe("Annotations - CORS", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).ShouldNot(ContainSubstring("more_set_headers 'Access-Control-Allow-Credentials: true';"))
|
return Expect(server).ShouldNot(ContainSubstring("more_set_headers 'Access-Control-Allow-Credentials: true';"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should allow origin for cors", func() {
|
It("should allow origin for cors", func() {
|
||||||
|
@ -155,16 +135,12 @@ var _ = framework.IngressNginxDescribe("Annotations - CORS", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Origin: https://origin.cors.com:8080';"))
|
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Origin: https://origin.cors.com:8080';"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should allow headers for cors", func() {
|
It("should allow headers for cors", func() {
|
||||||
|
@ -175,15 +151,11 @@ var _ = framework.IngressNginxDescribe("Annotations - CORS", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Headers: DNT, User-Agent';"))
|
return Expect(server).Should(ContainSubstring("more_set_headers 'Access-Control-Allow-Headers: DNT, User-Agent';"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -32,8 +32,7 @@ var _ = framework.IngressNginxDescribe("Annotations - custom default-backend", f
|
||||||
f := framework.NewDefaultFramework("default-backend")
|
f := framework.NewDefaultFramework("default-backend")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("when default backend annotation is enabled", func() {
|
Context("when default backend annotation is enabled", func() {
|
||||||
|
@ -44,18 +43,14 @@ var _ = framework.IngressNginxDescribe("Annotations - custom default-backend", f
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "invalid", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "invalid", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring(fmt.Sprintf("server_name %v", host)))
|
return Expect(server).Should(ContainSubstring(fmt.Sprintf("server_name %v", host)))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
uri := "/alma/armud"
|
uri := "/alma/armud"
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
|
|
66
test/e2e/annotations/forcesslredirect.go
Normal file
66
test/e2e/annotations/forcesslredirect.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
"github.com/parnurzeal/gorequest"
|
||||||
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = framework.IngressNginxDescribe("Annotations - Forcesslredirect", func() {
|
||||||
|
f := framework.NewDefaultFramework("forcesslredirect")
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should redirect to https", func() {
|
||||||
|
host := "forcesslredirect.bar.com"
|
||||||
|
|
||||||
|
annotations := map[string]string{
|
||||||
|
"nginx.ingress.kubernetes.io/force-ssl-redirect": "true",
|
||||||
|
}
|
||||||
|
|
||||||
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
|
f.WaitForNginxServer(host,
|
||||||
|
func(server string) bool {
|
||||||
|
return Expect(server).Should(ContainSubstring(`if ($redirect_to_https) {`)) &&
|
||||||
|
Expect(server).Should(ContainSubstring(`return 308 https://$best_http_host$request_uri;`))
|
||||||
|
})
|
||||||
|
|
||||||
|
resp, _, errs := gorequest.New().
|
||||||
|
Get(f.IngressController.HTTPURL).
|
||||||
|
Retry(10, 1*time.Second, http.StatusNotFound).
|
||||||
|
RedirectPolicy(noRedirectPolicyFunc).
|
||||||
|
Set("Host", host).
|
||||||
|
End()
|
||||||
|
|
||||||
|
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||||
|
Expect(resp.StatusCode).Should(Equal(http.StatusPermanentRedirect))
|
||||||
|
Expect(resp.Header.Get("Location")).Should(Equal("https://forcesslredirect.bar.com/"))
|
||||||
|
})
|
||||||
|
})
|
|
@ -31,8 +31,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Fromtowwwredirect", func()
|
||||||
f := framework.NewDefaultFramework("fromtowwwredirect")
|
f := framework.NewDefaultFramework("fromtowwwredirect")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -47,30 +46,25 @@ var _ = framework.IngressNginxDescribe("Annotations - Fromtowwwredirect", func()
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxConfiguration(
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return Expect(cfg).Should(ContainSubstring(`server_name www.fromtowwwredirect.bar.com;`)) &&
|
return Expect(cfg).Should(ContainSubstring(`server_name www.fromtowwwredirect.bar.com;`)) &&
|
||||||
Expect(cfg).Should(ContainSubstring(`return 308 $scheme://fromtowwwredirect.bar.com$request_uri;`))
|
Expect(cfg).Should(ContainSubstring(`return 308 $scheme://fromtowwwredirect.bar.com$request_uri;`))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("sending request to www.fromtowwwredirect.bar.com")
|
By("sending request to www.fromtowwwredirect.bar.com")
|
||||||
|
|
||||||
gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(fmt.Sprintf("%s/%s", f.IngressController.HTTPURL, "foo")).
|
Get(fmt.Sprintf("%s/%s", f.IngressController.HTTPURL, "foo")).
|
||||||
Retry(10, 1*time.Second, http.StatusNotFound).
|
Retry(10, 1*time.Second, http.StatusNotFound).
|
||||||
|
RedirectPolicy(noRedirectPolicyFunc).
|
||||||
Set("Host", fmt.Sprintf("%s.%s", "www", host)).
|
Set("Host", fmt.Sprintf("%s.%s", "www", host)).
|
||||||
End()
|
End()
|
||||||
|
|
||||||
log, err := f.NginxLogs()
|
Expect(len(errs)).Should(BeNumerically("==", 0))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(resp.StatusCode).Should(Equal(http.StatusPermanentRedirect))
|
||||||
Expect(log).ToNot(BeEmpty())
|
Expect(resp.Header.Get("Location")).Should(Equal("http://fromtowwwredirect.bar.com/foo"))
|
||||||
|
|
||||||
Expect(log).To(ContainSubstring(fmt.Sprintf(` "GET /foo HTTP/1.1" 308 171 "-" "Go-http-client/1.1"`)))
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -29,8 +29,7 @@ var _ = framework.IngressNginxDescribe("Annotations - grpc", func() {
|
||||||
f := framework.NewDefaultFramework("grpc")
|
f := framework.NewDefaultFramework("grpc")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewGRPCFortuneTellerDeployment()
|
f.NewGRPCFortuneTellerDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("when grpc is enabled", func() {
|
Context("when grpc is enabled", func() {
|
||||||
|
@ -42,25 +41,20 @@ var _ = framework.IngressNginxDescribe("Annotations - grpc", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "fortune-teller", 50051, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "fortune-teller", 50051, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring(fmt.Sprintf("server_name %v", host))) &&
|
return Expect(server).Should(ContainSubstring(fmt.Sprintf("server_name %v", host))) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("grpc_pass")) &&
|
return Expect(server).Should(ContainSubstring("grpc_pass")) &&
|
||||||
Expect(server).Should(ContainSubstring("grpc_set_header")) &&
|
Expect(server).Should(ContainSubstring("grpc_set_header")) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("proxy_pass"))
|
Expect(server).ShouldNot(ContainSubstring("proxy_pass"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -23,9 +23,10 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/parnurzeal/gorequest"
|
"github.com/parnurzeal/gorequest"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
@ -39,17 +40,13 @@ var _ = framework.IngressNginxDescribe("Annotations - influxdb", func() {
|
||||||
f := framework.NewDefaultFramework("influxdb")
|
f := framework.NewDefaultFramework("influxdb")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewInfluxDBDeployment()
|
f.NewInfluxDBDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.NewEchoDeployment()
|
||||||
err = f.NewEchoDeployment()
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("when influxdb is enabled", func() {
|
Context("when influxdb is enabled", func() {
|
||||||
It("should send the request metric to the influxdb server", func() {
|
It("should send the request metric to the influxdb server", func() {
|
||||||
ifs, err := createInfluxDBService(f)
|
ifs := createInfluxDBService(f)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
// Ingress configured with InfluxDB annotations
|
// Ingress configured with InfluxDB annotations
|
||||||
host := "influxdb.e2e.local"
|
host := "influxdb.e2e.local"
|
||||||
|
@ -80,6 +77,8 @@ var _ = framework.IngressNginxDescribe("Annotations - influxdb", func() {
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
var measurements string
|
var measurements string
|
||||||
|
var err error
|
||||||
|
|
||||||
err = wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
|
err = wait.PollImmediate(time.Second, time.Minute, func() (bool, error) {
|
||||||
measurements, err = extractInfluxDBMeasurements(f)
|
measurements, err = extractInfluxDBMeasurements(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -100,7 +99,7 @@ var _ = framework.IngressNginxDescribe("Annotations - influxdb", func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
func createInfluxDBService(f *framework.Framework) (*corev1.Service, error) {
|
func createInfluxDBService(f *framework.Framework) *corev1.Service {
|
||||||
service := &corev1.Service{
|
service := &corev1.Service{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "inflxudb-svc",
|
Name: "inflxudb-svc",
|
||||||
|
@ -120,29 +119,18 @@ func createInfluxDBService(f *framework.Framework) (*corev1.Service, error) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := f.EnsureService(service)
|
return f.EnsureService(service)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if s == nil {
|
|
||||||
return nil, fmt.Errorf("unexpected error creating service for influxdb deployment")
|
|
||||||
}
|
|
||||||
|
|
||||||
return s, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createInfluxDBIngress(f *framework.Framework, host, service string, port int, annotations map[string]string) {
|
func createInfluxDBIngress(f *framework.Framework, host, service string, port int, annotations map[string]string) {
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, service, port, &annotations))
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, service, port, &annotations)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.EnsureIngress(ing)
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring(fmt.Sprintf("server_name %v", host))) &&
|
return Expect(server).Should(ContainSubstring(fmt.Sprintf("server_name %v", host))) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractInfluxDBMeasurements(f *framework.Framework) (string, error) {
|
func extractInfluxDBMeasurements(f *framework.Framework) (string, error) {
|
||||||
|
@ -183,8 +171,7 @@ func execInfluxDBCommand(pod *corev1.Pod, command string) (string, error) {
|
||||||
execErr bytes.Buffer
|
execErr bytes.Buffer
|
||||||
)
|
)
|
||||||
|
|
||||||
args := fmt.Sprintf("kubectl exec --namespace %v %v -- %v", pod.Namespace, pod.Name, command)
|
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("%v exec --namespace %s %s -- %s", framework.KubectlPath, pod.Namespace, pod.Name, command))
|
||||||
cmd := exec.Command("/bin/bash", "-c", args)
|
|
||||||
cmd.Stdout = &execOut
|
cmd.Stdout = &execOut
|
||||||
cmd.Stderr = &execErr
|
cmd.Stderr = &execErr
|
||||||
|
|
||||||
|
@ -195,7 +182,7 @@ func execInfluxDBCommand(pod *corev1.Pod, command string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("could not execute: %v", err)
|
return "", fmt.Errorf("could not execute '%s %s': %v", cmd.Path, cmd.Args, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return execOut.String(), nil
|
return execOut.String(), nil
|
||||||
|
|
79
test/e2e/annotations/ipwhitelist.go
Normal file
79
test/e2e/annotations/ipwhitelist.go
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
|
||||||
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = framework.IngressNginxDescribe("Annotations - IPWhiteList", func() {
|
||||||
|
f := framework.NewDefaultFramework("ipwhitelist")
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should set valid ip whitelist range", func() {
|
||||||
|
host := "ipwhitelist.foo.com"
|
||||||
|
nameSpace := f.IngressController.Namespace
|
||||||
|
|
||||||
|
annotations := map[string]string{
|
||||||
|
"nginx.ingress.kubernetes.io/whitelist-source-range": "18.0.0.0/8, 56.0.0.0/8",
|
||||||
|
}
|
||||||
|
|
||||||
|
ing := framework.NewSingleIngress(host, "/", host, nameSpace, "http-svc", 80, &annotations)
|
||||||
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
|
denyRegex := regexp.MustCompile("geo \\$the_real_ip \\$deny_[A-Za-z]{32}")
|
||||||
|
denyString := ""
|
||||||
|
|
||||||
|
f.WaitForNginxConfiguration(
|
||||||
|
func(conf string) bool {
|
||||||
|
|
||||||
|
match := denyRegex.FindStringSubmatch(conf)
|
||||||
|
// If no match found, return false
|
||||||
|
if !(len(match) > 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
denyString = strings.Replace(match[0], "geo $the_real_ip ", "", -1)
|
||||||
|
return strings.Contains(conf, match[0])
|
||||||
|
})
|
||||||
|
|
||||||
|
ipOne := "18.0.0.0/8 0;"
|
||||||
|
ipTwo := "56.0.0.0/8 0;"
|
||||||
|
|
||||||
|
f.WaitForNginxConfiguration(
|
||||||
|
func(conf string) bool {
|
||||||
|
return strings.Contains(conf, ipOne) && strings.Contains(conf, ipTwo)
|
||||||
|
})
|
||||||
|
|
||||||
|
denyStatement := "if (" + denyString + ")"
|
||||||
|
f.WaitForNginxServer(host,
|
||||||
|
func(server string) bool {
|
||||||
|
return strings.Contains(server, denyStatement)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -19,6 +19,7 @@ package annotations
|
||||||
import (
|
import (
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,8 +27,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Log", func() {
|
||||||
f := framework.NewDefaultFramework("log")
|
f := framework.NewDefaultFramework("log")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -40,16 +40,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Log", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring(`access_log off;`))
|
return Expect(server).Should(ContainSubstring(`access_log off;`))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("set rewrite_log on", func() {
|
It("set rewrite_log on", func() {
|
||||||
|
@ -59,15 +55,11 @@ var _ = framework.IngressNginxDescribe("Annotations - Log", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring(`rewrite_log on;`))
|
return Expect(server).Should(ContainSubstring(`rewrite_log on;`))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -32,8 +32,7 @@ var _ = framework.IngressNginxDescribe("Annotations - lua-resty-waf", func() {
|
||||||
f := framework.NewDefaultFramework("luarestywaf")
|
f := framework.NewDefaultFramework("luarestywaf")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("when lua-resty-waf is enabled", func() {
|
Context("when lua-resty-waf is enabled", func() {
|
||||||
|
@ -65,6 +64,71 @@ var _ = framework.IngressNginxDescribe("Annotations - lua-resty-waf", func() {
|
||||||
Expect(len(errs)).Should(Equal(0))
|
Expect(len(errs)).Should(Equal(0))
|
||||||
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||||
})
|
})
|
||||||
|
It("should apply the score threshold", func() {
|
||||||
|
host := "foo"
|
||||||
|
createIngress(f, host, "http-svc", 80, map[string]string{
|
||||||
|
"nginx.ingress.kubernetes.io/lua-resty-waf": "active",
|
||||||
|
"nginx.ingress.kubernetes.io/lua-resty-waf-score-threshold": "20"})
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s?msg=<A href=\"http://mysite.com/\">XSS</A>", f.IngressController.HTTPURL)
|
||||||
|
resp, _, errs := gorequest.New().
|
||||||
|
Get(url).
|
||||||
|
Set("Host", host).
|
||||||
|
End()
|
||||||
|
|
||||||
|
Expect(len(errs)).Should(Equal(0))
|
||||||
|
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||||
|
})
|
||||||
|
It("should not reject request with an unknown content type", func() {
|
||||||
|
host := "foo"
|
||||||
|
contenttype := "application/octet-stream"
|
||||||
|
createIngress(f, host, "http-svc", 80, map[string]string{
|
||||||
|
"nginx.ingress.kubernetes.io/lua-resty-waf-allow-unknown-content-types": "true",
|
||||||
|
"nginx.ingress.kubernetes.io/lua-resty-waf": "active"})
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s?msg=my-message", f.IngressController.HTTPURL)
|
||||||
|
resp, _, errs := gorequest.New().
|
||||||
|
Get(url).
|
||||||
|
Set("Host", host).
|
||||||
|
Set("Content-Type", contenttype).
|
||||||
|
End()
|
||||||
|
|
||||||
|
Expect(len(errs)).Should(Equal(0))
|
||||||
|
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||||
|
})
|
||||||
|
It("should not fail a request with multipart content type when multipart body processing disabled", func() {
|
||||||
|
contenttype := "multipart/form-data; boundary=alamofire.boundary.3fc2e849279e18fc"
|
||||||
|
host := "foo"
|
||||||
|
createIngress(f, host, "http-svc", 80, map[string]string{
|
||||||
|
"nginx.ingress.kubernetes.io/lua-resty-waf-process-multipart-body": "false",
|
||||||
|
"nginx.ingress.kubernetes.io/lua-resty-waf": "active"})
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s?msg=my-message", f.IngressController.HTTPURL)
|
||||||
|
resp, _, errs := gorequest.New().
|
||||||
|
Get(url).
|
||||||
|
Set("Host", host).
|
||||||
|
Set("Content-Type", contenttype).
|
||||||
|
End()
|
||||||
|
|
||||||
|
Expect(len(errs)).Should(Equal(0))
|
||||||
|
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||||
|
})
|
||||||
|
It("should fail a request with multipart content type when multipart body processing enabled by default", func() {
|
||||||
|
contenttype := "multipart/form-data; boundary=alamofire.boundary.3fc2e849279e18fc"
|
||||||
|
host := "foo"
|
||||||
|
createIngress(f, host, "http-svc", 80, map[string]string{
|
||||||
|
"nginx.ingress.kubernetes.io/lua-resty-waf": "active"})
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s?msg=my-message", f.IngressController.HTTPURL)
|
||||||
|
resp, _, errs := gorequest.New().
|
||||||
|
Get(url).
|
||||||
|
Set("Host", host).
|
||||||
|
Set("Content-Type", contenttype).
|
||||||
|
End()
|
||||||
|
|
||||||
|
Expect(len(errs)).Should(Equal(0))
|
||||||
|
Expect(resp.StatusCode).Should(Equal(http.StatusBadRequest))
|
||||||
|
})
|
||||||
It("should apply configured extra rules", func() {
|
It("should apply configured extra rules", func() {
|
||||||
host := "foo"
|
host := "foo"
|
||||||
createIngress(f, host, "http-svc", 80, map[string]string{
|
createIngress(f, host, "http-svc", 80, map[string]string{
|
||||||
|
@ -139,16 +203,14 @@ var _ = framework.IngressNginxDescribe("Annotations - lua-resty-waf", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
func createIngress(f *framework.Framework, host, service string, port int, annotations map[string]string) {
|
func createIngress(f *framework.Framework, host, service string, port int, annotations map[string]string) {
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, service, port, &annotations))
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, service, port, &annotations)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.EnsureIngress(ing)
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring(fmt.Sprintf("server_name %v", host))) &&
|
return Expect(server).Should(ContainSubstring(fmt.Sprintf("server_name %v", host))) &&
|
||||||
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
Expect(server).ShouldNot(ContainSubstring("return 503"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,10 @@ limitations under the License.
|
||||||
package annotations
|
package annotations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
)
|
)
|
||||||
|
@ -28,8 +29,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
f := framework.NewDefaultFramework("proxy")
|
f := framework.NewDefaultFramework("proxy")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -43,16 +43,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("proxy_redirect off;"))
|
return Expect(server).Should(ContainSubstring("proxy_redirect off;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set proxy_redirect to default", func() {
|
It("should set proxy_redirect to default", func() {
|
||||||
|
@ -63,16 +59,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("proxy_redirect default;"))
|
return Expect(server).Should(ContainSubstring("proxy_redirect default;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set proxy_redirect to hello.com goodbye.com", func() {
|
It("should set proxy_redirect to hello.com goodbye.com", func() {
|
||||||
|
@ -83,16 +75,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("proxy_redirect hello.com goodbye.com;"))
|
return Expect(server).Should(ContainSubstring("proxy_redirect hello.com goodbye.com;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set proxy client-max-body-size to 8m", func() {
|
It("should set proxy client-max-body-size to 8m", func() {
|
||||||
|
@ -102,16 +90,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("client_max_body_size 8m;"))
|
return Expect(server).Should(ContainSubstring("client_max_body_size 8m;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not set proxy client-max-body-size to incorrect value", func() {
|
It("should not set proxy client-max-body-size to incorrect value", func() {
|
||||||
|
@ -121,16 +105,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).ShouldNot(ContainSubstring("client_max_body_size 15r;"))
|
return Expect(server).ShouldNot(ContainSubstring("client_max_body_size 15r;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should set valid proxy timeouts", func() {
|
It("should set valid proxy timeouts", func() {
|
||||||
|
@ -142,16 +122,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "proxy_connect_timeout 50s;") && strings.Contains(server, "proxy_send_timeout 20s;") && strings.Contains(server, "proxy_read_timeout 20s;")
|
return strings.Contains(server, "proxy_connect_timeout 50s;") && strings.Contains(server, "proxy_send_timeout 20s;") && strings.Contains(server, "proxy_read_timeout 20s;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not set invalid proxy timeouts", func() {
|
It("should not set invalid proxy timeouts", func() {
|
||||||
|
@ -163,16 +139,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return !strings.Contains(server, "proxy_connect_timeout 50ks;") && !strings.Contains(server, "proxy_send_timeout 20ks;") && !strings.Contains(server, "proxy_read_timeout 60s;")
|
return !strings.Contains(server, "proxy_connect_timeout 50ks;") && !strings.Contains(server, "proxy_send_timeout 20ks;") && !strings.Contains(server, "proxy_read_timeout 60s;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should turn on proxy-buffering", func() {
|
It("should turn on proxy-buffering", func() {
|
||||||
|
@ -183,16 +155,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "proxy_buffering on;") && strings.Contains(server, "proxy_buffer_size 8k;") && strings.Contains(server, "proxy_buffers 4 8k;") && strings.Contains(server, "proxy_request_buffering on;")
|
return strings.Contains(server, "proxy_buffering on;") && strings.Contains(server, "proxy_buffer_size 8k;") && strings.Contains(server, "proxy_buffers 4 8k;") && strings.Contains(server, "proxy_request_buffering on;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should turn off proxy-request-buffering", func() {
|
It("should turn off proxy-request-buffering", func() {
|
||||||
|
@ -202,16 +170,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("proxy_request_buffering off;"))
|
return Expect(server).Should(ContainSubstring("proxy_request_buffering off;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should build proxy next upstream", func() {
|
It("should build proxy next upstream", func() {
|
||||||
|
@ -222,16 +186,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "proxy_next_upstream error timeout http_502;") && strings.Contains(server, "proxy_next_upstream_tries 5;")
|
return strings.Contains(server, "proxy_next_upstream error timeout http_502;") && strings.Contains(server, "proxy_next_upstream_tries 5;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should setup proxy cookies", func() {
|
It("should setup proxy cookies", func() {
|
||||||
|
@ -242,16 +202,11 @@ var _ = framework.IngressNginxDescribe("Annotations - Proxy", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "proxy_cookie_domain localhost example.org;") && strings.Contains(server, "proxy_cookie_path /one/ /;")
|
return strings.Contains(server, "proxy_cookie_domain localhost example.org;") && strings.Contains(server, "proxy_cookie_path /one/ /;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -53,17 +53,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Redirect", func() {
|
||||||
annotations := map[string]string{"nginx.ingress.kubernetes.io/permanent-redirect": redirectURL}
|
annotations := map[string]string{"nginx.ingress.kubernetes.io/permanent-redirect": redirectURL}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, redirectPath, host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, redirectPath, host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, fmt.Sprintf("if ($uri ~* %s) {", redirectPath)) &&
|
return strings.Contains(server, fmt.Sprintf("if ($uri ~* %s) {", redirectPath)) &&
|
||||||
strings.Contains(server, fmt.Sprintf("return 301 %s;", redirectURL))
|
strings.Contains(server, fmt.Sprintf("return 301 %s;", redirectURL))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("sending request to redirected URL path")
|
By("sending request to redirected URL path")
|
||||||
|
|
||||||
|
@ -93,17 +89,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Redirect", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, redirectPath, host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, redirectPath, host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, fmt.Sprintf("if ($uri ~* %s) {", redirectPath)) &&
|
return strings.Contains(server, fmt.Sprintf("if ($uri ~* %s) {", redirectPath)) &&
|
||||||
strings.Contains(server, fmt.Sprintf("return %d %s;", redirectCode, redirectURL))
|
strings.Contains(server, fmt.Sprintf("return %d %s;", redirectCode, redirectURL))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("sending request to redirected URL path")
|
By("sending request to redirected URL path")
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Rewrite", func() {
|
||||||
f := framework.NewDefaultFramework("rewrite")
|
f := framework.NewDefaultFramework("rewrite")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(1)
|
f.NewEchoDeploymentWithReplicas(1)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -48,17 +47,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Rewrite", func() {
|
||||||
expectBodyRequestURI := fmt.Sprintf("request_uri=http://%v:8080/", host)
|
expectBodyRequestURI := fmt.Sprintf("request_uri=http://%v:8080/", host)
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/something", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/something", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, `rewrite "(?i)/something/(.*)" /$1 break;`) &&
|
return strings.Contains(server, `rewrite "(?i)/something/(.*)" /$1 break;`) &&
|
||||||
strings.Contains(server, `rewrite "(?i)/something$" / break;`)
|
strings.Contains(server, `rewrite "(?i)/something$" / break;`)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("sending request to Ingress rule path (lowercase)")
|
By("sending request to Ingress rule path (lowercase)")
|
||||||
|
|
||||||
|
@ -93,16 +88,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Rewrite", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/something", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/something", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "rewrite_log on;")
|
return strings.Contains(server, "rewrite_log on;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL+"/something").
|
Get(f.IngressController.HTTPURL+"/something").
|
||||||
|
@ -123,15 +114,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Rewrite", func() {
|
||||||
|
|
||||||
By("creating a regular ingress definition")
|
By("creating a regular ingress definition")
|
||||||
ing := framework.NewSingleIngress("kube-lego", "/.well-known/acme/challenge", host, f.IngressController.Namespace, "http-svc", 80, &map[string]string{})
|
ing := framework.NewSingleIngress("kube-lego", "/.well-known/acme/challenge", host, f.IngressController.Namespace, "http-svc", 80, &map[string]string{})
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "/.well-known/acme/challenge")
|
return strings.Contains(server, "/.well-known/acme/challenge")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("making a request to the non-rewritten location")
|
By("making a request to the non-rewritten location")
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
|
@ -148,15 +136,13 @@ var _ = framework.IngressNginxDescribe("Annotations - Rewrite", func() {
|
||||||
"nginx.ingress.kubernetes.io/rewrite-target": "/new/backend",
|
"nginx.ingress.kubernetes.io/rewrite-target": "/new/backend",
|
||||||
}
|
}
|
||||||
rewriteIng := framework.NewSingleIngress("rewrite-index", "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
rewriteIng := framework.NewSingleIngress("rewrite-index", "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(rewriteIng)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(rewriteIng).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.EnsureIngress(rewriteIng)
|
||||||
|
|
||||||
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "location ~* ^/ {") && strings.Contains(server, `location ~* "^/.well-known/acme/challenge" {`)
|
return strings.Contains(server, "location ~* ^/ {") && strings.Contains(server, `location ~* "^/.well-known/acme/challenge" {`)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("making a second request to the non-rewritten location")
|
By("making a second request to the non-rewritten location")
|
||||||
resp, body, errs = gorequest.New().
|
resp, body, errs = gorequest.New().
|
||||||
|
@ -173,15 +159,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Rewrite", func() {
|
||||||
|
|
||||||
By("creating a regular ingress definition")
|
By("creating a regular ingress definition")
|
||||||
ing := framework.NewSingleIngress("foo", "/foo", host, f.IngressController.Namespace, "http-svc", 80, &map[string]string{})
|
ing := framework.NewSingleIngress("foo", "/foo", host, f.IngressController.Namespace, "http-svc", 80, &map[string]string{})
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "location /foo {")
|
return strings.Contains(server, "location /foo {")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By(`creating an ingress definition with the use-regex amd rewrite-target annotation`)
|
By(`creating an ingress definition with the use-regex amd rewrite-target annotation`)
|
||||||
annotations := map[string]string{
|
annotations := map[string]string{
|
||||||
|
@ -189,15 +172,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Rewrite", func() {
|
||||||
"nginx.ingress.kubernetes.io/rewrite-target": "/new/backend",
|
"nginx.ingress.kubernetes.io/rewrite-target": "/new/backend",
|
||||||
}
|
}
|
||||||
ing = framework.NewSingleIngress("regex", "/foo.+", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing = framework.NewSingleIngress("regex", "/foo.+", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, `location ~* "^/foo" {`) && strings.Contains(server, `location ~* "^/foo.+\/?(?<baseuri>.*)" {`)
|
return strings.Contains(server, `location ~* "^/foo" {`) && strings.Contains(server, `location ~* "^/foo.+\/?(?<baseuri>.*)" {`)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("ensuring '/foo' matches '~* ^/foo'")
|
By("ensuring '/foo' matches '~* ^/foo'")
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
|
@ -225,9 +205,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Rewrite", func() {
|
||||||
|
|
||||||
By("creating a regular ingress definition")
|
By("creating a regular ingress definition")
|
||||||
ing := framework.NewSingleIngress("foo", "/foo/bar/bar", host, f.IngressController.Namespace, "http-svc", 80, &map[string]string{})
|
ing := framework.NewSingleIngress("foo", "/foo/bar/bar", host, f.IngressController.Namespace, "http-svc", 80, &map[string]string{})
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
By(`creating an ingress definition with the use-regex annotation`)
|
By(`creating an ingress definition with the use-regex annotation`)
|
||||||
annotations := map[string]string{
|
annotations := map[string]string{
|
||||||
|
@ -235,15 +213,12 @@ var _ = framework.IngressNginxDescribe("Annotations - Rewrite", func() {
|
||||||
"nginx.ingress.kubernetes.io/rewrite-target": "/new/backend",
|
"nginx.ingress.kubernetes.io/rewrite-target": "/new/backend",
|
||||||
}
|
}
|
||||||
ing = framework.NewSingleIngress("regex", "/foo/bar/[a-z]{3}", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing = framework.NewSingleIngress("regex", "/foo/bar/[a-z]{3}", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err = f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, `location ~* "^/foo/bar/bar" {`) && strings.Contains(server, `location ~* "^/foo/bar/[a-z]{3}\/?(?<baseuri>.*)" {`)
|
return strings.Contains(server, `location ~* "^/foo/bar/bar" {`) && strings.Contains(server, `location ~* "^/foo/bar/[a-z]{3}\/?(?<baseuri>.*)" {`)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("check that '/foo/bar/bar' does not match the longest exact path")
|
By("check that '/foo/bar/bar' does not match the longest exact path")
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
|
|
53
test/e2e/annotations/serversnippet.go
Normal file
53
test/e2e/annotations/serversnippet.go
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
|
||||||
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = framework.IngressNginxDescribe("Annotations - ServerSnippet", func() {
|
||||||
|
f := framework.NewDefaultFramework("serversnippet")
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
})
|
||||||
|
|
||||||
|
It(`add valid directives to server via server snippet"`, func() {
|
||||||
|
host := "serversnippet.foo.com"
|
||||||
|
annotations := map[string]string{
|
||||||
|
"nginx.ingress.kubernetes.io/server-snippet": `
|
||||||
|
more_set_headers "Content-Length: $content_length";
|
||||||
|
more_set_headers "Content-Type: $content_type";`,
|
||||||
|
}
|
||||||
|
|
||||||
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
|
f.WaitForNginxServer(host,
|
||||||
|
func(server string) bool {
|
||||||
|
return strings.Contains(server, `more_set_headers "Content-Length: $content_length`) && strings.Contains(server, `more_set_headers "Content-Type: $content_type";`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -26,8 +26,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Configurationsnippet", fun
|
||||||
f := framework.NewDefaultFramework("configurationsnippet")
|
f := framework.NewDefaultFramework("configurationsnippet")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -41,15 +40,11 @@ var _ = framework.IngressNginxDescribe("Annotations - Configurationsnippet", fun
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring(`more_set_headers "Request-Id: $req_id";`))
|
return Expect(server).Should(ContainSubstring(`more_set_headers "Request-Id: $req_id";`))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -27,8 +27,7 @@ var _ = framework.IngressNginxDescribe("Annotations - SSL CIPHERS", func() {
|
||||||
f := framework.NewDefaultFramework("sslciphers")
|
f := framework.NewDefaultFramework("sslciphers")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -41,15 +40,11 @@ var _ = framework.IngressNginxDescribe("Annotations - SSL CIPHERS", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/something", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/something", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;"))
|
return Expect(server).Should(ContainSubstring("ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -26,8 +26,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Upstreamvhost", func() {
|
||||||
f := framework.NewDefaultFramework("upstreamvhost")
|
f := framework.NewDefaultFramework("upstreamvhost")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(2)
|
f.NewEchoDeploymentWithReplicas(2)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -40,15 +39,11 @@ var _ = framework.IngressNginxDescribe("Annotations - Upstreamvhost", func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
|
||||||
_, err := f.EnsureIngress(ing)
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxServer(host,
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring(`proxy_set_header Host "upstreamvhost.bar.com";`))
|
return Expect(server).Should(ContainSubstring(`proxy_set_header Host "upstreamvhost.bar.com";`))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/parnurzeal/gorequest"
|
"github.com/parnurzeal/gorequest"
|
||||||
|
|
||||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||||
|
@ -34,8 +35,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
f := framework.NewDefaultFramework("custom-default-backend")
|
f := framework.NewDefaultFramework("custom-default-backend")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(1)
|
f.NewEchoDeploymentWithReplicas(1)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "nginx-ingress-controller", 1,
|
framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "nginx-ingress-controller", 1,
|
||||||
func(deployment *appsv1beta1.Deployment) error {
|
func(deployment *appsv1beta1.Deployment) error {
|
||||||
|
@ -47,11 +47,10 @@ var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
|
||||||
err = f.WaitForNginxServer("_",
|
f.WaitForNginxServer("_",
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "set $proxy_upstream_name \"upstream-default-backend\"")
|
return strings.Contains(server, "set $proxy_upstream_name \"upstream-default-backend\"")
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("uses custom default backend", func() {
|
It("uses custom default backend", func() {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,13 +17,14 @@ limitations under the License.
|
||||||
package e2e
|
package e2e
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
|
||||||
"github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
"github.com/onsi/ginkgo/config"
|
"github.com/onsi/ginkgo/config"
|
||||||
"github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
"k8s.io/apiserver/pkg/util/logs"
|
"k8s.io/apiserver/pkg/util/logs"
|
||||||
|
|
||||||
// required
|
// required
|
||||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ import (
|
||||||
_ "k8s.io/ingress-nginx/test/e2e/servicebackend"
|
_ "k8s.io/ingress-nginx/test/e2e/servicebackend"
|
||||||
_ "k8s.io/ingress-nginx/test/e2e/settings"
|
_ "k8s.io/ingress-nginx/test/e2e/settings"
|
||||||
_ "k8s.io/ingress-nginx/test/e2e/ssl"
|
_ "k8s.io/ingress-nginx/test/e2e/ssl"
|
||||||
|
_ "k8s.io/ingress-nginx/test/e2e/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunE2ETests checks configuration parameters (specified through flags) and then runs
|
// RunE2ETests checks configuration parameters (specified through flags) and then runs
|
||||||
|
@ -50,7 +52,12 @@ func RunE2ETests(t *testing.T) {
|
||||||
config.GinkgoConfig.SkipString = `\[Flaky\]|\[Feature:.+\]`
|
config.GinkgoConfig.SkipString = `\[Flaky\]|\[Feature:.+\]`
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.Infof("Starting e2e run %q on Ginkgo node %d", framework.RunID, config.GinkgoConfig.ParallelNode)
|
if os.Getenv("KUBECTL_PATH") != "" {
|
||||||
|
framework.KubectlPath = os.Getenv("KUBECTL_PATH")
|
||||||
|
framework.Logf("Using kubectl path '%s'", framework.KubectlPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
framework.Logf("Starting e2e run %q on Ginkgo node %d", framework.RunID, config.GinkgoConfig.ParallelNode)
|
||||||
ginkgo.RunSpecs(t, "nginx-ingress-controller e2e suite")
|
ginkgo.RunSpecs(t, "nginx-ingress-controller e2e suite")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,9 @@ limitations under the License.
|
||||||
package framework
|
package framework
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
extensions "k8s.io/api/extensions/v1beta1"
|
extensions "k8s.io/api/extensions/v1beta1"
|
||||||
|
@ -30,23 +29,23 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewEchoDeployment creates a new single replica deployment of the echoserver image in a particular namespace
|
// NewEchoDeployment creates a new single replica deployment of the echoserver image in a particular namespace
|
||||||
func (f *Framework) NewEchoDeployment() error {
|
func (f *Framework) NewEchoDeployment() {
|
||||||
return f.NewEchoDeploymentWithReplicas(1)
|
f.NewEchoDeploymentWithReplicas(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEchoDeploymentWithReplicas creates a new deployment of the echoserver image in a particular namespace. Number of
|
// NewEchoDeploymentWithReplicas creates a new deployment of the echoserver image in a particular namespace. Number of
|
||||||
// replicas is configurable
|
// replicas is configurable
|
||||||
func (f *Framework) NewEchoDeploymentWithReplicas(replicas int32) error {
|
func (f *Framework) NewEchoDeploymentWithReplicas(replicas int32) {
|
||||||
return f.NewDeployment("http-svc", "gcr.io/kubernetes-e2e-test-images/echoserver:2.1", 8080, replicas)
|
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.
|
// NewHttpbinDeployment creates a new single replica deployment of the httpbin image in a particular namespace.
|
||||||
func (f *Framework) NewHttpbinDeployment() error {
|
func (f *Framework) NewHttpbinDeployment() {
|
||||||
return f.NewDeployment("httpbin", "kennethreitz/httpbin", 80, 1)
|
f.NewDeployment("httpbin", "kennethreitz/httpbin", 80, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDeployment creates a new deployment in a particular namespace.
|
// NewDeployment creates a new deployment in a particular namespace.
|
||||||
func (f *Framework) NewDeployment(name, image string, port int32, replicas int32) error {
|
func (f *Framework) NewDeployment(name, image string, port int32, replicas int32) {
|
||||||
deployment := &extensions.Deployment{
|
deployment := &extensions.Deployment{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -86,20 +85,13 @@ func (f *Framework) NewDeployment(name, image string, port int32, replicas int32
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := f.EnsureDeployment(deployment)
|
d, err := f.EnsureDeployment(deployment)
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred(), "failed to create a deployment")
|
||||||
return err
|
Expect(d).NotTo(BeNil(), "expected a deployement but none returned")
|
||||||
}
|
|
||||||
|
|
||||||
if d == nil {
|
|
||||||
return fmt.Errorf("unexpected error creating deployement %s", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = WaitForPodsReady(f.KubeClientSet, 5*time.Minute, int(replicas), f.IngressController.Namespace, metav1.ListOptions{
|
err = WaitForPodsReady(f.KubeClientSet, 5*time.Minute, int(replicas), f.IngressController.Namespace, metav1.ListOptions{
|
||||||
LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(),
|
LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred(), "failed to wait for to become ready")
|
||||||
return errors.Wrap(err, "failed to wait for to become ready")
|
|
||||||
}
|
|
||||||
|
|
||||||
service := &corev1.Service{
|
service := &corev1.Service{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
@ -121,14 +113,6 @@ func (f *Framework) NewDeployment(name, image string, port int32, replicas int32
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := f.EnsureService(service)
|
s := f.EnsureService(service)
|
||||||
if err != nil {
|
Expect(s).NotTo(BeNil(), "expected a service but none returned")
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if s == nil {
|
|
||||||
return fmt.Errorf("unexpected error creating service %s", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,11 @@ package framework
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
@ -31,14 +35,14 @@ func (f *Framework) ExecCommand(pod *v1.Pod, command string) (string, error) {
|
||||||
execErr bytes.Buffer
|
execErr bytes.Buffer
|
||||||
)
|
)
|
||||||
|
|
||||||
args := fmt.Sprintf("kubectl exec --namespace %v %v --container nginx-ingress-controller -- %v", pod.Namespace, pod.Name, command)
|
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("%v exec --namespace %s %s --container nginx-ingress-controller -- %s", KubectlPath, pod.Namespace, pod.Name, command))
|
||||||
cmd := exec.Command("/bin/bash", "-c", args)
|
|
||||||
cmd.Stdout = &execOut
|
cmd.Stdout = &execOut
|
||||||
cmd.Stderr = &execErr
|
cmd.Stderr = &execErr
|
||||||
|
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("could not execute: %v", err)
|
return "", fmt.Errorf("could not execute '%s %s': %v", cmd.Path, cmd.Args, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if execErr.Len() > 0 {
|
if execErr.Len() > 0 {
|
||||||
|
@ -59,3 +63,51 @@ func (f *Framework) NewIngressController(namespace string) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
proxyRegexp = regexp.MustCompile("Starting to serve on .*:([0-9]+)")
|
||||||
|
)
|
||||||
|
|
||||||
|
// KubectlProxy creates a proxy to kubernetes apiserver
|
||||||
|
func (f *Framework) KubectlProxy(port int) (int, *exec.Cmd, 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 {
|
||||||
|
return -1, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer stdout.Close()
|
||||||
|
defer stderr.Close()
|
||||||
|
|
||||||
|
buf := make([]byte, 128)
|
||||||
|
var n int
|
||||||
|
if n, err = stdout.Read(buf); err != nil {
|
||||||
|
return -1, cmd, fmt.Errorf("Failed to read from kubectl proxy stdout: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := string(buf[:n])
|
||||||
|
match := proxyRegexp.FindStringSubmatch(output)
|
||||||
|
if len(match) == 2 {
|
||||||
|
if port, err := strconv.Atoi(match[1]); err == nil {
|
||||||
|
return port, cmd, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1, cmd, fmt.Errorf("Failed to parse port from proxy stdout: %s", output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func startCmdAndStreamOutput(cmd *exec.Cmd) (stdout, stderr io.ReadCloser, err error) {
|
||||||
|
stdout, err = cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stderr, err = cmd.StderrPipe()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Logf("Asynchronously running '%s'", strings.Join(cmd.Args, " "))
|
||||||
|
err = cmd.Start()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,11 @@ const (
|
||||||
HTTPS RequestScheme = "https"
|
HTTPS RequestScheme = "https"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// KubectlPath defines the full path of the kubectl binary
|
||||||
|
KubectlPath = "/usr/local/bin/kubectl"
|
||||||
|
)
|
||||||
|
|
||||||
// Framework supports common operations used by e2e tests; it will keep a client & a namespace for you.
|
// Framework supports common operations used by e2e tests; it will keep a client & a namespace for you.
|
||||||
type Framework struct {
|
type Framework struct {
|
||||||
BaseName string
|
BaseName string
|
||||||
|
@ -112,14 +117,10 @@ func (f *Framework) BeforeEach() {
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
HTTPURL, err := f.GetNginxURL(HTTP)
|
HTTPURL := f.GetNginxURL(HTTP)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
f.IngressController.HTTPURL = HTTPURL
|
f.IngressController.HTTPURL = HTTPURL
|
||||||
|
|
||||||
HTTPSURL, err := f.GetNginxURL(HTTPS)
|
HTTPSURL := f.GetNginxURL(HTTPS)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
f.IngressController.HTTPSURL = HTTPSURL
|
f.IngressController.HTTPSURL = HTTPSURL
|
||||||
|
|
||||||
// we wait for any change in the informers and SSL certificate generation
|
// we wait for any change in the informers and SSL certificate generation
|
||||||
|
@ -149,8 +150,10 @@ func IngressNginxDescribe(text string, body func()) bool {
|
||||||
|
|
||||||
// GetNginxIP returns the IP address of the minikube cluster
|
// GetNginxIP returns the IP address of the minikube cluster
|
||||||
// where the NGINX ingress controller is running
|
// where the NGINX ingress controller is running
|
||||||
func (f *Framework) GetNginxIP() (string, error) {
|
func (f *Framework) GetNginxIP() string {
|
||||||
return os.Getenv("NODE_IP"), nil
|
nodeIP := os.Getenv("NODE_IP")
|
||||||
|
Expect(nodeIP).NotTo(BeEmpty(), "env variable NODE_IP is empty")
|
||||||
|
return nodeIP
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNginxPort returns the number of TCP port where NGINX is running
|
// GetNginxPort returns the number of TCP port where NGINX is running
|
||||||
|
@ -173,33 +176,28 @@ func (f *Framework) GetNginxPort(name string) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNginxURL returns the URL should be used to make a request to NGINX
|
// GetNginxURL returns the URL should be used to make a request to NGINX
|
||||||
func (f *Framework) GetNginxURL(scheme RequestScheme) (string, error) {
|
func (f *Framework) GetNginxURL(scheme RequestScheme) string {
|
||||||
ip, err := f.GetNginxIP()
|
ip := f.GetNginxIP()
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
port, err := f.GetNginxPort(fmt.Sprintf("%v", scheme))
|
port, err := f.GetNginxPort(fmt.Sprintf("%v", scheme))
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred(), "unexpected error obtaning NGINX Port")
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%v://%v:%v", scheme, ip, port), nil
|
return fmt.Sprintf("%v://%v:%v", scheme, ip, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitForNginxServer waits until the nginx configuration contains a particular server section
|
// WaitForNginxServer waits until the nginx configuration contains a particular server section
|
||||||
func (f *Framework) WaitForNginxServer(name string, matcher func(cfg string) bool) error {
|
func (f *Framework) WaitForNginxServer(name string, matcher func(cfg string) bool) {
|
||||||
return wait.Poll(Poll, time.Minute*5, f.matchNginxConditions(name, matcher))
|
err := wait.Poll(Poll, time.Minute*5, f.matchNginxConditions(name, matcher))
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error waiting for nginx server condition/s")
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitForNginxConfiguration waits until the nginx configuration contains a particular configuration
|
// WaitForNginxConfiguration waits until the nginx configuration contains a particular configuration
|
||||||
func (f *Framework) WaitForNginxConfiguration(matcher func(cfg string) bool) error {
|
func (f *Framework) WaitForNginxConfiguration(matcher func(cfg string) bool) {
|
||||||
return wait.Poll(Poll, time.Minute*5, f.matchNginxConditions("", matcher))
|
err := wait.Poll(Poll, time.Minute*5, f.matchNginxConditions("", matcher))
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error waiting for nginx server condition/s")
|
||||||
}
|
}
|
||||||
|
|
||||||
// NginxLogs returns the logs of the nginx ingress controller pod running
|
func nginxLogs(client kubernetes.Interface, namespace string) (string, error) {
|
||||||
func (f *Framework) NginxLogs() (string, error) {
|
l, err := client.CoreV1().Pods(namespace).List(metav1.ListOptions{
|
||||||
l, err := f.KubeClientSet.CoreV1().Pods(f.IngressController.Namespace).List(metav1.ListOptions{
|
|
||||||
LabelSelector: "app.kubernetes.io/name=ingress-nginx",
|
LabelSelector: "app.kubernetes.io/name=ingress-nginx",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -209,7 +207,7 @@ func (f *Framework) NginxLogs() (string, error) {
|
||||||
for _, pod := range l.Items {
|
for _, pod := range l.Items {
|
||||||
if strings.HasPrefix(pod.GetName(), "nginx-ingress-controller") {
|
if strings.HasPrefix(pod.GetName(), "nginx-ingress-controller") {
|
||||||
if isRunning, err := podRunningReady(&pod); err == nil && isRunning {
|
if isRunning, err := podRunningReady(&pod); err == nil && isRunning {
|
||||||
return f.Logs(&pod)
|
return Logs(&pod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,6 +215,11 @@ func (f *Framework) NginxLogs() (string, error) {
|
||||||
return "", fmt.Errorf("no nginx ingress controller pod is running (logs)")
|
return "", fmt.Errorf("no nginx ingress controller pod is running (logs)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NginxLogs returns the logs of the nginx ingress controller pod running
|
||||||
|
func (f *Framework) NginxLogs() (string, error) {
|
||||||
|
return nginxLogs(f.KubeClientSet, f.IngressController.Namespace)
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Framework) matchNginxConditions(name string, matcher func(cfg string) bool) wait.ConditionFunc {
|
func (f *Framework) matchNginxConditions(name string, matcher func(cfg string) bool) wait.ConditionFunc {
|
||||||
return func() (bool, error) {
|
return func() (bool, error) {
|
||||||
l, err := f.KubeClientSet.CoreV1().Pods(f.IngressController.Namespace).List(metav1.ListOptions{
|
l, err := f.KubeClientSet.CoreV1().Pods(f.IngressController.Namespace).List(metav1.ListOptions{
|
||||||
|
@ -311,16 +314,12 @@ func (f *Framework) GetNginxConfigMapData() (map[string]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNginxConfigMapData sets ingress-nginx's nginx-configuration configMap data
|
// SetNginxConfigMapData sets ingress-nginx's nginx-configuration configMap data
|
||||||
func (f *Framework) SetNginxConfigMapData(cmData map[string]string) error {
|
func (f *Framework) SetNginxConfigMapData(cmData map[string]string) {
|
||||||
// Needs to do a Get and Set, Update will not take just the Data field
|
// Needs to do a Get and Set, Update will not take just the Data field
|
||||||
// or a configMap that is not the very last revision
|
// or a configMap that is not the very last revision
|
||||||
config, err := f.getNginxConfigMap()
|
config, err := f.getNginxConfigMap()
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred())
|
||||||
return err
|
Expect(config).NotTo(BeNil(), "expected a configmap but none returned")
|
||||||
}
|
|
||||||
if config == nil {
|
|
||||||
return fmt.Errorf("Unable to get nginx-configuration configMap")
|
|
||||||
}
|
|
||||||
|
|
||||||
config.Data = cmData
|
config.Data = cmData
|
||||||
|
|
||||||
|
@ -328,25 +327,19 @@ func (f *Framework) SetNginxConfigMapData(cmData map[string]string) error {
|
||||||
CoreV1().
|
CoreV1().
|
||||||
ConfigMaps(f.IngressController.Namespace).
|
ConfigMaps(f.IngressController.Namespace).
|
||||||
Update(config)
|
Update(config)
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred())
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateNginxConfigMapData updates single field in ingress-nginx's nginx-configuration map data
|
// UpdateNginxConfigMapData updates single field in ingress-nginx's nginx-configuration map data
|
||||||
func (f *Framework) UpdateNginxConfigMapData(key string, value string) error {
|
func (f *Framework) UpdateNginxConfigMapData(key string, value string) {
|
||||||
config, err := f.GetNginxConfigMapData()
|
config, err := f.GetNginxConfigMapData()
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred(), "unexpected error reading configmap")
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
config[key] = value
|
config[key] = value
|
||||||
|
|
||||||
return f.SetNginxConfigMapData(config)
|
f.SetNginxConfigMapData(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateDeployment runs the given updateFunc on the deployment and waits for it to be updated
|
// UpdateDeployment runs the given updateFunc on the deployment and waits for it to be updated
|
||||||
|
@ -380,7 +373,7 @@ func UpdateDeployment(kubeClientSet kubernetes.Interface, namespace string, name
|
||||||
LabelSelector: fields.SelectorFromSet(fields.Set(deployment.Spec.Template.ObjectMeta.Labels)).String(),
|
LabelSelector: fields.SelectorFromSet(fields.Set(deployment.Spec.Template.ObjectMeta.Labels)).String(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "failed to wait for nginx-ingress-controller replica count to be %v", replicas)
|
return errors.Wrapf(err, "waiting for nginx-ingress-controller replica count to be %v", replicas)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -428,6 +421,7 @@ func newSingleIngress(name, path, host, ns, service string, port int, annotation
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if withTLS {
|
if withTLS {
|
||||||
ing.Spec.TLS = []extensions.IngressTLS{
|
ing.Spec.TLS = []extensions.IngressTLS{
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,10 +17,9 @@ limitations under the License.
|
||||||
package framework
|
package framework
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
extensions "k8s.io/api/extensions/v1beta1"
|
extensions "k8s.io/api/extensions/v1beta1"
|
||||||
|
@ -31,13 +30,13 @@ import (
|
||||||
|
|
||||||
// NewGRPCFortuneTellerDeployment creates a new single replica
|
// NewGRPCFortuneTellerDeployment creates a new single replica
|
||||||
// deployment of the fortune teller image in a particular namespace
|
// deployment of the fortune teller image in a particular namespace
|
||||||
func (f *Framework) NewGRPCFortuneTellerDeployment() error {
|
func (f *Framework) NewGRPCFortuneTellerDeployment() {
|
||||||
return f.NewNewGRPCFortuneTellerDeploymentWithReplicas(1)
|
f.NewNewGRPCFortuneTellerDeploymentWithReplicas(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNewGRPCFortuneTellerDeploymentWithReplicas creates a new deployment of the
|
// NewNewGRPCFortuneTellerDeploymentWithReplicas creates a new deployment of the
|
||||||
// fortune teller image in a particular namespace. Number of replicas is configurable
|
// fortune teller image in a particular namespace. Number of replicas is configurable
|
||||||
func (f *Framework) NewNewGRPCFortuneTellerDeploymentWithReplicas(replicas int32) error {
|
func (f *Framework) NewNewGRPCFortuneTellerDeploymentWithReplicas(replicas int32) {
|
||||||
deployment := &extensions.Deployment{
|
deployment := &extensions.Deployment{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "fortune-teller",
|
Name: "fortune-teller",
|
||||||
|
@ -77,20 +76,13 @@ func (f *Framework) NewNewGRPCFortuneTellerDeploymentWithReplicas(replicas int32
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := f.EnsureDeployment(deployment)
|
d, err := f.EnsureDeployment(deployment)
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred())
|
||||||
return err
|
Expect(d).NotTo(BeNil(), "expected a fortune-teller deployment")
|
||||||
}
|
|
||||||
|
|
||||||
if d == nil {
|
|
||||||
return fmt.Errorf("unexpected error creating deployement for fortune-teller")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = WaitForPodsReady(f.KubeClientSet, 5*time.Minute, int(replicas), f.IngressController.Namespace, metav1.ListOptions{
|
err = WaitForPodsReady(f.KubeClientSet, 5*time.Minute, int(replicas), f.IngressController.Namespace, metav1.ListOptions{
|
||||||
LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(),
|
LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred(), "failed to wait for to become ready")
|
||||||
return errors.Wrap(err, "failed to wait for to become ready")
|
|
||||||
}
|
|
||||||
|
|
||||||
service := &corev1.Service{
|
service := &corev1.Service{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
@ -112,14 +104,5 @@ func (f *Framework) NewNewGRPCFortuneTellerDeploymentWithReplicas(replicas int32
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := f.EnsureService(service)
|
f.EnsureService(service)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if s == nil {
|
|
||||||
return fmt.Errorf("unexpected error creating service for fortune-teller deployment")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,9 @@ limitations under the License.
|
||||||
package framework
|
package framework
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
extensions "k8s.io/api/extensions/v1beta1"
|
extensions "k8s.io/api/extensions/v1beta1"
|
||||||
|
@ -60,7 +59,7 @@ bind-address = "0.0.0.0:8088"
|
||||||
|
|
||||||
// NewInfluxDBDeployment creates an InfluxDB server configured to reply
|
// NewInfluxDBDeployment creates an InfluxDB server configured to reply
|
||||||
// on 8086/tcp and 8089/udp
|
// on 8086/tcp and 8089/udp
|
||||||
func (f *Framework) NewInfluxDBDeployment() error {
|
func (f *Framework) NewInfluxDBDeployment() {
|
||||||
configuration := &corev1.ConfigMap{
|
configuration := &corev1.ConfigMap{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "influxdb-config",
|
Name: "influxdb-config",
|
||||||
|
@ -72,13 +71,9 @@ func (f *Framework) NewInfluxDBDeployment() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
cm, err := f.EnsureConfigMap(configuration)
|
cm, err := f.EnsureConfigMap(configuration)
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred(), "failed to create an Influxdb deployment")
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if cm == nil {
|
Expect(cm).NotTo(BeNil(), "expected a configmap but none returned")
|
||||||
return fmt.Errorf("unexpected error creating configmap for influxdb")
|
|
||||||
}
|
|
||||||
|
|
||||||
deployment := &extensions.Deployment{
|
deployment := &extensions.Deployment{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
@ -143,20 +138,12 @@ func (f *Framework) NewInfluxDBDeployment() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := f.EnsureDeployment(deployment)
|
d, err := f.EnsureDeployment(deployment)
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred(), "failed to create an Influxdb deployment")
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if d == nil {
|
Expect(d).NotTo(BeNil(), "unexpected error creating deployement for influxdb")
|
||||||
return fmt.Errorf("unexpected error creating deployement for influxdb")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = WaitForPodsReady(f.KubeClientSet, 5*time.Minute, 1, f.IngressController.Namespace, metav1.ListOptions{
|
err = WaitForPodsReady(f.KubeClientSet, 5*time.Minute, 1, f.IngressController.Namespace, metav1.ListOptions{
|
||||||
LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(),
|
LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred(), "failed to wait for influxdb to become ready")
|
||||||
return errors.Wrap(err, "failed to wait for influxdb to become ready")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
api "k8s.io/api/core/v1"
|
api "k8s.io/api/core/v1"
|
||||||
core "k8s.io/api/core/v1"
|
core "k8s.io/api/core/v1"
|
||||||
extensions "k8s.io/api/extensions/v1beta1"
|
extensions "k8s.io/api/extensions/v1beta1"
|
||||||
|
@ -31,15 +33,23 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// EnsureSecret creates a Secret object or returns it if it already exists.
|
// EnsureSecret creates a Secret object or returns it if it already exists.
|
||||||
func (f *Framework) EnsureSecret(secret *api.Secret) (*api.Secret, error) {
|
func (f *Framework) EnsureSecret(secret *api.Secret) *api.Secret {
|
||||||
s, err := f.KubeClientSet.CoreV1().Secrets(secret.Namespace).Create(secret)
|
s, err := f.KubeClientSet.CoreV1().Secrets(secret.Namespace).Create(secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if k8sErrors.IsAlreadyExists(err) {
|
if k8sErrors.IsAlreadyExists(err) {
|
||||||
return f.KubeClientSet.CoreV1().Secrets(secret.Namespace).Update(secret)
|
s, err := f.KubeClientSet.CoreV1().Secrets(secret.Namespace).Update(secret)
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error updating secret")
|
||||||
|
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
return nil, err
|
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error creating secret")
|
||||||
}
|
}
|
||||||
return s, nil
|
|
||||||
|
Expect(s).NotTo(BeNil())
|
||||||
|
Expect(s.ObjectMeta).NotTo(BeNil())
|
||||||
|
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureConfigMap creates a ConfigMap object or returns it if it already exists.
|
// EnsureConfigMap creates a ConfigMap object or returns it if it already exists.
|
||||||
|
@ -51,40 +61,49 @@ func (f *Framework) EnsureConfigMap(configMap *api.ConfigMap) (*api.ConfigMap, e
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cm, nil
|
return cm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureIngress creates an Ingress object or returns it if it already exists.
|
// EnsureIngress creates an Ingress object or returns it if it already exists.
|
||||||
func (f *Framework) EnsureIngress(ingress *extensions.Ingress) (*extensions.Ingress, error) {
|
func (f *Framework) EnsureIngress(ingress *extensions.Ingress) *extensions.Ingress {
|
||||||
s, err := f.KubeClientSet.ExtensionsV1beta1().Ingresses(ingress.Namespace).Update(ingress)
|
ing, err := f.KubeClientSet.ExtensionsV1beta1().Ingresses(ingress.Namespace).Update(ingress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if k8sErrors.IsNotFound(err) {
|
if k8sErrors.IsNotFound(err) {
|
||||||
s, err = f.KubeClientSet.ExtensionsV1beta1().Ingresses(ingress.Namespace).Create(ingress)
|
ing, err = f.KubeClientSet.ExtensionsV1beta1().Ingresses(ingress.Namespace).Create(ingress)
|
||||||
if err != nil {
|
Expect(err).NotTo(HaveOccurred(), "unexpected error creating ingress")
|
||||||
return nil, err
|
return ing
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Annotations == nil {
|
Expect(ing).NotTo(BeNil())
|
||||||
s.Annotations = make(map[string]string)
|
|
||||||
|
if ing.Annotations == nil {
|
||||||
|
ing.Annotations = make(map[string]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return ing
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureService creates a Service object or returns it if it already exists.
|
// EnsureService creates a Service object or returns it if it already exists.
|
||||||
func (f *Framework) EnsureService(service *core.Service) (*core.Service, error) {
|
func (f *Framework) EnsureService(service *core.Service) *core.Service {
|
||||||
s, err := f.KubeClientSet.CoreV1().Services(service.Namespace).Update(service)
|
s, err := f.KubeClientSet.CoreV1().Services(service.Namespace).Update(service)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if k8sErrors.IsNotFound(err) {
|
if k8sErrors.IsNotFound(err) {
|
||||||
return f.KubeClientSet.CoreV1().Services(service.Namespace).Create(service)
|
s, err := f.KubeClientSet.CoreV1().Services(service.Namespace).Create(service)
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error creating service")
|
||||||
|
return s
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil, err
|
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
}
|
}
|
||||||
return s, nil
|
|
||||||
|
Expect(s).NotTo(BeNil(), "expected a service but none returned")
|
||||||
|
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnsureDeployment creates a Deployment object or returns it if it already exists.
|
// EnsureDeployment creates a Deployment object or returns it if it already exists.
|
||||||
|
|
|
@ -25,7 +25,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logs returns the log entries of a given Pod.
|
// Logs returns the log entries of a given Pod.
|
||||||
func (f *Framework) Logs(pod *v1.Pod) (string, error) {
|
func Logs(pod *v1.Pod) (string, error) {
|
||||||
var (
|
var (
|
||||||
execOut bytes.Buffer
|
execOut bytes.Buffer
|
||||||
execErr bytes.Buffer
|
execErr bytes.Buffer
|
||||||
|
@ -35,14 +35,13 @@ func (f *Framework) Logs(pod *v1.Pod) (string, error) {
|
||||||
return "", fmt.Errorf("could not determine which container to use")
|
return "", fmt.Errorf("could not determine which container to use")
|
||||||
}
|
}
|
||||||
|
|
||||||
args := fmt.Sprintf("kubectl logs -n %v %v", pod.Namespace, pod.Name)
|
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("%v logs --namespace %s %s", KubectlPath, pod.Namespace, pod.Name))
|
||||||
cmd := exec.Command("/bin/bash", "-c", args)
|
|
||||||
cmd.Stdout = &execOut
|
cmd.Stdout = &execOut
|
||||||
cmd.Stderr = &execErr
|
cmd.Stderr = &execErr
|
||||||
|
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("could not execute: %v", err)
|
return "", fmt.Errorf("could not execute '%s %s': %v", cmd.Path, cmd.Args, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if execErr.Len() > 0 {
|
if execErr.Len() > 0 {
|
||||||
|
|
|
@ -32,6 +32,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
@ -140,8 +142,9 @@ func CreateIngressMASecret(client kubernetes.Interface, host string, secretName,
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitForTLS waits until the TLS handshake with a given server completes successfully.
|
// WaitForTLS waits until the TLS handshake with a given server completes successfully.
|
||||||
func WaitForTLS(url string, tlsConfig *tls.Config) error {
|
func WaitForTLS(url string, tlsConfig *tls.Config) {
|
||||||
return wait.Poll(Poll, 30*time.Second, matchTLSServerName(url, tlsConfig))
|
err := wait.Poll(Poll, 30*time.Second, matchTLSServerName(url, tlsConfig))
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "timeout waiting for TLS configuration in URL %s", url)
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateRSACert generates a basic self signed certificate using a key length
|
// generateRSACert generates a basic self signed certificate using a key length
|
||||||
|
|
|
@ -27,7 +27,6 @@ import (
|
||||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||||
extensions "k8s.io/api/extensions/v1beta1"
|
extensions "k8s.io/api/extensions/v1beta1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/kubernetes"
|
|
||||||
|
|
||||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
)
|
)
|
||||||
|
@ -37,17 +36,24 @@ var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
host := "foo.com"
|
host := "foo.com"
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := enableDynamicCertificates(f.IngressController.Namespace, f.KubeClientSet)
|
err := framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "nginx-ingress-controller", 1,
|
||||||
Expect(err).NotTo(HaveOccurred())
|
func(deployment *appsv1beta1.Deployment) error {
|
||||||
|
args := deployment.Spec.Template.Spec.Containers[0].Args
|
||||||
|
args = append(args, "--enable-dynamic-certificates")
|
||||||
|
args = append(args, "--enable-ssl-chain-completion=false")
|
||||||
|
deployment.Spec.Template.Spec.Containers[0].Args = args
|
||||||
|
_, err := f.KubeClientSet.AppsV1beta1().Deployments(f.IngressController.Namespace).Update(deployment)
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
return err
|
||||||
func(cfg string) bool {
|
|
||||||
return strings.Contains(cfg, "ok, res = pcall(require, \"certificate\")")
|
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
err = f.NewEchoDeploymentWithReplicas(1)
|
f.WaitForNginxConfiguration(
|
||||||
Expect(err).NotTo(HaveOccurred())
|
func(cfg string) bool {
|
||||||
|
return strings.Contains(cfg, "ok, res = pcall(require, \"certificate\")")
|
||||||
|
})
|
||||||
|
|
||||||
|
f.NewEchoDeploymentWithReplicas(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("picks up the certificate when we add TLS spec to existing ingress", func() {
|
It("picks up the certificate when we add TLS spec to existing ingress", func() {
|
||||||
|
@ -74,27 +80,27 @@ var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("picks up the previously missing secret for a given ingress without reloading", func() {
|
It("picks up the previously missing secret for a given ingress without reloading", func() {
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
ing := framework.NewSingleIngressWithTLS(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.EnsureIngress(ing)
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
time.Sleep(waitForLuaSync)
|
time.Sleep(waitForLuaSync)
|
||||||
|
|
||||||
ensureHTTPSRequest(fmt.Sprintf("%s?id=dummy_log_splitter_foo_bar", f.IngressController.HTTPSURL), host, "ingress.local")
|
ensureHTTPSRequest(fmt.Sprintf("%s?id=dummy_log_splitter_foo_bar", f.IngressController.HTTPSURL), host, "ingress.local")
|
||||||
|
|
||||||
_, err = framework.CreateIngressTLSSecret(f.KubeClientSet,
|
_, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
|
||||||
ing.Spec.TLS[0].Hosts,
|
ing.Spec.TLS[0].Hosts,
|
||||||
ing.Spec.TLS[0].SecretName,
|
ing.Spec.TLS[0].SecretName,
|
||||||
ing.Namespace)
|
ing.Namespace)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
By("configuring certificate_by_lua and skipping Nginx configuration of the new certificate")
|
By("configuring certificate_by_lua and skipping Nginx configuration of the new certificate")
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "ssl_certificate_by_lua_block") &&
|
return strings.Contains(server, "ssl_certificate_by_lua_block") &&
|
||||||
!strings.Contains(server, fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
!strings.Contains(server, fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
||||||
!strings.Contains(server, fmt.Sprintf("ssl_certificate_key /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
!strings.Contains(server, fmt.Sprintf("ssl_certificate_key /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
||||||
strings.Contains(server, "listen 443")
|
strings.Contains(server, "listen 443")
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
|
|
||||||
time.Sleep(waitForLuaSync)
|
time.Sleep(waitForLuaSync)
|
||||||
|
|
||||||
|
@ -114,14 +120,13 @@ var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
|
|
||||||
Context("given an ingress with TLS correctly configured", func() {
|
Context("given an ingress with TLS correctly configured", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
time.Sleep(waitForLuaSync)
|
time.Sleep(waitForLuaSync)
|
||||||
|
|
||||||
ensureHTTPSRequest(f.IngressController.HTTPSURL, host, "ingress.local")
|
ensureHTTPSRequest(f.IngressController.HTTPSURL, host, "ingress.local")
|
||||||
|
|
||||||
_, err = framework.CreateIngressTLSSecret(f.KubeClientSet,
|
_, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
|
||||||
ing.Spec.TLS[0].Hosts,
|
ing.Spec.TLS[0].Hosts,
|
||||||
ing.Spec.TLS[0].SecretName,
|
ing.Spec.TLS[0].SecretName,
|
||||||
ing.Namespace)
|
ing.Namespace)
|
||||||
|
@ -129,14 +134,13 @@ var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
time.Sleep(waitForLuaSync)
|
time.Sleep(waitForLuaSync)
|
||||||
|
|
||||||
By("configuring certificate_by_lua and skipping Nginx configuration of the new certificate")
|
By("configuring certificate_by_lua and skipping Nginx configuration of the new certificate")
|
||||||
err = f.WaitForNginxServer(ing.Spec.TLS[0].Hosts[0],
|
f.WaitForNginxServer(ing.Spec.TLS[0].Hosts[0],
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "ssl_certificate_by_lua_block") &&
|
return strings.Contains(server, "ssl_certificate_by_lua_block") &&
|
||||||
!strings.Contains(server, fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
!strings.Contains(server, fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
||||||
!strings.Contains(server, fmt.Sprintf("ssl_certificate_key /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
!strings.Contains(server, fmt.Sprintf("ssl_certificate_key /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
||||||
strings.Contains(server, "listen 443")
|
strings.Contains(server, "listen 443")
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
|
|
||||||
time.Sleep(waitForLuaSync)
|
time.Sleep(waitForLuaSync)
|
||||||
|
|
||||||
|
@ -146,6 +150,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
|
|
||||||
It("picks up the updated certificate without reloading", func() {
|
It("picks up the updated certificate without reloading", func() {
|
||||||
ing, err := f.KubeClientSet.ExtensionsV1beta1().Ingresses(f.IngressController.Namespace).Get(host, metav1.GetOptions{})
|
ing, err := f.KubeClientSet.ExtensionsV1beta1().Ingresses(f.IngressController.Namespace).Get(host, metav1.GetOptions{})
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
ensureHTTPSRequest(fmt.Sprintf("%s?id=dummy_log_splitter_foo_bar", f.IngressController.HTTPSURL), host, host)
|
ensureHTTPSRequest(fmt.Sprintf("%s?id=dummy_log_splitter_foo_bar", f.IngressController.HTTPSURL), host, host)
|
||||||
|
|
||||||
|
@ -157,14 +162,13 @@ var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
time.Sleep(waitForLuaSync)
|
time.Sleep(waitForLuaSync)
|
||||||
|
|
||||||
By("configuring certificate_by_lua and skipping Nginx configuration of the new certificate")
|
By("configuring certificate_by_lua and skipping Nginx configuration of the new certificate")
|
||||||
err = f.WaitForNginxServer(ing.Spec.TLS[0].Hosts[0],
|
f.WaitForNginxServer(ing.Spec.TLS[0].Hosts[0],
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "ssl_certificate_by_lua_block") &&
|
return strings.Contains(server, "ssl_certificate_by_lua_block") &&
|
||||||
!strings.Contains(server, fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
!strings.Contains(server, fmt.Sprintf("ssl_certificate /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
||||||
!strings.Contains(server, fmt.Sprintf("ssl_certificate_key /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
!strings.Contains(server, fmt.Sprintf("ssl_certificate_key /etc/ingress-controller/ssl/%s-%s.pem;", ing.Namespace, host)) &&
|
||||||
strings.Contains(server, "listen 443")
|
strings.Contains(server, "listen 443")
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
|
|
||||||
time.Sleep(waitForLuaSync)
|
time.Sleep(waitForLuaSync)
|
||||||
|
|
||||||
|
@ -192,14 +196,13 @@ var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
time.Sleep(waitForLuaSync)
|
time.Sleep(waitForLuaSync)
|
||||||
|
|
||||||
By("configuring certificate_by_lua and skipping Nginx configuration of the new certificate")
|
By("configuring certificate_by_lua and skipping Nginx configuration of the new certificate")
|
||||||
err = f.WaitForNginxServer(ing.Spec.TLS[0].Hosts[0],
|
f.WaitForNginxServer(ing.Spec.TLS[0].Hosts[0],
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "ssl_certificate_by_lua_block") &&
|
return strings.Contains(server, "ssl_certificate_by_lua_block") &&
|
||||||
strings.Contains(server, "ssl_certificate /etc/ingress-controller/ssl/default-fake-certificate.pem;") &&
|
strings.Contains(server, "ssl_certificate /etc/ingress-controller/ssl/default-fake-certificate.pem;") &&
|
||||||
strings.Contains(server, "ssl_certificate_key /etc/ingress-controller/ssl/default-fake-certificate.pem;") &&
|
strings.Contains(server, "ssl_certificate_key /etc/ingress-controller/ssl/default-fake-certificate.pem;") &&
|
||||||
strings.Contains(server, "listen 443")
|
strings.Contains(server, "listen 443")
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
|
|
||||||
time.Sleep(waitForLuaSync)
|
time.Sleep(waitForLuaSync)
|
||||||
|
|
||||||
|
@ -242,16 +245,3 @@ var _ = framework.IngressNginxDescribe("Dynamic Certificate", func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
func enableDynamicCertificates(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-certificates")
|
|
||||||
args = append(args, "--enable-ssl-chain-completion=false")
|
|
||||||
deployment.Spec.Template.Spec.Containers[0].Args = args
|
|
||||||
_, err := kubeClientSet.AppsV1beta1().Deployments(namespace).Update(deployment)
|
|
||||||
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
|
@ -47,60 +47,54 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
||||||
f := framework.NewDefaultFramework("dynamic-configuration")
|
f := framework.NewDefaultFramework("dynamic-configuration")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(1)
|
f.NewEchoDeploymentWithReplicas(1)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
ensureIngress(f, "foo.com")
|
ensureIngress(f, "foo.com")
|
||||||
})
|
})
|
||||||
|
|
||||||
It("configures balancer Lua middleware correctly", func() {
|
It("configures balancer Lua middleware correctly", func() {
|
||||||
err := f.WaitForNginxConfiguration(func(cfg string) bool {
|
f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||||
return strings.Contains(cfg, "balancer.init_worker()") && strings.Contains(cfg, "balancer.balance()")
|
return strings.Contains(cfg, "balancer.init_worker()") && strings.Contains(cfg, "balancer.balance()")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
host := "foo.com"
|
host := "foo.com"
|
||||||
err = f.WaitForNginxServer(host, func(server string) bool {
|
f.WaitForNginxServer(host, func(server string) bool {
|
||||||
return strings.Contains(server, "balancer.rewrite()") && strings.Contains(server, "balancer.log()")
|
return strings.Contains(server, "balancer.rewrite()") && strings.Contains(server, "balancer.log()")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("sets nameservers for Lua", func() {
|
It("sets nameservers for Lua", func() {
|
||||||
err := f.WaitForNginxConfiguration(func(cfg string) bool {
|
f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||||
r := regexp.MustCompile(`configuration.nameservers = { [".,0-9a-zA-Z]+ }`)
|
r := regexp.MustCompile(`configuration.nameservers = { [".,0-9a-zA-Z]+ }`)
|
||||||
return r.MatchString(cfg)
|
return r.MatchString(cfg)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("when only backends change", func() {
|
Context("when only backends change", func() {
|
||||||
It("handles endpoints only changes", func() {
|
It("handles endpoints only changes", func() {
|
||||||
var nginxConfig string
|
var nginxConfig string
|
||||||
err := f.WaitForNginxConfiguration(func(cfg string) bool {
|
f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||||
nginxConfig = cfg
|
nginxConfig = cfg
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
replicas := 2
|
replicas := 2
|
||||||
err = framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "http-svc", replicas, nil)
|
err := framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "http-svc", replicas, nil)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
time.Sleep(waitForLuaSync)
|
time.Sleep(waitForLuaSync)
|
||||||
|
|
||||||
ensureRequest(f, "foo.com")
|
ensureRequest(f, "foo.com")
|
||||||
|
|
||||||
var newNginxConfig string
|
var newNginxConfig string
|
||||||
err = f.WaitForNginxConfiguration(func(cfg string) bool {
|
f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||||
newNginxConfig = cfg
|
newNginxConfig = cfg
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
Expect(nginxConfig).Should(Equal(newNginxConfig))
|
Expect(nginxConfig).Should(Equal(newNginxConfig))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("handles an annotation change", func() {
|
It("handles an annotation change", func() {
|
||||||
var nginxConfig string
|
var nginxConfig string
|
||||||
err := f.WaitForNginxConfiguration(func(cfg string) bool {
|
f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||||
nginxConfig = cfg
|
nginxConfig = cfg
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
@ -116,7 +110,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
||||||
ensureRequest(f, "foo.com")
|
ensureRequest(f, "foo.com")
|
||||||
|
|
||||||
var newNginxConfig string
|
var newNginxConfig string
|
||||||
err = f.WaitForNginxConfiguration(func(cfg string) bool {
|
f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||||
newNginxConfig = cfg
|
newNginxConfig = cfg
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
@ -127,7 +121,7 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
||||||
|
|
||||||
It("handles a non backend update", func() {
|
It("handles a non backend update", func() {
|
||||||
var nginxConfig string
|
var nginxConfig string
|
||||||
err := f.WaitForNginxConfiguration(func(cfg string) bool {
|
f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||||
nginxConfig = cfg
|
nginxConfig = cfg
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
@ -149,11 +143,10 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
var newNginxConfig string
|
var newNginxConfig string
|
||||||
err = f.WaitForNginxConfiguration(func(cfg string) bool {
|
f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||||
newNginxConfig = cfg
|
newNginxConfig = cfg
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
Expect(nginxConfig).ShouldNot(Equal(newNginxConfig))
|
Expect(nginxConfig).ShouldNot(Equal(newNginxConfig))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -181,7 +174,7 @@ func ensureIngress(f *framework.Framework, host string) *extensions.Ingress {
|
||||||
"nginx.ingress.kubernetes.io/session-cookie-max-age": "172800"}))
|
"nginx.ingress.kubernetes.io/session-cookie-max-age": "172800"}))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(ing).NotTo(BeNil())
|
Expect(ing).NotTo(BeNil())
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, fmt.Sprintf("server_name %s ;", host)) &&
|
return strings.Contains(server, fmt.Sprintf("server_name %s ;", host)) &&
|
||||||
strings.Contains(server, "proxy_pass http://upstream_balancer;")
|
strings.Contains(server, "proxy_pass http://upstream_balancer;")
|
||||||
|
|
|
@ -45,15 +45,12 @@ var _ = framework.IngressNginxDescribe("Service backend - 503", func() {
|
||||||
host := "nonexistent.svc.com"
|
host := "nonexistent.svc.com"
|
||||||
|
|
||||||
bi := buildIngressWithNonexistentService(host, f.IngressController.Namespace, "/")
|
bi := buildIngressWithNonexistentService(host, f.IngressController.Namespace, "/")
|
||||||
ing, err := f.EnsureIngress(bi)
|
f.EnsureIngress(bi)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "return 503;")
|
return strings.Contains(server, "proxy_pass http://upstream_balancer;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -68,19 +65,15 @@ var _ = framework.IngressNginxDescribe("Service backend - 503", func() {
|
||||||
|
|
||||||
bi, bs := buildIngressWithUnavailableServiceEndpoints(host, f.IngressController.Namespace, "/")
|
bi, bs := buildIngressWithUnavailableServiceEndpoints(host, f.IngressController.Namespace, "/")
|
||||||
|
|
||||||
svc, err := f.EnsureService(bs)
|
svc := f.EnsureService(bs)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(svc).NotTo(BeNil())
|
Expect(svc).NotTo(BeNil())
|
||||||
|
|
||||||
ing, err := f.EnsureIngress(bi)
|
f.EnsureIngress(bi)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "return 503;")
|
return strings.Contains(server, "proxy_pass http://upstream_balancer;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
|
|
@ -30,8 +30,7 @@ var _ = framework.IngressNginxDescribe("Configmap change", func() {
|
||||||
f := framework.NewDefaultFramework("configmap-change")
|
f := framework.NewDefaultFramework("configmap-change")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -40,22 +39,20 @@ var _ = framework.IngressNginxDescribe("Configmap change", func() {
|
||||||
It("should reload after an update in the configuration", func() {
|
It("should reload after an update in the configuration", func() {
|
||||||
host := "configmap-change"
|
host := "configmap-change"
|
||||||
|
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.EnsureIngress(ing)
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
wlKey := "whitelist-source-range"
|
wlKey := "whitelist-source-range"
|
||||||
wlValue := "1.1.1.1"
|
wlValue := "1.1.1.1"
|
||||||
|
|
||||||
By("adding a whitelist-source-range")
|
By("adding a whitelist-source-range")
|
||||||
|
|
||||||
err = f.UpdateNginxConfigMapData(wlKey, wlValue)
|
f.UpdateNginxConfigMapData(wlKey, wlValue)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
checksumRegex := regexp.MustCompile("Configuration checksum:\\s+(\\d+)")
|
checksumRegex := regexp.MustCompile("Configuration checksum:\\s+(\\d+)")
|
||||||
checksum := ""
|
checksum := ""
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
f.WaitForNginxConfiguration(
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
// before returning, extract the current checksum
|
// before returning, extract the current checksum
|
||||||
match := checksumRegex.FindStringSubmatch(cfg)
|
match := checksumRegex.FindStringSubmatch(cfg)
|
||||||
|
@ -66,16 +63,14 @@ var _ = framework.IngressNginxDescribe("Configmap change", func() {
|
||||||
return strings.Contains(cfg, "geo $the_real_ip $deny_") &&
|
return strings.Contains(cfg, "geo $the_real_ip $deny_") &&
|
||||||
strings.Contains(cfg, "1.1.1.1 0")
|
strings.Contains(cfg, "1.1.1.1 0")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(checksum).NotTo(BeEmpty())
|
Expect(checksum).NotTo(BeEmpty())
|
||||||
|
|
||||||
By("changing error-log-level")
|
By("changing error-log-level")
|
||||||
|
|
||||||
err = f.UpdateNginxConfigMapData("error-log-level", "debug")
|
f.UpdateNginxConfigMapData("error-log-level", "debug")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
newChecksum := ""
|
newChecksum := ""
|
||||||
err = f.WaitForNginxConfiguration(
|
f.WaitForNginxConfiguration(
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
match := checksumRegex.FindStringSubmatch(cfg)
|
match := checksumRegex.FindStringSubmatch(cfg)
|
||||||
if len(match) > 0 {
|
if len(match) > 0 {
|
||||||
|
@ -84,8 +79,6 @@ var _ = framework.IngressNginxDescribe("Configmap change", func() {
|
||||||
|
|
||||||
return strings.ContainsAny(cfg, "error_log /var/log/nginx/error.log debug;")
|
return strings.ContainsAny(cfg, "error_log /var/log/nginx/error.log debug;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
Expect(checksum).NotTo(BeEquivalentTo(newChecksum))
|
Expect(checksum).NotTo(BeEquivalentTo(newChecksum))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -34,11 +34,8 @@ var _ = framework.IngressNginxDescribe("X-Forwarded headers", func() {
|
||||||
setting := "use-forwarded-headers"
|
setting := "use-forwarded-headers"
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.UpdateNginxConfigMapData(setting, "false")
|
||||||
|
|
||||||
err = f.UpdateNginxConfigMapData(setting, "false")
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -47,18 +44,15 @@ var _ = framework.IngressNginxDescribe("X-Forwarded headers", func() {
|
||||||
It("should trust X-Forwarded headers when setting is true", func() {
|
It("should trust X-Forwarded headers when setting is true", func() {
|
||||||
host := "forwarded-headers"
|
host := "forwarded-headers"
|
||||||
|
|
||||||
err := f.UpdateNginxConfigMapData(setting, "true")
|
f.UpdateNginxConfigMapData(setting, "true")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.EnsureIngress(ing)
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "server_name forwarded-headers")
|
return strings.Contains(server, "server_name forwarded-headers")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -80,18 +74,14 @@ var _ = framework.IngressNginxDescribe("X-Forwarded headers", func() {
|
||||||
It("should not trust X-Forwarded headers when setting is false", func() {
|
It("should not trust X-Forwarded headers when setting is false", func() {
|
||||||
host := "forwarded-headers"
|
host := "forwarded-headers"
|
||||||
|
|
||||||
err := f.UpdateNginxConfigMapData(setting, "false")
|
f.UpdateNginxConfigMapData(setting, "false")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "server_name forwarded-headers")
|
return strings.Contains(server, "server_name forwarded-headers")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
|
90
test/e2e/settings/geoip2.go
Normal file
90
test/e2e/settings/geoip2.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
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"
|
||||||
|
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
"github.com/parnurzeal/gorequest"
|
||||||
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = framework.IngressNginxDescribe("Geoip2", func() {
|
||||||
|
f := framework.NewDefaultFramework("geoip2")
|
||||||
|
|
||||||
|
host := "geoip2"
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
f.NewEchoDeployment()
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should only allow requests from specific countries", func() {
|
||||||
|
f.UpdateNginxConfigMapData("use-geoip2", "true")
|
||||||
|
|
||||||
|
httpSnippetAllowingOnlyAustralia :=
|
||||||
|
`map $geoip2_city_country_code $blocked_country {
|
||||||
|
default 1;
|
||||||
|
AU 0;
|
||||||
|
}`
|
||||||
|
f.UpdateNginxConfigMapData("http-snippet", httpSnippetAllowingOnlyAustralia)
|
||||||
|
|
||||||
|
f.WaitForNginxConfiguration(
|
||||||
|
func(cfg string) bool {
|
||||||
|
return strings.Contains(cfg, "map $geoip2_city_country_code $blocked_country")
|
||||||
|
})
|
||||||
|
|
||||||
|
configSnippet :=
|
||||||
|
`if ($blocked_country) {
|
||||||
|
return 403;
|
||||||
|
}`
|
||||||
|
|
||||||
|
annotations := map[string]string{
|
||||||
|
"nginx.ingress.kubernetes.io/configuration-snippet": configSnippet,
|
||||||
|
}
|
||||||
|
|
||||||
|
f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations))
|
||||||
|
|
||||||
|
f.WaitForNginxConfiguration(
|
||||||
|
func(cfg string) bool {
|
||||||
|
return strings.Contains(cfg, "if ($blocked_country)")
|
||||||
|
})
|
||||||
|
|
||||||
|
// Should be blocked
|
||||||
|
usIP := "8.8.8.8"
|
||||||
|
resp, _, errs := gorequest.New().
|
||||||
|
Get(f.IngressController.HTTPURL).
|
||||||
|
Set("Host", host).
|
||||||
|
Set("X-Forwarded-For", usIP).
|
||||||
|
End()
|
||||||
|
Expect(errs).To(BeNil())
|
||||||
|
Expect(resp.StatusCode).Should(Equal(http.StatusForbidden))
|
||||||
|
|
||||||
|
// Shouldn't be blocked
|
||||||
|
australianIP := "1.1.1.1"
|
||||||
|
resp, _, errs = gorequest.New().
|
||||||
|
Get(f.IngressController.HTTPURL).
|
||||||
|
Set("Host", host).
|
||||||
|
Set("X-Forwarded-For", australianIP).
|
||||||
|
End()
|
||||||
|
Expect(errs).To(BeNil())
|
||||||
|
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||||
|
})
|
||||||
|
})
|
|
@ -33,28 +33,22 @@ var _ = framework.IngressNginxDescribe("Global access block", func() {
|
||||||
host := "global-access-block"
|
host := "global-access-block"
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeploymentWithReplicas(1)
|
f.NewEchoDeploymentWithReplicas(1)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
||||||
|
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should block CIDRs defined in the ConfigMap", func() {
|
It("should block CIDRs defined in the ConfigMap", func() {
|
||||||
err := f.UpdateNginxConfigMapData("block-cidrs", "172.16.0.0/12,192.168.0.0/16,10.0.0.0/8")
|
f.UpdateNginxConfigMapData("block-cidrs", "172.16.0.0/12,192.168.0.0/16,10.0.0.0/8")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
f.WaitForNginxConfiguration(
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, "deny 172.16.0.0/12;") &&
|
return strings.Contains(cfg, "deny 172.16.0.0/12;") &&
|
||||||
strings.Contains(cfg, "deny 192.168.0.0/16;") &&
|
strings.Contains(cfg, "deny 192.168.0.0/16;") &&
|
||||||
strings.Contains(cfg, "deny 10.0.0.0/8;")
|
strings.Contains(cfg, "deny 10.0.0.0/8;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
// This test works for minikube, but may have problems with real kubernetes clusters,
|
// This test works for minikube, but may have problems with real kubernetes clusters,
|
||||||
// especially if connection is done via Internet. In this case, the test should be disabled/removed.
|
// especially if connection is done via Internet. In this case, the test should be disabled/removed.
|
||||||
|
@ -67,15 +61,13 @@ var _ = framework.IngressNginxDescribe("Global access block", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should block User-Agents defined in the ConfigMap", func() {
|
It("should block User-Agents defined in the ConfigMap", func() {
|
||||||
err := f.UpdateNginxConfigMapData("block-user-agents", "~*chrome\\/68\\.0\\.3440\\.106\\ safari\\/537\\.36,AlphaBot")
|
f.UpdateNginxConfigMapData("block-user-agents", "~*chrome\\/68\\.0\\.3440\\.106\\ safari\\/537\\.36,AlphaBot")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
f.WaitForNginxConfiguration(
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, "~*chrome\\/68\\.0\\.3440\\.106\\ safari\\/537\\.36 1;") &&
|
return strings.Contains(cfg, "~*chrome\\/68\\.0\\.3440\\.106\\ safari\\/537\\.36 1;") &&
|
||||||
strings.Contains(cfg, "AlphaBot 1;")
|
strings.Contains(cfg, "AlphaBot 1;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
// Should be blocked
|
// Should be blocked
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
|
@ -105,15 +97,13 @@ var _ = framework.IngressNginxDescribe("Global access block", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should block Referers defined in the ConfigMap", func() {
|
It("should block Referers defined in the ConfigMap", func() {
|
||||||
err := f.UpdateNginxConfigMapData("block-referers", "~*example\\.com,qwerty")
|
f.UpdateNginxConfigMapData("block-referers", "~*example\\.com,qwerty")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
f.WaitForNginxConfiguration(
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, "~*example\\.com 1;") &&
|
return strings.Contains(cfg, "~*example\\.com 1;") &&
|
||||||
strings.Contains(cfg, "qwerty 1;")
|
strings.Contains(cfg, "qwerty 1;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
// Should be blocked
|
// Should be blocked
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
|
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
|
|
||||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
)
|
)
|
||||||
|
@ -31,13 +30,11 @@ var _ = framework.IngressNginxDescribe("Main Snippet", func() {
|
||||||
|
|
||||||
It("should add value of main-snippet setting to nginx config", func() {
|
It("should add value of main-snippet setting to nginx config", func() {
|
||||||
expectedComment := "# main snippet"
|
expectedComment := "# main snippet"
|
||||||
err := f.UpdateNginxConfigMapData(mainSnippet, expectedComment)
|
f.UpdateNginxConfigMapData(mainSnippet, expectedComment)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
f.WaitForNginxConfiguration(
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, expectedComment)
|
return strings.Contains(cfg, expectedComment)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
|
|
||||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
)
|
)
|
||||||
|
@ -31,34 +30,29 @@ var _ = framework.IngressNginxDescribe("Multi Accept", func() {
|
||||||
|
|
||||||
It("should be enabled by default", func() {
|
It("should be enabled by default", func() {
|
||||||
expectedDirective := "multi_accept on;"
|
expectedDirective := "multi_accept on;"
|
||||||
err := f.WaitForNginxConfiguration(
|
f.WaitForNginxConfiguration(
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, expectedDirective)
|
return strings.Contains(cfg, expectedDirective)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be enabled when set to true", func() {
|
It("should be enabled when set to true", func() {
|
||||||
expectedDirective := "multi_accept on;"
|
expectedDirective := "multi_accept on;"
|
||||||
err := f.UpdateNginxConfigMapData(multiAccept, "true")
|
f.UpdateNginxConfigMapData(multiAccept, "true")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
f.WaitForNginxConfiguration(
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, expectedDirective)
|
return strings.Contains(cfg, expectedDirective)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be disabled when set to false", func() {
|
It("should be disabled when set to false", func() {
|
||||||
expectedDirective := "multi_accept off;"
|
expectedDirective := "multi_accept off;"
|
||||||
err := f.UpdateNginxConfigMapData(multiAccept, "false")
|
f.UpdateNginxConfigMapData(multiAccept, "false")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
f.WaitForNginxConfiguration(
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, expectedDirective)
|
return strings.Contains(cfg, expectedDirective)
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -43,32 +43,24 @@ var _ = framework.IngressNginxDescribe("No Auth locations", func() {
|
||||||
noAuthPath := "/noauth"
|
noAuthPath := "/noauth"
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
s, err := f.EnsureSecret(buildSecret(username, password, secretName, f.IngressController.Namespace))
|
s := f.EnsureSecret(buildSecret(username, password, secretName, f.IngressController.Namespace))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(s).NotTo(BeNil())
|
|
||||||
Expect(s.ObjectMeta).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.UpdateNginxConfigMapData(setting, noAuthPath)
|
f.UpdateNginxConfigMapData(setting, noAuthPath)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
bi := buildBasicAuthIngressWithSecondPath(host, f.IngressController.Namespace, s.Name, noAuthPath)
|
bi := buildBasicAuthIngressWithSecondPath(host, f.IngressController.Namespace, s.Name, noAuthPath)
|
||||||
ing, err := f.EnsureIngress(bi)
|
f.EnsureIngress(bi)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should return status code 401 when accessing '/' unauthentication", func() {
|
It("should return status code 401 when accessing '/' unauthentication", func() {
|
||||||
err := f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("test auth"))
|
return Expect(server).Should(ContainSubstring("test auth"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, body, errs := gorequest.New().
|
resp, body, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -81,11 +73,10 @@ var _ = framework.IngressNginxDescribe("No Auth locations", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should return status code 200 when accessing '/' authentication", func() {
|
It("should return status code 200 when accessing '/' authentication", func() {
|
||||||
err := f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("test auth"))
|
return Expect(server).Should(ContainSubstring("test auth"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPURL).
|
Get(f.IngressController.HTTPURL).
|
||||||
|
@ -98,11 +89,10 @@ var _ = framework.IngressNginxDescribe("No Auth locations", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should return status code 200 when accessing '/noauth' unauthenticated", func() {
|
It("should return status code 200 when accessing '/noauth' unauthenticated", func() {
|
||||||
err := f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return Expect(server).Should(ContainSubstring("test auth"))
|
return Expect(server).Should(ContainSubstring("test auth"))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(fmt.Sprintf("%s/noauth", f.IngressController.HTTPURL)).
|
Get(fmt.Sprintf("%s/noauth", f.IngressController.HTTPURL)).
|
||||||
|
@ -156,8 +146,9 @@ func buildBasicAuthIngressWithSecondPath(host, namespace, secretName, pathName s
|
||||||
|
|
||||||
func buildSecret(username, password, name, namespace string) *corev1.Secret {
|
func buildSecret(username, password, name, namespace string) *corev1.Secret {
|
||||||
out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput()
|
out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput()
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "creating password")
|
||||||
|
|
||||||
encpass := fmt.Sprintf("%v:%s\n", username, out)
|
encpass := fmt.Sprintf("%v:%s\n", username, out)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
return &corev1.Secret{
|
return &corev1.Secret{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
|
|
@ -35,11 +35,8 @@ var _ = framework.IngressNginxDescribe("Proxy Protocol", func() {
|
||||||
setting := "use-proxy-protocol"
|
setting := "use-proxy-protocol"
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.UpdateNginxConfigMapData(setting, "false")
|
||||||
|
|
||||||
err = f.UpdateNginxConfigMapData(setting, "false")
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -48,27 +45,22 @@ var _ = framework.IngressNginxDescribe("Proxy Protocol", func() {
|
||||||
It("should respect port passed by the PROXY Protocol", func() {
|
It("should respect port passed by the PROXY Protocol", func() {
|
||||||
host := "proxy-protocol"
|
host := "proxy-protocol"
|
||||||
|
|
||||||
err := f.UpdateNginxConfigMapData(setting, "true")
|
f.UpdateNginxConfigMapData(setting, "true")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "server_name proxy-protocol") &&
|
return strings.Contains(server, "server_name proxy-protocol") &&
|
||||||
strings.Contains(server, "listen 80 proxy_protocol")
|
strings.Contains(server, "listen 80 proxy_protocol")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
ip, err := f.GetNginxIP()
|
ip := f.GetNginxIP()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
port, err := f.GetNginxPort("http")
|
port, err := f.GetNginxPort("http")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred(), "unexpected error obtaning NGINX Port")
|
||||||
|
|
||||||
conn, err := net.Dial("tcp", net.JoinHostPort(ip, strconv.Itoa(port)))
|
conn, err := net.Dial("tcp", net.JoinHostPort(ip, strconv.Itoa(port)))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred(), "unexpected error creating connection to %s:%d", ip, port)
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
header := "PROXY TCP4 192.168.0.1 192.168.0.11 56324 1234\r\n"
|
header := "PROXY TCP4 192.168.0.1 192.168.0.11 56324 1234\r\n"
|
||||||
|
@ -76,7 +68,7 @@ var _ = framework.IngressNginxDescribe("Proxy Protocol", func() {
|
||||||
conn.Write([]byte("GET / HTTP/1.1\r\nHost: proxy-protocol\r\n\r\n"))
|
conn.Write([]byte("GET / HTTP/1.1\r\nHost: proxy-protocol\r\n\r\n"))
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(conn)
|
data, err := ioutil.ReadAll(conn)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred(), "unexpected error reading connection data")
|
||||||
body := string(data)
|
body := string(data)
|
||||||
Expect(body).Should(ContainSubstring(fmt.Sprintf("host=%v", "proxy-protocol")))
|
Expect(body).Should(ContainSubstring(fmt.Sprintf("host=%v", "proxy-protocol")))
|
||||||
Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-port=80")))
|
Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-port=80")))
|
||||||
|
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
|
|
||||||
"k8s.io/api/extensions/v1beta1"
|
"k8s.io/api/extensions/v1beta1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
@ -33,34 +32,28 @@ var _ = framework.IngressNginxDescribe("Server Tokens", func() {
|
||||||
serverTokens := "server-tokens"
|
serverTokens := "server-tokens"
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should not exists Server header in the response", func() {
|
It("should not exists Server header in the response", func() {
|
||||||
err := f.UpdateNginxConfigMapData(serverTokens, "false")
|
f.UpdateNginxConfigMapData(serverTokens, "false")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngress(serverTokens, "/", serverTokens, f.IngressController.Namespace, "http-svc", 80, nil))
|
f.EnsureIngress(framework.NewSingleIngress(serverTokens, "/", serverTokens, f.IngressController.Namespace, "http-svc", 80, nil))
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
f.WaitForNginxConfiguration(
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, "server_tokens off") &&
|
return strings.Contains(cfg, "server_tokens off") &&
|
||||||
strings.Contains(cfg, "more_clear_headers Server;")
|
strings.Contains(cfg, "more_clear_headers Server;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should exists Server header in the response when is enabled", func() {
|
It("should exists Server header in the response when is enabled", func() {
|
||||||
err := f.UpdateNginxConfigMapData(serverTokens, "true")
|
f.UpdateNginxConfigMapData(serverTokens, "true")
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
ing, err := f.EnsureIngress(&v1beta1.Ingress{
|
f.EnsureIngress(&v1beta1.Ingress{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: serverTokens,
|
Name: serverTokens,
|
||||||
Namespace: f.IngressController.Namespace,
|
Namespace: f.IngressController.Namespace,
|
||||||
|
@ -88,13 +81,9 @@ var _ = framework.IngressNginxDescribe("Server Tokens", func() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
f.WaitForNginxConfiguration(
|
||||||
Expect(ing).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, "server_tokens on")
|
return strings.Contains(cfg, "server_tokens on")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -34,8 +34,7 @@ var _ = framework.IngressNginxDescribe("Settings - TLS)", func() {
|
||||||
host := "settings-tls"
|
host := "settings-tls"
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -52,19 +51,15 @@ var _ = framework.IngressNginxDescribe("Settings - TLS)", func() {
|
||||||
tlsConfig, err := tlsEndpoint(f, host)
|
tlsConfig, err := tlsEndpoint(f, host)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
err = framework.WaitForTLS(f.IngressController.HTTPSURL, tlsConfig)
|
framework.WaitForTLS(f.IngressController.HTTPSURL, tlsConfig)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("setting cipher suite")
|
By("setting cipher suite")
|
||||||
|
f.UpdateNginxConfigMapData(sslCiphers, testCiphers)
|
||||||
|
|
||||||
err = f.UpdateNginxConfigMapData(sslCiphers, testCiphers)
|
f.WaitForNginxConfiguration(
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, fmt.Sprintf("ssl_ciphers '%s';", testCiphers))
|
return strings.Contains(cfg, fmt.Sprintf("ssl_ciphers '%s';", testCiphers))
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPSURL).
|
Get(f.IngressController.HTTPSURL).
|
||||||
|
@ -78,15 +73,12 @@ var _ = framework.IngressNginxDescribe("Settings - TLS)", func() {
|
||||||
Expect(resp.TLS.CipherSuite).Should(BeNumerically("==", tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384))
|
Expect(resp.TLS.CipherSuite).Should(BeNumerically("==", tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384))
|
||||||
|
|
||||||
By("enforcing TLS v1.0")
|
By("enforcing TLS v1.0")
|
||||||
|
f.UpdateNginxConfigMapData(sslProtocols, "TLSv1")
|
||||||
|
|
||||||
err = f.UpdateNginxConfigMapData(sslProtocols, "TLSv1")
|
f.WaitForNginxConfiguration(
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxConfiguration(
|
|
||||||
func(cfg string) bool {
|
func(cfg string) bool {
|
||||||
return strings.Contains(cfg, "ssl_protocols TLSv1;")
|
return strings.Contains(cfg, "ssl_protocols TLSv1;")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs = gorequest.New().
|
resp, _, errs = gorequest.New().
|
||||||
Get(f.IngressController.HTTPSURL).
|
Get(f.IngressController.HTTPSURL).
|
||||||
|
@ -108,19 +100,15 @@ var _ = framework.IngressNginxDescribe("Settings - TLS)", func() {
|
||||||
tlsConfig, err := tlsEndpoint(f, host)
|
tlsConfig, err := tlsEndpoint(f, host)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
err = framework.WaitForTLS(f.IngressController.HTTPSURL, tlsConfig)
|
framework.WaitForTLS(f.IngressController.HTTPSURL, tlsConfig)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
By("setting max-age parameter")
|
By("setting max-age parameter")
|
||||||
|
f.UpdateNginxConfigMapData(hstsMaxAge, "86400")
|
||||||
|
|
||||||
err = f.UpdateNginxConfigMapData(hstsMaxAge, "86400")
|
f.WaitForNginxServer(host,
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "Strict-Transport-Security: max-age=86400; includeSubDomains\"")
|
return strings.Contains(server, "Strict-Transport-Security: max-age=86400; includeSubDomains\"")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
Get(f.IngressController.HTTPSURL).
|
Get(f.IngressController.HTTPSURL).
|
||||||
|
@ -133,15 +121,12 @@ var _ = framework.IngressNginxDescribe("Settings - TLS)", func() {
|
||||||
Expect(resp.Header.Get("Strict-Transport-Security")).Should(ContainSubstring("max-age=86400"))
|
Expect(resp.Header.Get("Strict-Transport-Security")).Should(ContainSubstring("max-age=86400"))
|
||||||
|
|
||||||
By("setting includeSubDomains parameter")
|
By("setting includeSubDomains parameter")
|
||||||
|
f.UpdateNginxConfigMapData(hstsIncludeSubdomains, "false")
|
||||||
|
|
||||||
err = f.UpdateNginxConfigMapData(hstsIncludeSubdomains, "false")
|
f.WaitForNginxServer(host,
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "Strict-Transport-Security: max-age=86400\"")
|
return strings.Contains(server, "Strict-Transport-Security: max-age=86400\"")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs = gorequest.New().
|
resp, _, errs = gorequest.New().
|
||||||
Get(f.IngressController.HTTPSURL).
|
Get(f.IngressController.HTTPSURL).
|
||||||
|
@ -154,15 +139,12 @@ var _ = framework.IngressNginxDescribe("Settings - TLS)", func() {
|
||||||
Expect(resp.Header.Get("Strict-Transport-Security")).ShouldNot(ContainSubstring("includeSubDomains"))
|
Expect(resp.Header.Get("Strict-Transport-Security")).ShouldNot(ContainSubstring("includeSubDomains"))
|
||||||
|
|
||||||
By("setting preload parameter")
|
By("setting preload parameter")
|
||||||
|
f.UpdateNginxConfigMapData(hstsPreload, "true")
|
||||||
|
|
||||||
err = f.UpdateNginxConfigMapData(hstsPreload, "true")
|
f.WaitForNginxServer(host,
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "Strict-Transport-Security: max-age=86400; preload\"")
|
return strings.Contains(server, "Strict-Transport-Security: max-age=86400; preload\"")
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
resp, _, errs = gorequest.New().
|
resp, _, errs = gorequest.New().
|
||||||
Get(f.IngressController.HTTPSURL).
|
Get(f.IngressController.HTTPSURL).
|
||||||
|
@ -177,11 +159,7 @@ var _ = framework.IngressNginxDescribe("Settings - TLS)", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
func tlsEndpoint(f *framework.Framework, host string) (*tls.Config, error) {
|
func tlsEndpoint(f *framework.Framework, host string) (*tls.Config, error) {
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return framework.CreateIngressTLSSecret(f.KubeClientSet,
|
return framework.CreateIngressTLSSecret(f.KubeClientSet,
|
||||||
ing.Spec.TLS[0].Hosts,
|
ing.Spec.TLS[0].Hosts,
|
||||||
ing.Spec.TLS[0].SecretName,
|
ing.Spec.TLS[0].SecretName,
|
||||||
|
|
|
@ -33,8 +33,7 @@ var _ = framework.IngressNginxDescribe("SSL", func() {
|
||||||
f := framework.NewDefaultFramework("ssl")
|
f := framework.NewDefaultFramework("ssl")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
err := f.NewEchoDeployment()
|
f.NewEchoDeployment()
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
})
|
||||||
|
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
|
@ -43,7 +42,7 @@ var _ = framework.IngressNginxDescribe("SSL", func() {
|
||||||
It("should not appear references to secret updates not used in ingress rules", func() {
|
It("should not appear references to secret updates not used in ingress rules", func() {
|
||||||
host := "ssl-update"
|
host := "ssl-update"
|
||||||
|
|
||||||
dummySecret, err := f.EnsureSecret(&v1.Secret{
|
dummySecret := f.EnsureSecret(&v1.Secret{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "dummy",
|
Name: "dummy",
|
||||||
Namespace: f.IngressController.Namespace,
|
Namespace: f.IngressController.Namespace,
|
||||||
|
@ -52,24 +51,20 @@ var _ = framework.IngressNginxDescribe("SSL", func() {
|
||||||
"key": []byte("value"),
|
"key": []byte("value"),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
ing, err := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
ing := f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(ing).ToNot(BeNil())
|
|
||||||
|
|
||||||
_, err = framework.CreateIngressTLSSecret(f.KubeClientSet,
|
_, err := framework.CreateIngressTLSSecret(f.KubeClientSet,
|
||||||
ing.Spec.TLS[0].Hosts,
|
ing.Spec.TLS[0].Hosts,
|
||||||
ing.Spec.TLS[0].SecretName,
|
ing.Spec.TLS[0].SecretName,
|
||||||
ing.Namespace)
|
ing.Namespace)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
err = f.WaitForNginxServer(host,
|
f.WaitForNginxServer(host,
|
||||||
func(server string) bool {
|
func(server string) bool {
|
||||||
return strings.Contains(server, "server_name ssl-update") &&
|
return strings.Contains(server, "server_name ssl-update") &&
|
||||||
strings.Contains(server, "listen 443")
|
strings.Contains(server, "listen 443")
|
||||||
})
|
})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
|
|
||||||
log, err := f.NginxLogs()
|
log, err := f.NginxLogs()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
141
test/e2e/status/update.go
Normal file
141
test/e2e/status/update.go
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||||
|
apiv1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
|
||||||
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = framework.IngressNginxDescribe("Status Update [Status]", func() {
|
||||||
|
f := framework.NewDefaultFramework("status-update")
|
||||||
|
host := "status-update"
|
||||||
|
address := getHostIP()
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should update status field after client-go reconnection", func() {
|
||||||
|
port, cmd, err := f.KubectlProxy(0)
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error starting kubectl proxy")
|
||||||
|
|
||||||
|
err = framework.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, fmt.Sprintf("--apiserver-host=http://%s:%d", address.String(), port))
|
||||||
|
args = append(args, "--publish-status-address=1.1.0.0")
|
||||||
|
// flags --publish-service and --publish-status-address are mutually exclusive
|
||||||
|
var index int
|
||||||
|
for k, v := range args {
|
||||||
|
if strings.Index(v, "--publish-service") != -1 {
|
||||||
|
index = k
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if index > -1 {
|
||||||
|
args[index] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
deployment.Spec.Template.Spec.Containers[0].Args = args
|
||||||
|
_, err := f.KubeClientSet.AppsV1beta1().Deployments(f.IngressController.Namespace).Update(deployment)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error updating ingress controller deployment flags")
|
||||||
|
|
||||||
|
f.NewEchoDeploymentWithReplicas(1)
|
||||||
|
|
||||||
|
ing := f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil))
|
||||||
|
|
||||||
|
f.WaitForNginxConfiguration(
|
||||||
|
func(cfg string) bool {
|
||||||
|
return strings.Contains(cfg, fmt.Sprintf("server_name %s", host))
|
||||||
|
})
|
||||||
|
|
||||||
|
framework.Logf("waiting for leader election and initial status update")
|
||||||
|
time.Sleep(30 * time.Second)
|
||||||
|
|
||||||
|
err = cmd.Process.Kill()
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error terminating kubectl proxy")
|
||||||
|
|
||||||
|
ing, err = f.KubeClientSet.Extensions().Ingresses(f.IngressController.Namespace).Get(host, metav1.GetOptions{})
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error getting %s/%v Ingress", f.IngressController.Namespace, host)
|
||||||
|
|
||||||
|
ing.Status.LoadBalancer.Ingress = []apiv1.LoadBalancerIngress{}
|
||||||
|
_, err = f.KubeClientSet.Extensions().Ingresses(f.IngressController.Namespace).UpdateStatus(ing)
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error cleaning Ingress status")
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
|
err = f.KubeClientSet.CoreV1().
|
||||||
|
ConfigMaps(f.IngressController.Namespace).
|
||||||
|
Delete("ingress-controller-leader-nginx", &metav1.DeleteOptions{})
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error deleting leader election configmap")
|
||||||
|
|
||||||
|
_, cmd, err = f.KubectlProxy(port)
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error starting kubectl proxy")
|
||||||
|
defer func() {
|
||||||
|
if cmd != nil {
|
||||||
|
err := cmd.Process.Kill()
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error terminating kubectl proxy")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = wait.Poll(10*time.Second, time.Minute*3, func() (done bool, err error) {
|
||||||
|
ing, err = f.KubeClientSet.Extensions().Ingresses(f.IngressController.Namespace).Get(host, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ing.Status.LoadBalancer.Ingress) != 1 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred(), "unexpected error waiting for ingress status")
|
||||||
|
Expect(ing.Status.LoadBalancer.Ingress).Should(Equal([]apiv1.LoadBalancerIngress{
|
||||||
|
{IP: "1.1.0.0"},
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
func getHostIP() net.IP {
|
||||||
|
conn, err := net.Dial("udp", "8.8.8.8:80")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
localAddr := conn.LocalAddr().(*net.UDPAddr)
|
||||||
|
|
||||||
|
return localAddr.IP
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ if test -e kubectl; then
|
||||||
echo "skipping download of kubectl"
|
echo "skipping download of kubectl"
|
||||||
else
|
else
|
||||||
echo "downloading kubectl..."
|
echo "downloading kubectl..."
|
||||||
curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.11.0/bin/linux/amd64/kubectl && \
|
curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kubectl && \
|
||||||
chmod +x kubectl && sudo mv kubectl /usr/local/bin/
|
chmod +x kubectl && sudo mv kubectl /usr/local/bin/
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -31,6 +31,9 @@ touch ${HOME}/.kube/config
|
||||||
export KUBECONFIG=${HOME}/.kube/config
|
export KUBECONFIG=${HOME}/.kube/config
|
||||||
|
|
||||||
echo "starting Kubernetes cluster..."
|
echo "starting Kubernetes cluster..."
|
||||||
|
curl -Lo $DIR/dind-cluster-v1.11.sh https://raw.githubusercontent.com/kubernetes-sigs/kubeadm-dind-cluster/master/fixed/dind-cluster-v1.11.sh && \
|
||||||
|
chmod +x $DIR/dind-cluster-v1.11.sh
|
||||||
|
|
||||||
$DIR/dind-cluster-v1.11.sh up
|
$DIR/dind-cluster-v1.11.sh up
|
||||||
|
|
||||||
kubectl config use-context dind
|
kubectl config use-context dind
|
||||||
|
|
Loading…
Reference in a new issue