diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 9f8fd83ba..469e00834 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -10,7 +10,8 @@ assignees: '' +**What happened**: + + + +**What you expected to happen**: + + + + **NGINX Ingress controller version** (exec into the pod and run nginx-ingress-controller --version.): - -**What you expected to happen**: - - - -**How to reproduce it**: +**How to reproduce this issue**: ## Quick start @@ -51,7 +51,7 @@ It will install the controller in the `ingress-nginx` namespace, creating that n **If you don't have Helm** or if you prefer to use a YAML manifest, you can run the following command instead: ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml ``` !!! info @@ -93,7 +93,7 @@ Then create an ingress resource. The following example uses an host that maps to ```console kubectl create ingress demo-localhost --class=nginx \ - --rule=demo.localdev.me/*=demo:80 + --rule="demo.localdev.me/*=demo:80" ``` Now, forward a local port to the ingress controller: @@ -186,17 +186,17 @@ In AWS we use a Network load balancer (NLB) to expose the NGINX Ingress controll ##### Network Load Balancer (NLB) ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/aws/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/aws/deploy.yaml ``` ##### TLS termination in AWS Load Balancer (NLB) By default, TLS is terminated in the ingress controller. But it is also possible to terminate TLS in the Load Balancer. This section explains how to do that on AWS using an NLB. -1. Download the [deploy.yaml](https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml) template +1. Download the [deploy.yaml](https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml) template ```console - wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml + wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml ``` 2. Edit the file and change the VPC CIDR in use for the Kubernetes cluster: @@ -218,7 +218,7 @@ By default, TLS is terminated in the ingress controller. But it is also possible Idle timeout value for TCP flows is 350 seconds and [cannot be modified](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#connection-idle-timeout). -For this reason, you need to ensure the [keepalive_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout) value is configured less than 350 seconds to work as expected. +For this reason, you need to ensure the [keepalive_timeout](https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout) value is configured less than 350 seconds to work as expected. By default NGINX `keepalive_timeout` is set to `75s`. @@ -238,7 +238,7 @@ Then, the ingress controller can be installed like this: ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/cloud/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml ``` !!! warning @@ -252,7 +252,7 @@ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/cont #### Azure ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/cloud/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml ``` More information with regards to Azure annotations for ingress controller can be found in the [official AKS documentation](https://docs.microsoft.com/en-us/azure/aks/ingress-internal-ip#create-an-ingress-controller). @@ -260,13 +260,13 @@ More information with regards to Azure annotations for ingress controller can be #### Digital Ocean ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/do/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/do/deploy.yaml ``` #### Scaleway ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/scw/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/scw/deploy.yaml ``` #### Exoscale @@ -280,7 +280,7 @@ The full list of annotations supported by Exoscale is available in the Exoscale #### Oracle Cloud Infrastructure ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/cloud/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml ``` A [complete list of available annotations for Oracle Cloud Infrastructure](https://github.com/oracle/oci-cloud-controller-manager/blob/master/docs/load-balancer-annotations.md) can be found in the [OCI Cloud Controller Manager](https://github.com/oracle/oci-cloud-controller-manager) documentation. @@ -292,7 +292,7 @@ This section is applicable to Kubernetes clusters deployed on bare metal servers For quick testing, you can use a [NodePort](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport). This should work on almost every cluster, but it will typically use a port in the range 30000-32767. ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/baremetal/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/baremetal/deploy.yaml ``` For more information about bare metal deployments (and how to use port 80 instead of a random port in the 30000-32767 range), see [bare-metal considerations](./baremetal.md). @@ -325,7 +325,7 @@ See also [“How to easily install multiple instances of the Ingress NGINX contr !!! attention The first time the ingress controller starts, two [Jobs](https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/) create the SSL Certificate used by the admission webhook. -THis can cause an initial delay of up to two minutes until it is possible to create and validate Ingress definitions. +This can cause an initial delay of up to two minutes until it is possible to create and validate Ingress definitions. You can wait until it is ready to run the next command: diff --git a/docs/deploy/upgrade.md b/docs/deploy/upgrade.md index 3b29a689b..e16992612 100644 --- a/docs/deploy/upgrade.md +++ b/docs/deploy/upgrade.md @@ -24,7 +24,7 @@ spec: spec: containers: - name: ingress-nginx-controller - image: k8s.gcr.io/ingress-nginx/controller:v1.0.4@sha256:545cff00370f28363dad31e3b59a94ba377854d3a11f18988f5f9e56841ef9ef + image: registry.k8s.io/ingress-nginx/controller:v1.0.4@sha256:545cff00370f28363dad31e3b59a94ba377854d3a11f18988f5f9e56841ef9ef args: ... ``` @@ -33,7 +33,7 @@ The easiest way to do this is e.g. (do note you may need to change the name para ``` kubectl set image deployment/ingress-nginx-controller \ - controller=k8s.gcr.io/ingress-nginx/controller:v1.0.5@sha256:55a1fcda5b7657c372515fe402c3e39ad93aa59f6e4378e82acd99912fe6028d \ + controller=registry.k8s.io/ingress-nginx/controller:v1.0.5@sha256:55a1fcda5b7657c372515fe402c3e39ad93aa59f6e4378e82acd99912fe6028d \ -n ingress-nginx ``` diff --git a/docs/developer-guide/code-overview.md b/docs/developer-guide/code-overview.md index 6f4beb9c9..7531daf92 100644 --- a/docs/developer-guide/code-overview.md +++ b/docs/developer-guide/code-overview.md @@ -101,6 +101,12 @@ The e2e tests code is in [test](https://github.com/kubernetes/ingress-nginx/tree Describe here `kubectl plugin`, `dbg`, `waitshutdown` and cover the hack scripts. +### kubectl plugin + +It containes kubectl plugin for inspecting your ingress-nginx deployments. +This part of code can be found in [cmd/plugin](https://github.com/kubernetes/ingress-nginx/tree/main/cmd/plugin) directory +Detail functions flow and available flow can be found in [kubectl-plugin](https://github.com/kubernetes/ingress-nginx/blob/main/docs/kubectl-plugin.md) + ## Deploy files This directory contains the `yaml` deploy files used as examples or references in the docs to deploy Ingress NGINX and other components. @@ -140,7 +146,7 @@ This is NGINX with some Lua enhancement. We do dynamic certificate, endpoints ha The files are in [rootfs](https://github.com/kubernetes/ingress-nginx/tree/main/rootfs) directory and contains: * The Dockerfile -* [Auxiliary scripts](https://github.com/kubernetes/ingress-nginx/tree/main/rootfs/ingress-controller) +* [nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/rootfs/etc/nginx) #### Ingress NGINX Lua Scripts diff --git a/docs/e2e-tests.md b/docs/e2e-tests.md index 29ef07161..d5aa6cc16 100644 --- a/docs/e2e-tests.md +++ b/docs/e2e-tests.md @@ -1,405 +1,36 @@ - + # e2e test suite for [Ingress NGINX Controller](https://github.com/kubernetes/ingress-nginx/tree/main/) -### [[Default Backend] change default settings](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/with_hosts.go#L31) - -- [should apply the annotation to the default backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/with_hosts.go#L39) - -### [[Default Backend]](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/default_backend.go#L29) - -- [should return 404 sending requests when only a default backend is running](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/default_backend.go#L32) -- [enables access logging for default backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/default_backend.go#L89) -- [disables access logging for default backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/default_backend.go#L106) - -### [[Default Backend] custom service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/custom_default_backend.go#L33) - -- [uses custom default backend that returns 200 as status code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/custom_default_backend.go#L36) - -### [[Default Backend] SSL](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/ssl.go#L26) - -- [should return a self generated SSL certificate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/ssl.go#L29) - -### [[TCP] tcp-services](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/tcpudp/tcp.go#L37) - -- [should expose a TCP service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/tcpudp/tcp.go#L40) -- [should expose an ExternalName TCP service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/tcpudp/tcp.go#L98) - -### [auth-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L39) - -- [should return status code 200 when no authentication is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L46) -- [should return status code 503 when authentication is configured with an invalid secret](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L65) -- [should return status code 401 when authentication is configured but Authorization header is not configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L89) -- [should return status code 401 when authentication is configured and Authorization header is sent with invalid credentials](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L116) -- [should return status code 200 when authentication is configured and Authorization header is sent](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L144) -- [should return status code 200 when authentication is configured with a map and Authorization header is sent](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L171) -- [should return status code 401 when authentication is configured with invalid content and Authorization header is sent](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L199) -- [proxy_set_header My-Custom-Header 42;](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L238) -- [proxy_set_header My-Custom-Header 42;](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L256) -- [proxy_set_header 'My-Custom-Header' '42';](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L273) -- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L294) -- [retains cookie set by external authentication server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L316) -- [should return status code 200 when signed in](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L413) -- [should redirect to signin url when not signed in](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L422) -- [keeps processing new ingresses even if one of the existing ingresses is misconfigured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L433) -- [should return status code 200 when signed in](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L490) -- [should redirect to signin url when not signed in](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L499) -- [keeps processing new ingresses even if one of the existing ingresses is misconfigured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L510) -- [should return status code 200 when signed in after auth backend is deleted ](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L584) -- [should deny login for different location on same server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L604) -- [should deny login for different servers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L632) -- [should redirect to signin url when not signed in](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L661) - -### [affinitymode](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinitymode.go#L31) - -- [Balanced affinity mode should balance](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinitymode.go#L34) -- [Check persistent affinity mode](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinitymode.go#L64) - -### [proxy-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L28) - -- [should set proxy_redirect to off](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L36) -- [should set proxy_redirect to default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L52) -- [should set proxy_redirect to hello.com goodbye.com](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L68) -- [should set proxy client-max-body-size to 8m](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L85) -- [should not set proxy client-max-body-size to incorrect value](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L100) -- [should set valid proxy timeouts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L115) -- [should not set invalid proxy timeouts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L136) -- [should turn on proxy-buffering](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L157) -- [should turn off proxy-request-buffering](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L179) -- [should build proxy next upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L194) -- [should setup proxy cookies](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L215) -- [should change the default proxy HTTP version](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L233) - -### [affinity session-cookie-name](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L35) - -- [should set sticky cookie SERVERID](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L42) -- [should change cookie name on ingress definition change](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L64) -- [should set the path to /something on the generated cookie](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L99) -- [does not set the path to / on the generated cookie if there's more than one rule referring to the same backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L121) -- [should set cookie with expires](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L182) -- [should work with use-regex annotation and session-cookie-path](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L213) -- [should warn user when use-regex is true and session-cookie-path is not set](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L237) -- [should not set affinity across all server locations when using separate ingresses](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L263) -- [should set sticky cookie without host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L295) -- [should work with server-alias annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L315) - -### [mirror-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/mirror.go#L28) - -- [should set mirror-target to http://localhost/mirror](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/mirror.go#L36) -- [should set mirror-target to https://test.env.com/$request_uri](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/mirror.go#L51) -- [should disable mirror-request-body](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/mirror.go#L67) - -### [canary-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L35) - -- [should response with a 200 status from the mainline upstream when requests are made to the mainline ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L47) -- [should return 404 status for requests to the canary if no matching ingress is found](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L79) -- [should return the correct status codes when endpoints are unavailable](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L106) -- [should route requests to the correct upstream if mainline ingress is created before the canary ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L160) -- [should route requests to the correct upstream if mainline ingress is created after the canary ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L205) -- [should route requests to the correct upstream if the mainline ingress is modified](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L249) -- [should route requests to the correct upstream if the canary ingress is modified](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L306) -- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L361) -- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L415) -- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L479) -- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L521) -- [should routes to mainline upstream when the given Regex causes error](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L555) -- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L593) -- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L632) -- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L687) -- [should not use canary as a catch-all server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L743) -- [should not use canary with domain as a server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L771) -- [does not crash when canary ingress has multiple paths to the same non-matching backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L795) - -### [limit-rate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/limitrate.go#L29) - -- [Check limit-rate annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/limitrate.go#L37) - -### [force-ssl-redirect](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/forcesslredirect.go#L27) - -- [should redirect to https](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/forcesslredirect.go#L34) - -### [http2-push-preload](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/http2pushpreload.go#L27) - -- [enable the http2-push-preload directive](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/http2pushpreload.go#L34) - -### [proxy-ssl-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L30) - -- [should set valid proxy-ssl-secret](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L37) -- [should set valid proxy-ssl-secret, proxy-ssl-verify to on, proxy-ssl-verify-depth to 2, and proxy-ssl-server-name to on](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L64) -- [should set valid proxy-ssl-secret, proxy-ssl-ciphers to HIGH:!AES](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L94) -- [should set valid proxy-ssl-secret, proxy-ssl-protocols](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L122) -- [proxy-ssl-location-only flag should change the nginx config server part](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L150) - -### [modsecurity owasp](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity.go#L27) - -- [should enable modsecurity](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity.go#L34) -- [should enable modsecurity with transaction ID and OWASP rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity.go#L52) -- [should disable modsecurity](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity.go#L73) -- [should enable modsecurity with snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity.go#L90) -- [should enable modsecurity without using 'modsecurity on;'](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity.go#L109) -- [should disable modsecurity using 'modsecurity off;'](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity.go#L131) -- [should enable modsecurity with snippet and block requests](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity.go#L152) -- [should enable modsecurity globally and with modsecurity-snippet block requests](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity.go#L186) - -### [backend-protocol - GRPC](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/grpc.go#L38) - -- [should use grpc_pass in the configuration file](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/grpc.go#L41) -- [should return OK for service with backend protocol GRPC](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/grpc.go#L66) -- [should return OK for service with backend protocol GRPCS](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/grpc.go#L124) - -### [cors-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L28) - -- [should enable cors](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L35) -- [should set cors methods to only allow POST, GET](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L60) -- [should set cors max-age](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L76) -- [should disable cors allow credentials](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L92) -- [should allow origin for cors](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L108) -- [should allow headers for cors](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L124) -- [should expose headers for cors](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L140) - -### [influxdb-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/influxdb.go#L39) - -- [should send the request metric to the influxdb server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/influxdb.go#L48) - -### [Annotation - limit-connections](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/limitconnections.go#L31) - -- [should limit-connections](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/limitconnections.go#L38) - -### [client-body-buffer-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L28) - -- [should set client_body_buffer_size to 1000](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L35) -- [should set client_body_buffer_size to 1K](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L51) -- [should set client_body_buffer_size to 1k](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L67) -- [should set client_body_buffer_size to 1m](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L83) -- [should set client_body_buffer_size to 1M](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L99) -- [should not set client_body_buffer_size to invalid 1b](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L115) - -### [default-backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/default_backend.go#L29) - -- [should use a custom default backend as upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/default_backend.go#L37) - -### [connection-proxy-header](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/connection.go#L29) - -- [set connection header to keep-alive](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/connection.go#L36) - -### [upstream-vhost](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/upstreamvhost.go#L27) - -- [set host to upstreamvhost.bar.com](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/upstreamvhost.go#L34) - -### [custom-http-errors](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/customhttperrors.go#L34) - -- [configures Nginx correctly](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/customhttperrors.go#L41) - -### [disable-access-log disable-http-access-log disable-stream-access-log](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/disableaccesslog.go#L27) - -- [disable-access-log set access_log off](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/disableaccesslog.go#L34) -- [disable-http-access-log set access_log off](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/disableaccesslog.go#L46) - -### [server-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/serversnippet.go#L27) - -- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/serversnippet.go#L34) - -### [rewrite-target use-regex enable-rewrite-log](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L30) - -- [should write rewrite logs](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L37) -- [should use correct longest path match](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L66) -- [should use ~* location modifier if regex annotation is present](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L111) -- [should fail to use longest match for documented warning](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L158) -- [should allow for custom rewrite parameters](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L190) - -### [app-root](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/approot.go#L28) - -- [should redirect to /foo](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/approot.go#L35) - -### [whitelist-source-range](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/ipwhitelist.go#L26) - -- [should set valid ip whitelist range](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/ipwhitelist.go#L33) - -### [enable-access-log enable-rewrite-log](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/log.go#L27) - -- [set access_log off](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/log.go#L34) -- [set rewrite_log on](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/log.go#L49) - -### [x-forwarded-prefix](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/xforwardedprefix.go#L28) - -- [should set the X-Forwarded-Prefix to the annotation value](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/xforwardedprefix.go#L35) -- [should not add X-Forwarded-Prefix if the annotation value is empty](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/xforwardedprefix.go#L57) - -### [configuration-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/snippet.go#L27) - -- [ in all locations](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/snippet.go#L34) - -### [backend-protocol - FastCGI](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fastcgi.go#L31) - -- [should use fastcgi_pass in the configuration file](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fastcgi.go#L38) -- [should add fastcgi_index in the configuration file](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fastcgi.go#L55) -- [should add fastcgi_param in the configuration file](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fastcgi.go#L72) -- [should return OK for service with backend protocol FastCGI](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fastcgi.go#L105) - -### [from-to-www-redirect](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fromtowwwredirect.go#L31) - -- [should redirect from www HTTP to HTTP](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fromtowwwredirect.go#L38) -- [should redirect from www HTTPS to HTTPS](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fromtowwwredirect.go#L64) - -### [permanent-redirect permanent-redirect-code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/redirect.go#L30) - -- [should respond with a standard redirect code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/redirect.go#L33) -- [should respond with a custom redirect code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/redirect.go#L61) - -### [upstream-hash-by-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/upstreamhashby.go#L76) - -- [should connect to the same pod](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/upstreamhashby.go#L83) -- [should connect to the same subset of pods](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/upstreamhashby.go#L92) - -### [annotation-global-rate-limit](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/globalratelimit.go#L30) - -- [generates correct configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/globalratelimit.go#L38) - -### [backend-protocol](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L27) - -- [should set backend protocol to https:// and use proxy_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L34) -- [should set backend protocol to grpc:// and use grpc_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L49) -- [should set backend protocol to grpcs:// and use grpc_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L64) -- [should set backend protocol to '' and use fastcgi_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L79) -- [should set backend protocol to '' and use ajp_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L94) - -### [satisfy](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/satisfy.go#L35) - -- [should configure satisfy directive correctly](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/satisfy.go#L42) -- [should allow multiple auth with satisfy any](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/satisfy.go#L84) - -### [server-alias](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/alias.go#L29) - -- [should return status code 200 for host 'foo' and 404 for 'bar'](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/alias.go#L36) -- [should return status code 200 for host 'foo' and 'bar'](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/alias.go#L62) -- [should return status code 200 for hosts defined in two ingresses, different path with one alias](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/alias.go#L87) - -### [ssl-ciphers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/sslciphers.go#L27) - -- [should change ssl ciphers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/sslciphers.go#L34) - -### [auth-tls-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L30) - -- [should set valid auth-tls-secret](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L37) -- [should set valid auth-tls-secret, sslVerify to off, and sslVerifyDepth to 2](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L73) -- [should set valid auth-tls-secret, pass certificate to upstream, and error page](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L103) -- [should validate auth-tls-verify-client](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L153) - -### [[Status] status update](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/status/update.go#L38) - -- [should update status field after client-go reconnection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/status/update.go#L43) - -### [Debug CLI](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/dbg/main.go#L29) - -- [should list the backend servers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/dbg/main.go#L37) -- [should get information for a specific backend server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/dbg/main.go#L56) -- [should produce valid JSON for /dbg general](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/dbg/main.go#L85) - -### [[Memory Leak] Dynamic Certificates](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/leaks/lua_ssl.go#L35) - -- [should not leak memory from ingress SSL certificates or configuration updates](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/leaks/lua_ssl.go#L42) - -### [[Ingress] [PathType] mix Exact and Prefix paths](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_mixed.go#L30) - -- [should choose the correct location](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_mixed.go#L39) - -### [[Ingress] definition without host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/without_host.go#L32) - -- [should set ingress details variables for ingresses without a host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/without_host.go#L35) -- [should set ingress details variables for ingresses with host without IngressRuleValue, only Backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/without_host.go#L56) - -### [single ingress - multiple hosts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/multiple_rules.go#L31) - -- [should set the correct $service_name NGINX variable](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/multiple_rules.go#L39) - -### [[Ingress] [PathType] exact](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_exact.go#L30) - -- [should choose exact location for /exact](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_exact.go#L37) - -### [[Ingress] [PathType] prefix checks](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_prefix.go#L28) - -- [should return 404 when prefix /aaa does not match request /aaaccc](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_prefix.go#L35) - -### [[Security] request smuggling](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/security/request_smuggling.go#L32) - -- [should not return body content from error_page](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/security/request_smuggling.go#L39) - -### [[SSL] [Flag] default-ssl-certificate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L33) - -- [uses default ssl certificate for catch-all ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L64) -- [uses default ssl certificate for host based ingress when configured certificate does not match host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L80) - -### [enable-real-ip](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L30) - -- [trusts X-Forwarded-For header only when setting is true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L40) -- [should not trust X-Forwarded-For header when setting is false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L78) - -### [access-log](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L26) - -- [use the default configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L31) -- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L39) -- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L51) -- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L63) -- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L75) - -### [[Lua] lua-shared-dicts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/lua_shared_dicts.go#L26) - -- [configures lua shared dicts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/lua_shared_dicts.go#L29) - -### [server-tokens](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L30) - -- [should not exists Server header in the response](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L38) -- [should exists Server header in the response when is enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L50) - -### [use-proxy-protocol](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L36) - -- [should respect port passed by the PROXY Protocol](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L46) -- [should respect proto passed by the PROXY Protocol server port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L79) -- [should enable PROXY Protocol for HTTPS](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L112) -- [should enable PROXY Protocol for TCP](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L155) - -### [[Flag] custom HTTP and HTTPS ports](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L32) - -- [should set X-Forwarded-Port headers accordingly when listening on a non-default HTTP port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L48) -- [should set X-Forwarded-Port header to 443](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L70) -- [should set the X-Forwarded-Port header to 443](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L100) - -### [[Security] no-auth-locations](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L34) - -- [should return status code 401 when accessing '/' unauthentication](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L55) -- [should return status code 200 when accessing '/' authentication](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L69) -- [should return status code 200 when accessing '/noauth' unauthenticated](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L83) - -### [Dynamic $proxy_host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L28) - -- [should exist a proxy_host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L36) -- [should exist a proxy_host using the upstream-vhost annotation value](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L57) - -### [proxy-connect-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L28) - -- [should set valid proxy timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L36) -- [should not set invalid proxy timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L52) +### [Geoip2](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/geoip2.go#L37) + +- [should include geoip2 line in config when enabled and db file exists](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/geoip2.go#L46) +- [should only allow requests from specific countries](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/geoip2.go#L70) + +### [[Security] global-auth-url](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L34) + +- [should return status code 401 when request any protected service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L85) +- [should return status code 200 when request whitelisted (via no-auth-locations) service and 401 when request protected service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L102) +- [should return status code 200 when request whitelisted (via ingress annotation) service and 401 when request protected service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L126) +- [should still return status code 200 after auth backend is deleted using cache](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L155) +- [should proxy_method method when global-auth-method is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L197) +- [should add custom error page when global-auth-signin url is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L210) +- [should add auth headers when global-auth-response-headers is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L223) +- [should set request-redirect when global-auth-request-redirect is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L237) +- [should set snippet when global external auth is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L250) +- [user retains cookie by default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L326) +- [user does not retain cookie if upstream returns error status code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L337) +- [user with global-auth-always-set-cookie key in configmap retains cookie if upstream returns error status code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L348) ### [[Security] Pod Security Policies](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy.go#L40) - [should be running with a Pod Security Policy](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy.go#L43) -### [Geoip2](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/geoip2.go#L29) - -- [should only allow requests from specific countries](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/geoip2.go#L38) - -### [[Security] Pod Security Policies with volumes](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy_volumes.go#L36) - -- [should be running with a Pod Security Policy](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy_volumes.go#L39) - -### [enable-multi-accept](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L27) - -- [should be enabled by default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L31) -- [should be enabled when set to true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L39) -- [should be disabled when set to false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L49) - ### [log-format-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L28) - [should disable the log-format-escape-json by default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L40) @@ -408,93 +39,47 @@ - [log-format-escape-json enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L66) - [log-format-escape-json disabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L89) -### [[Flag] ingress-class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L39) +### [server-tokens](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L29) -- [should ignore Ingress with class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L91) -- [should ignore Ingress with no class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L143) -- [should delete Ingress when class is removed](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L177) -- [check scenarios for IngressClass and ingress.class annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L216) +- [should not exists Server header in the response](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L38) +- [should exists Server header in the response when is enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L50) + +### [proxy-connect-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L28) + +- [should set valid proxy timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L36) +- [should not set invalid proxy timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L52) ### [ssl-ciphers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ssl_ciphers.go#L28) - [Add ssl ciphers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ssl_ciphers.go#L31) -### [proxy-next-upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_next_upstream.go#L28) +### [use-proxy-protocol](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L36) -- [should build proxy next upstream using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_next_upstream.go#L36) - -### [[Security] global-auth-url](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L32) - -- [should return status code 401 when request any protected service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L83) -- [should return status code 200 when request whitelisted (via no-auth-locations) service and 401 when request protected service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L100) -- [should return status code 200 when request whitelisted (via ingress annotation) service and 401 when request protected service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L124) -- [should still return status code 200 after auth backend is deleted using cache ](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L153) -- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L195) -- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L208) -- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L221) -- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L235) -- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L248) - -### [[Security] block-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L28) - -- [should block CIDRs defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L38) -- [should block User-Agents defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L55) -- [should block Referers defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L88) +- [should respect port passed by the PROXY Protocol](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L46) +- [should respect proto passed by the PROXY Protocol server port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L79) +- [should enable PROXY Protocol for HTTPS](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L112) +- [should enable PROXY Protocol for TCP](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L155) ### [plugins](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/plugins.go#L28) - [should exist a x-hello-world header](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/plugins.go#L35) -### [Configmap - limit-rate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/limit_rate.go#L28) +### [configmap server-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_snippet.go#L28) -- [Check limit-rate config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/limit_rate.go#L36) +- [should add value of server-snippet setting to all ingress config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_snippet.go#L35) +- [should add global server-snippet and drop annotations per admin config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_snippet.go#L92) -### [Configure OpenTracing](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L47) +### [[Flag] disable-catch-all](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L33) -- [should not exists opentracing directive](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L57) -- [should exists opentracing directive when is enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L70) -- [should not exists opentracing_operation_name directive when is empty](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L84) -- [should exists opentracing_operation_name directive when is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L99) -- [should not exists opentracing_location_operation_name directive when is empty](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L114) -- [should exists opentracing_location_operation_name directive when is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L129) -- [should enable opentracing using zipkin](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L144) -- [should enable opentracing using jaeger](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L156) -- [should enable opentracing using jaeger with sampler host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L168) -- [should propagate the w3c header when configured with jaeger](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L181) -- [should enable opentracing using datadog](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L225) +- [should ignore catch all Ingress with backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L50) +- [should ignore catch all Ingress with backend and rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L69) +- [should delete Ingress updated to catch-all](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L81) +- [should allow Ingress with rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L123) -### [use-forwarded-headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L30) +### [enable-real-ip](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L30) -- [should trust X-Forwarded headers when setting is true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L40) -- [should not trust X-Forwarded headers when setting is false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L90) - -### [proxy-send-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L28) - -- [should set valid proxy send timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L36) -- [should not set invalid proxy send timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L52) - -### [Add no tls redirect locations](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_tls_redirect_locations.go#L28) - -- [Check no tls redirect locations config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_tls_redirect_locations.go#L31) - -### [settings-global-rate-limit](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/globalratelimit.go#L30) - -- [generates correct NGINX configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/globalratelimit.go#L38) - -### [add-headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L30) - -- [Add a custom header](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L40) -- [Add multiple custom headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L65) - -### [hash size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L27) - -- [should set server_names_hash_bucket_size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L40) -- [should set server_names_hash_max_size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L48) -- [should set proxy-headers-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L60) -- [should set proxy-headers-hash-max-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L68) -- [should set variables-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L80) -- [should set variables-hash-max-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L88) -- [should set vmap-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L100) +- [trusts X-Forwarded-For header only when setting is true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L40) +- [should not trust X-Forwarded-For header when setting is false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L78) ### [keep-alive keep-alive-requests](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/keep-alive.go#L28) @@ -504,16 +89,130 @@ - [should set keep alive connection timeout to upstream server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/keep-alive.go#L68) - [should set the request count to upstream server through one keep alive connection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/keep-alive.go#L77) -### [[Flag] disable-catch-all](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L34) +### [enable-multi-accept](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L27) -- [should ignore catch all Ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L51) -- [should delete Ingress updated to catch-all](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L70) -- [should allow Ingress with both a default backend and rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L108) +- [should be enabled by default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L31) +- [should be enabled when set to true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L39) +- [should be disabled when set to false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L49) + +### [[Flag] watch namespace selector](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/namespace_selector.go#L30) + +- [should ingore Ingress of namespace without label foo=bar and accept those of namespace with label foo=bar](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/namespace_selector.go#L70) + +### [[Flag] disable-service-external-name](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_service_external_name.go#L34) + +- [should ignore services of external-name type](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_service_external_name.go#L51) + +### [Configure OpenTracing](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L48) + +- [should not exists opentracing directive](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L58) +- [should exists opentracing directive when is enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L71) +- [should include opentracing_trust_incoming_span off directive when disabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L85) +- [should not exists opentracing_operation_name directive when is empty](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L100) +- [should exists opentracing_operation_name directive when is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L115) +- [should not exists opentracing_location_operation_name directive when is empty](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L130) +- [should exists opentracing_location_operation_name directive when is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L145) +- [should enable opentracing using zipkin](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L160) +- [should enable opentracing using jaeger](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L172) +- [should enable opentracing using jaeger with sampler host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L184) +- [should propagate the w3c header when configured with jaeger](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L197) +- [should enable opentracing using jaeger with an HTTP endpoint](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L228) +- [should enable opentracing using datadog](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L241) + +### [Configmap change](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/configmap_change.go#L29) + +- [should reload after an update in the configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/configmap_change.go#L36) + +### [Configmap - limit-rate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/limit_rate.go#L28) + +- [Check limit-rate config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/limit_rate.go#L36) + +### [access-log](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L26) + +- [use the default configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L31) +- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L41) +- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L53) +- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L66) +- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L79) + +### [global-options](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_options.go#L28) + +- [should have worker_rlimit_nofile option](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_options.go#L31) +- [should have worker_rlimit_nofile option and be independent on amount of worker processes](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_options.go#L38) + +### [[Flag] ingress-class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L39) + +- [should ignore Ingress with a different class annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L68) +- [should ignore Ingress with different controller class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L104) +- [should accept both Ingresses with default IngressClassName and IngressClass annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L132) +- [should ignore Ingress without IngressClass configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L164) +- [should delete Ingress when class is removed](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L192) +- [should serve Ingress when class is added](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L257) +- [should serve Ingress when class is updated between annotation and ingressClassName](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L323) +- [should ignore Ingress with no class and accept the correctly configured Ingresses](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L413) +- [should watch Ingress with no class and ignore ingress with a different class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L482) +- [should watch Ingress that uses the class name even if spec is different](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L539) +- [should watch Ingress with correct annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L631) +- [should ignore Ingress with only IngressClassName](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L652) + +### [reuse-port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L27) + +- [reuse port should be enabled by default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L38) +- [reuse port should be disabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L44) +- [reuse port should be enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L52) + +### [proxy-send-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L28) + +- [should set valid proxy send timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L36) +- [should not set invalid proxy send timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L52) + +### [[SSL] [Flag] default-ssl-certificate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L33) + +- [uses default ssl certificate for catch-all ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L64) +- [uses default ssl certificate for host based ingress when configured certificate does not match host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L80) + +### [brotli](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/brotli.go#L30) + +- [ condition](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/brotli.go#L39) + +### [[Security] Pod Security Policies with volumes](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy_volumes.go#L36) + +- [should be running with a Pod Security Policy](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy_volumes.go#L39) + +### [Dynamic $proxy_host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L28) + +- [should exist a proxy_host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L36) +- [should exist a proxy_host using the upstream-vhost annotation value](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L57) + +### [[Security] block-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L28) + +- [should block CIDRs defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L38) +- [should block User-Agents defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L55) +- [should block Referers defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L88) + +### [settings-global-rate-limit](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/globalratelimit.go#L30) + +- [generates correct NGINX configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/globalratelimit.go#L38) + +### [Add no tls redirect locations](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_tls_redirect_locations.go#L28) + +- [Check no tls redirect locations config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_tls_redirect_locations.go#L31) ### [main-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/main_snippet.go#L27) - [should add value of main-snippet setting to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/main_snippet.go#L31) +### [[Lua] lua-shared-dicts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/lua_shared_dicts.go#L26) + +- [configures lua shared dicts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/lua_shared_dicts.go#L29) + +### [Bad annotation values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L29) + +- [[BAD_ANNOTATIONS] should drop an ingress if there is an invalid character in some annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L36) +- [[BAD_ANNOTATIONS] should drop an ingress if there is a forbidden word in some annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L67) +- [[BAD_ANNOTATIONS] should allow an ingress if there is a default blocklist config in place](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L102) +- [[BAD_ANNOTATIONS] should drop an ingress if there is a custom blocklist config in place and allow others to pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L133) + ### [[SSL] TLS protocols, ciphers and headers)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L31) - [setting cipher suite](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L65) @@ -525,50 +224,96 @@ - [should not use ports during the HTTP to HTTPS redirection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L209) - [should not use ports or X-Forwarded-Host during the HTTP to HTTPS redirection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L227) -### [Configmap change](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/configmap_change.go#L29) +### [[Security] modsecurity-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/modsecurity/modsecurity_snippet.go#L27) -- [should reload after an update in the configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/configmap_change.go#L36) +- [should add value of modsecurity-snippet setting to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/modsecurity/modsecurity_snippet.go#L30) + +### [OCSP](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ocsp/ocsp.go#L42) + +- [should enable OCSP and contain stapling information in the connection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ocsp/ocsp.go#L49) + +### [configmap stream-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/stream_snippet.go#L34) + +- [should add value of stream-snippet via config map to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/stream_snippet.go#L41) ### [proxy-read-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_read_timeout.go#L28) - [should set valid proxy read timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_read_timeout.go#L36) - [should not set invalid proxy read timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_read_timeout.go#L52) -### [[Security] modsecurity-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/modsecurity_snippet.go#L27) +### [proxy-next-upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_next_upstream.go#L28) -- [should add value of modsecurity-snippet setting to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/modsecurity_snippet.go#L30) +- [should build proxy next upstream using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_next_upstream.go#L36) -### [OCSP](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ocsp/ocsp.go#L42) +### [hash size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L27) -- [should enable OCSP and contain stapling information in the connection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ocsp/ocsp.go#L49) +- [should set server_names_hash_bucket_size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L40) +- [should set server_names_hash_max_size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L48) +- [should set proxy-headers-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L60) +- [should set proxy-headers-hash-max-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L68) +- [should set variables-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L80) +- [should set variables-hash-max-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L88) +- [should set vmap-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L100) -### [reuse-port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L27) +### [[Security] no-auth-locations](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L33) -- [reuse port should be enabled by default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L38) -- [reuse port should be disabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L44) -- [reuse port should be enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L52) +- [should return status code 401 when accessing '/' unauthentication](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L54) +- [should return status code 200 when accessing '/' authentication](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L68) +- [should return status code 200 when accessing '/noauth' unauthenticated](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L82) -### [[Shutdown] Graceful shutdown with pending request](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/slow_requests.go#L28) +### [[Flag] custom HTTP and HTTPS ports](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L32) -- [should let slow requests finish before shutting down](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/slow_requests.go#L36) +- [should set X-Forwarded-Port headers accordingly when listening on a non-default HTTP port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L48) +- [should set X-Forwarded-Port header to 443](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L70) +- [should set the X-Forwarded-Port header to 443](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L100) -### [[Shutdown] ingress controller](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/shutdown.go#L33) +### [use-forwarded-headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L30) -- [should shutdown in less than 60 secons without pending connections](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/shutdown.go#L43) -- [should shutdown after waiting 60 seconds for pending connections to be closed](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/shutdown.go#L64) -- [should shutdown after waiting 150 seconds for pending connections to be closed](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/shutdown.go#L109) +- [should trust X-Forwarded headers when setting is true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L40) +- [should not trust X-Forwarded headers when setting is false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L92) -### [[Service] backend status code 503](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L32) +### [add-headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L30) -- [should return 503 when backend service does not exist](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L35) -- [should return 503 when all backend service endpoints are unavailable](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L53) +- [Add a custom header](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L40) +- [Add multiple custom headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L65) -### [[Service] Type ExternalName](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L37) +### [[Load Balancer] round-robin](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/round_robin.go#L31) -- [works with external name set to incomplete fqdn](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L40) -- [should return 200 for service type=ExternalName without a port defined](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L73) -- [should return 200 for service type=ExternalName with a port defined](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L107) -- [should return status 502 for service type=ExternalName with an invalid host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L148) -- [should return 200 for service type=ExternalName using a port name](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L179) -- [should return 200 for service type=ExternalName using FQDN with trailing dot](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L221) -- [should update the external name after a service update](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L252) +- [should evenly distribute requests with round-robin (default algorithm)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/round_robin.go#L39) + +### [[Load Balancer] EWMA](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/ewma.go#L31) + +- [does not fail requests](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/ewma.go#L42) + +### [[Load Balancer] load-balance](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/configmap.go#L28) + +- [should apply the configmap load-balance setting](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/configmap.go#L35) + +### [[SSL] redirect to HTTPS](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ssl/http_redirect.go#L29) + +- [should redirect from HTTP to HTTPS when secret is missing](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ssl/http_redirect.go#L36) + +### [[SSL] secret update](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ssl/secret_update.go#L33) + +- [should not appear references to secret updates not used in ingress rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ssl/secret_update.go#L40) +- [should return the fake SSL certificate if the secret is invalid](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ssl/secret_update.go#L82) + +### [[Service] Type ExternalName](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L58) + +- [works with external name set to incomplete fqdn](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L61) +- [should return 200 for service type=ExternalName without a port defined](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L94) +- [should return 200 for service type=ExternalName with a port defined](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L128) +- [should return status 502 for service type=ExternalName with an invalid host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L152) +- [should return 200 for service type=ExternalName using a port name](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L183) +- [should return 200 for service type=ExternalName using FQDN with trailing dot](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L216) +- [should update the external name after a service update](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L247) +- [should sync ingress on external name service addition/deletion](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L310) + +### [[Service] Nil Service Backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_nil_backend.go#L31) + +- [should return 404 when backend service is nil](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_nil_backend.go#L38) + +### [[Service] backend status code 503](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L33) + +- [should return 503 when backend service does not exist](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L36) +- [should return 503 when all backend service endpoints are unavailable](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L54) diff --git a/docs/enhancements/20190815-zone-aware-routing.md b/docs/enhancements/20190815-zone-aware-routing.md index 357e8ad92..7000fb6fd 100644 --- a/docs/enhancements/20190815-zone-aware-routing.md +++ b/docs/enhancements/20190815-zone-aware-routing.md @@ -17,13 +17,15 @@ status: implementable ## Table of Contents -- [Summary](#summary) -- [Motivation](#motivation) - - [Goals](#goals) - - [Non-Goals](#non-goals) -- [Proposal](#proposal) -- [Implementation History](#implementation-history) -- [Drawbacks [optional]](#drawbacks-optional) +- [Availability zone aware routing](#availability-zone-aware-routing) + - [Table of Contents](#table-of-contents) + - [Summary](#summary) + - [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) + - [Proposal](#proposal) + - [Implementation History](#implementation-history) + - [Drawbacks [optional]](#drawbacks-optional) ## Summary @@ -39,7 +41,7 @@ inter-zone traffic and usually costs extra money. At the time of this writing, GCP charges $0.01 per GB of inter-zone egress traffic according to https://cloud.google.com/compute/network-pricing. -According to https://datapath.io/resources/blog/what-are-aws-data-transfer-costs-and-how-to-minimize-them/ Amazon also charges the same amount of money as GCP for cross-zone, egress traffic. +According to [https://datapath.io/resources/blog/what-are-aws-data-transfer-costs-and-how-to-minimize-them/](https://web.archive.org/web/20201008160149/https://datapath.io/resources/blog/what-are-aws-data-transfer-costs-and-how-to-minimize-them/) Amazon also charges the same amount of money as GCP for cross-zone, egress traffic. This can be a lot of money depending on once's traffic. By teaching ingress-nginx about zones we can eliminate or at least decrease this cost. diff --git a/docs/examples/chashsubset/deployment.yaml b/docs/examples/chashsubset/deployment.yaml index 0ac13fcce..7eb7613ba 100644 --- a/docs/examples/chashsubset/deployment.yaml +++ b/docs/examples/chashsubset/deployment.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: nginxhello - image: k8s.gcr.io/e2e-test-images/echoserver:2.3 + image: registry.k8s.io/e2e-test-images/echoserver:2.3 ports: - containerPort: 8080 env: diff --git a/docs/examples/customization/configuration-snippets/README.md b/docs/examples/customization/configuration-snippets/README.md index 5ef230ff1..33e7c4bf0 100644 --- a/docs/examples/customization/configuration-snippets/README.md +++ b/docs/examples/customization/configuration-snippets/README.md @@ -2,7 +2,7 @@ ## Ingress -The Ingress in [this example](ingress.yaml) adds a custom header to Nginx configuration that only applies to that specific Ingress. If you want to add headers that apply globally to all Ingresses, please have a look at [an example of specifying customer headers](../custom-headers/README.md). +The Ingress in [this example](ingress.yaml) adds a custom header to Nginx configuration that only applies to that specific Ingress. If you want to add headers that apply globally to all Ingresses, please have a look at [an example of specifying custom headers](../custom-headers/README.md). ```console kubectl apply -f ingress.yaml diff --git a/docs/examples/customization/custom-errors/custom-default-backend.helm.values.yaml b/docs/examples/customization/custom-errors/custom-default-backend.helm.values.yaml index fc00707ce..52ddb24a9 100644 --- a/docs/examples/customization/custom-errors/custom-default-backend.helm.values.yaml +++ b/docs/examples/customization/custom-errors/custom-default-backend.helm.values.yaml @@ -3,7 +3,7 @@ controller: defaultBackend: enabled: true image: - registry: k8s.gcr.io + registry: registry.k8s.io image: ingress-nginx/nginx-errors tag: "0.48.1" extraVolumes: diff --git a/docs/examples/customization/custom-errors/custom-default-backend.yaml b/docs/examples/customization/custom-errors/custom-default-backend.yaml index 4b40d36e7..fb4f899a0 100644 --- a/docs/examples/customization/custom-errors/custom-default-backend.yaml +++ b/docs/examples/customization/custom-errors/custom-default-backend.yaml @@ -36,7 +36,7 @@ spec: spec: containers: - name: nginx-error-server - image: k8s.gcr.io/ingress-nginx/nginx-errors:0.48.1 + image: registry.k8s.io/ingress-nginx/nginx-errors:0.49.0 ports: - containerPort: 8080 # Setting the environment variable DEBUG we can see the headers sent diff --git a/docs/examples/grpc/README.md b/docs/examples/grpc/README.md index 2d1929b66..cf4597fcd 100644 --- a/docs/examples/grpc/README.md +++ b/docs/examples/grpc/README.md @@ -86,7 +86,7 @@ This example demonstrates how to route traffic to a gRPC service through the Ing ### Step 3: Create the Kubernetes `Ingress` resource for the gRPC app -- Use the following example manifest of a ingress resource to create a ingress for your grpc app. If required, edit it to match your app's details like name, namespace, service, secret etc. Make sure you have the required SSL-Certificate, existing in your Kubernetes cluster in the same namespace where the gRPC app is. The certificate must be available as a kubernetes secret resource, of type "kubernete.io/tls" https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets. This is because we are terminating TLS on the ingress. +- Use the following example manifest of a ingress resource to create a ingress for your grpc app. If required, edit it to match your app's details like name, namespace, service, secret etc. Make sure you have the required SSL-Certificate, existing in your Kubernetes cluster in the same namespace where the gRPC app is. The certificate must be available as a kubernetes secret resource, of type "kubernetes.io/tls" https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets. This is because we are terminating TLS on the ingress. ``` cat < ingress-nginx-control - `--v=2` shows details using `diff` about the changes in the configuration in nginx - `--v=3` shows details about the service, Ingress rule, endpoint changes and it dumps the nginx configuration in JSON format -- `--v=5` configures NGINX in [debug mode](http://nginx.org/en/docs/debugging_log.html) +- `--v=5` configures NGINX in [debug mode](https://nginx.org/en/docs/debugging_log.html) ## Authentication to the Kubernetes API Server @@ -256,7 +256,7 @@ Note: The below is based on the nginx [documentation](https://docs.nginx.com/ngi ```console $ docker ps | grep ingress-nginx-controller CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - d9e1d243156a k8s.gcr.io/ingress-nginx/controller "/usr/bin/dumb-init …" 19 minutes ago Up 19 minutes k8s_ingress-nginx-controller_ingress-nginx-controller-67956bf89d-mqxzt_kube-system_079f31ec-aa37-11e8-ad39-080027a227db_0 + d9e1d243156a registry.k8s.io/ingress-nginx/controller "/usr/bin/dumb-init …" 19 minutes ago Up 19 minutes k8s_ingress-nginx-controller_ingress-nginx-controller-67956bf89d-mqxzt_kube-system_079f31ec-aa37-11e8-ad39-080027a227db_0 ``` 3. Exec into the container diff --git a/docs/user-guide/cli-arguments.md b/docs/user-guide/cli-arguments.md index b9cd0c564..ae7c5b3ba 100644 --- a/docs/user-guide/cli-arguments.md +++ b/docs/user-guide/cli-arguments.md @@ -12,6 +12,7 @@ They are set in the container spec of the `ingress-nginx-controller` Deployment | `--apiserver-host` | 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. | | `--certificate-authority` | Path to a cert file for the certificate authority. This certificate is used only when the flag --apiserver-host is specified. | | `--configmap` | Name of the ConfigMap containing custom global configurations for the controller. | +| `--deep-inspect` | Enables ingress object security deep inspector. (default true) | | `--default-backend-service` | 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. | | `--default-server-port` | Port to use for exposing the default server (catch-all). (default 8181) | | `--default-ssl-certificate` | Secret containing a SSL certificate to be used by the default HTTPS server (catch-all). Takes the form "namespace/name". | @@ -46,6 +47,7 @@ They are set in the container spec of the `ingress-nginx-controller` Deployment | `--publish-service` | Service fronting the Ingress controller. Takes the form "namespace/name". When used together with update-status, the controller mirrors the address of this service's endpoints to the load-balancer status of all Ingress objects it satisfies. | | `--publish-status-address` | Customized address (or addresses, separated by comma) to set as the load-balancer status of Ingress objects this controller satisfies. Requires the update-status parameter. | | `--report-node-internal-ip-address`| Set the load-balancer status of Ingress objects to internal Node addresses instead of external. Requires the update-status parameter. | +| `--report-status-classes` | If true, report status classes in metrics (2xx, 3xx, 4xx and 5xx) instead of full status codes. (default false) | | `--skip_headers` | If true, avoid header prefixes in the log messages | | `--skip_log_headers` | If true, avoid headers when opening log files | | `--ssl-passthrough-proxy-port` | Port to use internally for SSL Passthrough. (default 442) | diff --git a/docs/user-guide/fcgi-services.md b/docs/user-guide/fcgi-services.md index becb4819f..db4d9428b 100644 --- a/docs/user-guide/fcgi-services.md +++ b/docs/user-guide/fcgi-services.md @@ -93,13 +93,13 @@ To enable FastCGI, the `nginx.ingress.kubernetes.io/backend-protocol` annotation ### The `nginx.ingress.kubernetes.io/fastcgi-index` Annotation -To specify an index file, the `fastcgi-index` annotation value can optionally be set. In the example below, the value is set to `index.php`. This annotation corresponds to [the _NGINX_ `fastcgi_index` directive](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_index). +To specify an index file, the `fastcgi-index` annotation value can optionally be set. In the example below, the value is set to `index.php`. This annotation corresponds to [the _NGINX_ `fastcgi_index` directive](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_index). > `nginx.ingress.kubernetes.io/fastcgi-index: "index.php"` ### The `nginx.ingress.kubernetes.io/fastcgi-params-configmap` Annotation -To specify [_NGINX_ `fastcgi_param` directives](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param), the `fastcgi-params-configmap` annotation is used, which in turn must lead to a _ConfigMap_ object containing the _NGINX_ `fastcgi_param` directives as key/values. +To specify [_NGINX_ `fastcgi_param` directives](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param), the `fastcgi-params-configmap` annotation is used, which in turn must lead to a _ConfigMap_ object containing the _NGINX_ `fastcgi_param` directives as key/values. > `nginx.ingress.kubernetes.io/fastcgi-params-configmap: "example-configmap"` diff --git a/docs/user-guide/miscellaneous.md b/docs/user-guide/miscellaneous.md index a991d91b9..196ea17fc 100644 --- a/docs/user-guide/miscellaneous.md +++ b/docs/user-guide/miscellaneous.md @@ -36,7 +36,7 @@ A more adequate value to support websockets is a value higher than one hour (`36 ## Optimizing TLS Time To First Byte (TTTFB) -NGINX provides the configuration option [ssl_buffer_size](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size) to allow the optimization of the TLS record size. +NGINX provides the configuration option [ssl_buffer_size](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size) to allow the optimization of the TLS record size. This improves the [TLS Time To First Byte](https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/) (TTTFB). The default value in the Ingress controller is `4k` (NGINX default is `16k`). diff --git a/docs/user-guide/multiple-ingress.md b/docs/user-guide/multiple-ingress.md index 246e38b52..4825b8458 100644 --- a/docs/user-guide/multiple-ingress.md +++ b/docs/user-guide/multiple-ingress.md @@ -11,7 +11,7 @@ If all ingress controllers respect IngressClasses (e.g. multiple instances of in First, ensure the `--controller-class=` and `--ingress-class` are set to something different on each ingress controller: ```yaml -# ingress-nginx Deployment/Statfulset +# ingress-nginx Deployment/Statefulset spec: template: spec: diff --git a/docs/user-guide/nginx-configuration/annotations.md b/docs/user-guide/nginx-configuration/annotations.md index a0086abec..0c65bd0c8 100755 --- a/docs/user-guide/nginx-configuration/annotations.md +++ b/docs/user-guide/nginx-configuration/annotations.md @@ -28,9 +28,13 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz |[nginx.ingress.kubernetes.io/auth-tls-verify-client](#client-certificate-authentication)|string| |[nginx.ingress.kubernetes.io/auth-tls-error-page](#client-certificate-authentication)|string| |[nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream](#client-certificate-authentication)|"true" or "false"| +|[nginx.ingress.kubernetes.io/auth-tls-match-cn](#client-certificate-authentication)|string| |[nginx.ingress.kubernetes.io/auth-url](#external-authentication)|string| |[nginx.ingress.kubernetes.io/auth-cache-key](#external-authentication)|string| |[nginx.ingress.kubernetes.io/auth-cache-duration](#external-authentication)|string| +|[nginx.ingress.kubernetes.io/auth-keepalive](#external-authentication)|number| +|[nginx.ingress.kubernetes.io/auth-keepalive-requests](#external-authentication)|number| +|[nginx.ingress.kubernetes.io/auth-keepalive-timeout](#external-authentication)|number| |[nginx.ingress.kubernetes.io/auth-proxy-set-headers](#external-authentication)|string| |[nginx.ingress.kubernetes.io/auth-snippet](#external-authentication)|string| |[nginx.ingress.kubernetes.io/enable-global-auth](#external-authentication)|"true" or "false"| @@ -127,6 +131,7 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz |[nginx.ingress.kubernetes.io/modsecurity-snippet](#modsecurity)|string| |[nginx.ingress.kubernetes.io/mirror-request-body](#mirror)|string| |[nginx.ingress.kubernetes.io/mirror-target](#mirror)|string| +|[nginx.ingress.kubernetes.io/mirror-host](#mirror)|string| ### Canary @@ -222,7 +227,7 @@ nginx.ingress.kubernetes.io/auth-realm: "realm string" ### Custom NGINX upstream hashing -NGINX supports load balancing by client-server mapping based on [consistent hashing](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#hash) for a given key. The key can contain text, variables or any combination thereof. This feature allows for request stickiness other than client IP or cookies. The [ketama](https://www.last.fm/user/RJ/journal/2007/04/10/rz_libketama_-_a_consistent_hashing_algo_for_memcache_clients) consistent hashing method will be used which ensures only a few keys would be remapped to different servers on upstream group changes. +NGINX supports load balancing by client-server mapping based on [consistent hashing](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#hash) for a given key. The key can contain text, variables or any combination thereof. This feature allows for request stickiness other than client IP or cookies. The [ketama](https://www.last.fm/user/RJ/journal/2007/04/10/rz_libketama_-_a_consistent_hashing_algo_for_memcache_clients) consistent hashing method will be used which ensures only a few keys would be remapped to different servers on upstream group changes. There is a special mode of upstream hashing called subset. In this mode, upstream servers are grouped into subsets, and stickiness works by mapping keys to a subset instead of individual upstream servers. Specific server is chosen uniformly at random from the selected sticky subset. It provides a balance between stickiness and load distribution. @@ -261,6 +266,7 @@ You can further customize client certificate authentication and behavior with th * `optional_no_ca`: Do optional client certificate validation, but do not fail the request when the client certificate is not signed by the CAs from `auth-tls-secret`. Certificate verification result is sent to the upstream service. * `nginx.ingress.kubernetes.io/auth-tls-error-page`: The URL/Page that user should be redirected in case of a Certificate Authentication Error * `nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream`: Indicates if the received certificates should be passed or not to the upstream server in the header `ssl-client-cert`. Possible values are "true" or "false" (default). +* `nginx.ingress.kubernetes.io/auth-tls-match-cn`: Adds a sanity check for the CN of the client certificate that is sent over using a string / regex starting with "CN=", example: `"CN=myvalidclient"`. If the certificate CN sent during mTLS does not match your string / regex it will fail with status code 403. Another way of using this is by adding multiple options in your regex, example: `"CN=(option1|option2|myvalidclient)"`. In this case, as long as one of the options in the brackets matches the certificate CN then you will receive a 200 status code. The following headers are sent to the upstream service according to the `auth-tls-*` annotations: @@ -277,7 +283,7 @@ The following headers are sent to the upstream service according to the `auth-tl Cloudflare only allows Authenticated Origin Pulls and is required to use their own certificate: [https://blog.cloudflare.com/protecting-the-origin-with-tls-authenticated-origin-pulls/](https://blog.cloudflare.com/protecting-the-origin-with-tls-authenticated-origin-pulls/) - Only Authenticated Origin Pulls are allowed and can be configured by following their tutorial: [https://support.cloudflare.com/hc/en-us/articles/204494148-Setting-up-NGINX-to-use-TLS-Authenticated-Origin-Pulls](https://support.cloudflare.com/hc/en-us/articles/204494148-Setting-up-NGINX-to-use-TLS-Authenticated-Origin-Pulls) + Only Authenticated Origin Pulls are allowed and can be configured by following their tutorial: [https://support.cloudflare.com/hc/en-us/articles/204494148-Setting-up-NGINX-to-use-TLS-Authenticated-Origin-Pulls](https://web.archive.org/web/20200907143649/https://support.cloudflare.com/hc/en-us/articles/204899617-Setting-up-NGINX-to-use-TLS-Authenticated-Origin-Pulls#section5) ### Backend Certificate Authentication @@ -291,11 +297,11 @@ It is possible to authenticate to a proxied HTTPS backend with certificate using * `nginx.ingress.kubernetes.io/proxy-ssl-verify-depth`: Sets the verification depth in the proxied HTTPS server certificates chain. (default: 1) * `nginx.ingress.kubernetes.io/proxy-ssl-ciphers`: - Specifies the enabled [ciphers](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_ciphers) for requests to a proxied HTTPS server. The ciphers are specified in the format understood by the OpenSSL library. + Specifies the enabled [ciphers](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_ciphers) for requests to a proxied HTTPS server. The ciphers are specified in the format understood by the OpenSSL library. * `nginx.ingress.kubernetes.io/proxy-ssl-name`: - Allows to set [proxy_ssl_name](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_name). This allows overriding the server name used to verify the certificate of the proxied HTTPS server. This value is also passed through SNI when a connection is established to the proxied HTTPS server. + Allows to set [proxy_ssl_name](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_name). This allows overriding the server name used to verify the certificate of the proxied HTTPS server. This value is also passed through SNI when a connection is established to the proxied HTTPS server. * `nginx.ingress.kubernetes.io/proxy-ssl-protocols`: - Enables the specified [protocols](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_protocols) for requests to a proxied HTTPS server. + Enables the specified [protocols](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_protocols) for requests to a proxied HTTPS server. * `nginx.ingress.kubernetes.io/proxy-ssl-server-name`: Enables passing of the server name through TLS Server Name Indication extension (SNI, RFC 6066) when establishing a connection with the proxied HTTPS server. @@ -346,7 +352,7 @@ CORS can be controlled with the following annotations: This is a multi-valued field, separated by ',' and accepts letters, numbers, _ and -. - - Default: `DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization` + - Default: `DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization` - Example: `nginx.ingress.kubernetes.io/cors-allow-headers: "X-Forwarded-For, X-app123-XPTO"` * `nginx.ingress.kubernetes.io/cors-expose-headers`: Controls which headers are exposed to response. @@ -397,7 +403,7 @@ This will create a server with the same configuration, but adding new values to If a server-alias is created and later a new server with the same hostname is created, the new server configuration will take place over the alias configuration. -For more information please see [the `server_name` documentation](http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name). +For more information please see [the `server_name` documentation](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_name). ### Server snippet @@ -441,7 +447,7 @@ applied to each location provided in the ingress rule. * `nginx.ingress.kubernetes.io/client-body-buffer-size: 1m` # 1 megabyte * `nginx.ingress.kubernetes.io/client-body-buffer-size: 1M` # 1 megabyte -For more information please see [http://nginx.org](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) +For more information please see [https://nginx.org](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) ### External Authentication @@ -453,6 +459,19 @@ nginx.ingress.kubernetes.io/auth-url: "URL to the authentication service" Additionally it is possible to set: +* `nginx.ingress.kubernetes.io/auth-keepalive`: + `` to specify the maximum number of keepalive connections to `auth-url`. Only takes effect + when no variables are used in the host part of the URL. Defaults to `0` (keepalive disabled). + +> Note: does not work with HTTP/2 listener because of a limitation in Lua [subrequests](https://github.com/openresty/lua-nginx-module#spdy-mode-not-fully-supported). +> [UseHTTP2](./configmap.md#use-http2) configuration should be disabled! + +* `nginx.ingress.kubernetes.io/auth-keepalive-requests`: + `` to specify the maximum number of requests that can be served through one keepalive connection. + Defaults to `1000` and only applied if `auth-keepalive` is set to higher than `0`. +* `nginx.ingress.kubernetes.io/auth-keepalive-timeout`: + `` to specify a duration in seconds which an idle keepalive connection to an upstream server will stay open. + Defaults to `60` and only applied if `auth-keepalive` is set to higher than `0`. * `nginx.ingress.kubernetes.io/auth-method`: `` to specify the HTTP method to use. * `nginx.ingress.kubernetes.io/auth-signin`: @@ -468,7 +487,9 @@ Additionally it is possible to set: * `nginx.ingress.kubernetes.io/auth-cache-key`: `` this enables caching for auth requests. specify a lookup key for auth responses. e.g. `$remote_user$http_authorization`. Each server and location has it's own keyspace. Hence a cached response is only valid on a per-server and per-location basis. * `nginx.ingress.kubernetes.io/auth-cache-duration`: - `` to specify a caching time for auth responses based on their response codes, e.g. `200 202 30m`. See [proxy_cache_valid](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid) for details. You may specify multiple, comma-separated values: `200 202 10m, 401 5m`. defaults to `200 202 401 5m`. + `` to specify a caching time for auth responses based on their response codes, e.g. `200 202 30m`. See [proxy_cache_valid](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid) for details. You may specify multiple, comma-separated values: `200 202 10m, 401 5m`. defaults to `200 202 401 5m`. +* `nginx.ingress.kubernetes.io/auth-always-set-cookie`: + `` to set a cookie returned by auth request. By default, the cookie will be set only if an upstream reports with the code 200, 201, 204, 206, 301, 302, 303, 304, 307, or 308. * `nginx.ingress.kubernetes.io/auth-snippet`: `` to specify a custom snippet to use with external authentication, e.g. @@ -642,7 +663,7 @@ Note: All timeout values are unitless and in seconds e.g. `nginx.ingress.kuberne ### Proxy redirect The annotations `nginx.ingress.kubernetes.io/proxy-redirect-from` and `nginx.ingress.kubernetes.io/proxy-redirect-to` will set the first and second parameters of NGINX's proxy_redirect directive respectively. It is possible to -set the text that should be changed in the `Location` and `Refresh` header fields of a [proxied server response](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect) +set the text that should be changed in the `Location` and `Refresh` header fields of a [proxied server response](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect) Setting "off" or "default" in the annotation `nginx.ingress.kubernetes.io/proxy-redirect-from` disables `nginx.ingress.kubernetes.io/proxy-redirect-to`, otherwise, both annotations must be used in unison. Note that each annotation must be a string without spaces. @@ -651,7 +672,7 @@ By default the value of each annotation is "off". ### Custom max body size -For NGINX, an 413 error will be returned to the client when the size in a request exceeds the maximum allowed size of the client request body. This size can be configured by the parameter [`client_max_body_size`](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). +For NGINX, an 413 error will be returned to the client when the size in a request exceeds the maximum allowed size of the client request body. This size can be configured by the parameter [`client_max_body_size`](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). To configure this setting globally for all Ingress rules, the `proxy-body-size` value may be set in the [NGINX ConfigMap](./configmap.md#proxy-body-size). To use custom values in an Ingress rule define these annotation: @@ -662,19 +683,19 @@ nginx.ingress.kubernetes.io/proxy-body-size: 8m ### Proxy cookie domain -Sets a text that [should be changed in the domain attribute](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain) of the "Set-Cookie" header fields of a proxied server response. +Sets a text that [should be changed in the domain attribute](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain) of the "Set-Cookie" header fields of a proxied server response. To configure this setting globally for all Ingress rules, the `proxy-cookie-domain` value may be set in the [NGINX ConfigMap](./configmap.md#proxy-cookie-domain). ### Proxy cookie path -Sets a text that [should be changed in the path attribute](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_path) of the "Set-Cookie" header fields of a proxied server response. +Sets a text that [should be changed in the path attribute](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_path) of the "Set-Cookie" header fields of a proxied server response. To configure this setting globally for all Ingress rules, the `proxy-cookie-path` value may be set in the [NGINX ConfigMap](./configmap.md#proxy-cookie-path). ### Proxy buffering -Enable or disable proxy buffering [`proxy_buffering`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering). +Enable or disable proxy buffering [`proxy_buffering`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering). By default proxy buffering is disabled in the NGINX config. To configure this setting globally for all Ingress rules, the `proxy-buffering` value may be set in the [NGINX ConfigMap](./configmap.md#proxy-buffering). @@ -686,7 +707,7 @@ nginx.ingress.kubernetes.io/proxy-buffering: "on" ### Proxy buffers Number -Sets the number of the buffers in [`proxy_buffers`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers) used for reading the first part of the response received from the proxied server. +Sets the number of the buffers in [`proxy_buffers`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers) used for reading the first part of the response received from the proxied server. By default proxy buffers number is set as 4 To configure this setting globally, set `proxy-buffers-number` in [NGINX ConfigMap](./configmap.md#proxy-buffers-number). To use custom values in an Ingress rule, define this annotation: @@ -696,7 +717,7 @@ nginx.ingress.kubernetes.io/proxy-buffers-number: "4" ### Proxy buffer size -Sets the size of the buffer [`proxy_buffer_size`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) used for reading the first part of the response received from the proxied server. +Sets the size of the buffer [`proxy_buffer_size`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) used for reading the first part of the response received from the proxied server. By default proxy buffer size is set as "4k" To configure this setting globally, set `proxy-buffer-size` in [NGINX ConfigMap](./configmap.md#proxy-buffer-size). To use custom values in an Ingress rule, define this annotation: @@ -706,7 +727,7 @@ nginx.ingress.kubernetes.io/proxy-buffer-size: "8k" ### Proxy max temp file size -When [`buffering`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering) of responses from the proxied server is enabled, and the whole response does not fit into the buffers set by the [`proxy_buffer_size`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) and [`proxy_buffers`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers) directives, a part of the response can be saved to a temporary file. This directive sets the maximum `size` of the temporary file setting the [`proxy_max_temp_file_size`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_max_temp_file_size). The size of data written to the temporary file at a time is set by the [`proxy_temp_file_write_size`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_temp_file_write_size) directive. +When [`buffering`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering) of responses from the proxied server is enabled, and the whole response does not fit into the buffers set by the [`proxy_buffer_size`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) and [`proxy_buffers`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers) directives, a part of the response can be saved to a temporary file. This directive sets the maximum `size` of the temporary file setting the [`proxy_max_temp_file_size`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_max_temp_file_size). The size of data written to the temporary file at a time is set by the [`proxy_temp_file_write_size`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_temp_file_write_size) directive. The zero value disables buffering of responses to temporary files. @@ -717,7 +738,7 @@ nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "1024m" ### Proxy HTTP version -Using this annotation sets the [`proxy_http_version`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version) that the Nginx reverse proxy will use to communicate with the backend. +Using this annotation sets the [`proxy_http_version`](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version) that the Nginx reverse proxy will use to communicate with the backend. By default this is set to "1.1". ```yaml @@ -726,7 +747,7 @@ nginx.ingress.kubernetes.io/proxy-http-version: "1.0" ### SSL ciphers -Specifies the [enabled ciphers](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers). +Specifies the [enabled ciphers](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers). Using this annotation will set the `ssl_ciphers` directive at the server level. This configuration is active for all the paths in the host. @@ -923,6 +944,13 @@ By default the request-body is sent to the mirror backend, but can be turned off nginx.ingress.kubernetes.io/mirror-request-body: "off" ``` +Also by default header Host for mirrored requests will be set the same as a host part of uri in the "mirror-target" annotation. You can override it by "mirror-host" annotation: + +```yaml +nginx.ingress.kubernetes.io/mirror-target: https://1.2.3.4/$request_uri +nginx.ingress.kubernetes.io/mirror-host: "test.env.com" +``` + **Note:** The mirror directive will be applied to all paths within the ingress resource. The request sent to the mirror is linked to the original request. If you have a slow mirror backend, then the original request will throttle. diff --git a/docs/user-guide/nginx-configuration/configmap.md b/docs/user-guide/nginx-configuration/configmap.md index b48cc1028..270dd1c62 100755 --- a/docs/user-guide/nginx-configuration/configmap.md +++ b/docs/user-guide/nginx-configuration/configmap.md @@ -111,6 +111,7 @@ The following table shows a configuration option's name, type, and the default v |[variables-hash-bucket-size](#variables-hash-bucket-size)|int|128| |[variables-hash-max-size](#variables-hash-max-size)|int|2048| |[upstream-keepalive-connections](#upstream-keepalive-connections)|int|320| +|[upstream-keepalive-time](#upstream-keepalive-time)|string|"1h"| |[upstream-keepalive-timeout](#upstream-keepalive-timeout)|int|60| |[upstream-keepalive-requests](#upstream-keepalive-requests)|int|10000| |[limit-conn-zone-variable](#limit-conn-zone-variable)|string|"$binary_remote_addr"| @@ -210,6 +211,7 @@ The following table shows a configuration option's name, type, and the default v |[global-rate-limit-status-code](#global-rate-limit)|int|429| |[service-upstream](#service-upstream)|bool|"false"| |[ssl-reject-handshake](#ssl-reject-handshake)|bool|"false"| +|[debug-connections](#debug-connections)|[]string|"127.0.0.1,1.1.1.1/24"| ## add-headers @@ -223,13 +225,13 @@ Enables the return of the header Server from the backend instead of the generic Enables Ingress to parse and add *-snippet annotations/directives created by the user. _**default:**_ `true` -Warning: We recommend enabling this option only if you TRUST users with permission to create Ingress objects, as this +Warning: We recommend enabling this option only if you TRUST users with permission to create Ingress objects, as this may allow a user to add restricted configurations to the final nginx.conf file ## annotation-value-word-blocklist -Contains a comma-separated value of chars/words that are well known of being used to abuse Ingress configuration -and must be blocked. Related to [CVE-2021-25742](https://github.com/kubernetes/ingress-nginx/issues/7837) +Contains a comma-separated value of chars/words that are well known of being used to abuse Ingress configuration +and must be blocked. Related to [CVE-2021-25742](https://github.com/kubernetes/ingress-nginx/issues/7837) When an annotation is detected with a value that matches one of the blocked bad words, the whole Ingress won't be configured. @@ -238,7 +240,7 @@ _**default:**_ `""` When doing this, the default blocklist is override, which means that the Ingress admin should add all the words that should be blocked, here is a suggested block list. -_**suggested:**_ `"load_module,lua_package,_by_lua,location,root,proxy_pass,serviceaccount,{,},',\"` +_**suggested:**_ `"load_module,lua_package,_by_lua,location,root,proxy_pass,serviceaccount,{,},',\""` ## hide-headers @@ -246,14 +248,14 @@ Sets additional header that will not be passed from the upstream server to the c _**default:**_ empty _References:_ -[http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header) +[https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header) ## access-log-params Additional params for access_log. For example, buffer=16k, gzip, flush=1m _References:_ -[http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log](http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log) +[https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log](https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log) ## access-log-path @@ -286,7 +288,7 @@ Error log path. Goes to `/var/log/nginx/error.log` by default. __Note:__ the file `/var/log/nginx/error.log` is a symlink to `/dev/stderr` _References:_ -[http://nginx.org/en/docs/ngx_core_module.html#error_log](http://nginx.org/en/docs/ngx_core_module.html#error_log) +[https://nginx.org/en/docs/ngx_core_module.html#error_log](https://nginx.org/en/docs/ngx_core_module.html#error_log) ## enable-modsecurity @@ -305,35 +307,35 @@ Adds custom rules to modsecurity section of nginx configuration Allows to configure a custom buffer size for reading client request header. _References:_ -[http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_buffer_size) +[https://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_buffer_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_buffer_size) ## client-header-timeout Defines a timeout for reading client request header, in seconds. _References:_ -[http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout) +[https://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout) ## client-body-buffer-size Sets buffer size for reading client request body. _References:_ -[http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) +[https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) ## client-body-timeout Defines a timeout for reading client request body, in seconds. _References:_ -[http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout) +[https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout) ## disable-access-log Disables the Access Log from the entire Ingress Controller. _**default:**_ `false` _References:_ -[http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log](http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log) +[https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log](https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log) ## disable-ipv6 @@ -366,10 +368,13 @@ Since 1.9.13 NGINX will not retry non-idempotent requests (POST, LOCK, PATCH) in Configures the logging level of errors. Log levels above are listed in the order of increasing severity. _References:_ -[http://nginx.org/en/docs/ngx_core_module.html#error_log](http://nginx.org/en/docs/ngx_core_module.html#error_log) +[https://nginx.org/en/docs/ngx_core_module.html#error_log](https://nginx.org/en/docs/ngx_core_module.html#error_log) ## http2-max-field-size +!!! warning + This feature was deprecated in 1.1.3 and will be removed in 1.3.0. Use [large-client-header-buffers](#large-client-header-buffers) instead. + Limits the maximum size of an HPACK-compressed request header field. _References:_ @@ -377,6 +382,9 @@ _References:_ ## http2-max-header-size +!!! warning + This feature was deprecated in 1.1.3 and will be removed in 1.3.0. Use [large-client-header-buffers](#large-client-header-buffers) instead. + Limits the maximum size of the entire request header list after HPACK decompression. _References:_ @@ -384,17 +392,20 @@ _References:_ ## http2-max-requests +!!! warning + This feature was deprecated in 1.1.3 and will be removed in 1.3.0. Use [upstream-keepalive-requests](#upstream-keepalive-requests) instead. + Sets the maximum number of requests (including push requests) that can be served through one HTTP/2 connection, after which the next client request will lead to connection closing and the need of establishing a new connection. _References:_ -[http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_requests](http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_requests) +[https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_requests](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_requests) ## http2-max-concurrent-streams Sets the maximum number of concurrent HTTP/2 streams in a connection. _References:_ -[http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_concurrent_streams](http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_concurrent_streams) +[https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_concurrent_streams](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_concurrent_streams) ## hsts @@ -423,7 +434,7 @@ Enables or disables the preload attribute in the HSTS feature (when it is enable Sets the time during which a keep-alive client connection will stay open on the server side. The zero value disables keep-alive client connections. _References:_ -[http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout) +[https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout](https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout) !!! important Setting `keep-alive: '0'` will most likely break concurrent http/2 requests due to changes introduced with nginx 1.19.7 @@ -439,7 +450,7 @@ Changes with nginx 1.19.7 16 Feb 2021 ``` _References:_ -[nginx change log](http://nginx.org/en/CHANGES) +[nginx change log](https://nginx.org/en/CHANGES) [nginx issue tracker](https://trac.nginx.org/nginx/ticket/2155) [nginx mailing list](https://mailman.nginx.org/pipermail/nginx/2021-May/060697.html) @@ -448,22 +459,22 @@ _References:_ Sets the maximum number of requests that can be served through one keep-alive connection. _References:_ -[http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_requests](http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_requests) +[https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_requests](https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_requests) ## large-client-header-buffers Sets the maximum number and size of buffers used for reading large client request header. _**default:**_ 4 8k _References:_ -[http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers](http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers) +[https://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers](https://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers) ## log-format-escape-json -Sets if the escape parameter allows JSON ("true") or default characters escaping in variables ("false") Sets the nginx [log format](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format). +Sets if the escape parameter allows JSON ("true") or default characters escaping in variables ("false") Sets the nginx [log format](https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format). ## log-format-upstream -Sets the nginx [log format](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format). +Sets the nginx [log format](https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format). Example for json output: ```json @@ -486,11 +497,11 @@ If disabled, a worker process will accept one new connection at a time. Otherwis _**default:**_ true _References:_ -[http://nginx.org/en/docs/ngx_core_module.html#multi_accept](http://nginx.org/en/docs/ngx_core_module.html#multi_accept) +[https://nginx.org/en/docs/ngx_core_module.html#multi_accept](https://nginx.org/en/docs/ngx_core_module.html#multi_accept) ## max-worker-connections -Sets the [maximum number of simultaneous connections](http://nginx.org/en/docs/ngx_core_module.html#worker_connections) that can be opened by each worker process. +Sets the [maximum number of simultaneous connections](https://nginx.org/en/docs/ngx_core_module.html#worker_connections) that can be opened by each worker process. 0 will use the value of [max-worker-open-files](#max-worker-open-files). _**default:**_ 16384 @@ -499,13 +510,13 @@ _**default:**_ 16384 ## max-worker-open-files -Sets the [maximum number of files](http://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_nofile) that can be opened by each worker process. +Sets the [maximum number of files](https://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_nofile) that can be opened by each worker process. The default of 0 means "max open files (system's limit) - 1024". _**default:**_ 0 ## map-hash-bucket-size -Sets the bucket size for the [map variables hash tables](http://nginx.org/en/docs/http/ngx_http_map_module.html#map_hash_bucket_size). The details of setting up hash tables are provided in a separate [document](http://nginx.org/en/docs/hash.html). +Sets the bucket size for the [map variables hash tables](https://nginx.org/en/docs/http/ngx_http_map_module.html#map_hash_bucket_size). The details of setting up hash tables are provided in a separate [document](https://nginx.org/en/docs/hash.html). ## proxy-real-ip-cidr @@ -518,10 +529,10 @@ Sets custom headers from named configmap before sending traffic to backends. The ## server-name-hash-max-size -Sets the maximum size of the [server names hash tables](http://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_max_size) used in server names,map directive’s values, MIME types, names of request header strings, etc. +Sets the maximum size of the [server names hash tables](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_max_size) used in server names,map directive’s values, MIME types, names of request header strings, etc. _References:_ -[http://nginx.org/en/docs/hash.html](http://nginx.org/en/docs/hash.html) +[https://nginx.org/en/docs/hash.html](https://nginx.org/en/docs/hash.html) ## server-name-hash-bucket-size @@ -529,8 +540,8 @@ Sets the size of the bucket for the server names hash tables. _References:_ -- [http://nginx.org/en/docs/hash.html](http://nginx.org/en/docs/hash.html) -- [http://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_bucket_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_bucket_size) +- [https://nginx.org/en/docs/hash.html](https://nginx.org/en/docs/hash.html) +- [https://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_bucket_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_bucket_size) ## proxy-headers-hash-max-size @@ -538,7 +549,7 @@ Sets the maximum size of the proxy headers hash tables. _References:_ -- [http://nginx.org/en/docs/hash.html](http://nginx.org/en/docs/hash.html) +- [https://nginx.org/en/docs/hash.html](https://nginx.org/en/docs/hash.html) - [https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_max_size](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_max_size) ## reuse-port @@ -552,7 +563,7 @@ Sets the size of the bucket for the proxy headers hash tables. _References:_ -- [http://nginx.org/en/docs/hash.html](http://nginx.org/en/docs/hash.html) +- [https://nginx.org/en/docs/hash.html](https://nginx.org/en/docs/hash.html) - [https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_bucket_size](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_bucket_size) ## plugins @@ -565,7 +576,7 @@ Send NGINX Server header in responses and display NGINX version in error pages. ## ssl-ciphers -Sets the [ciphers](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers) list to enable. The ciphers are specified in the format understood by the OpenSSL library. +Sets the [ciphers](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers) list to enable. The ciphers are specified in the format understood by the OpenSSL library. The default cipher list is: `ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384`. @@ -583,7 +594,7 @@ __Note:__ ssl_prefer_server_ciphers directive will be enabled by default for htt Specifies a curve for ECDHE ciphers. _References:_ -[http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ecdh_curve](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ecdh_curve) +[https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ecdh_curve](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ecdh_curve) ## ssl-dh-param @@ -593,11 +604,11 @@ _References:_ - [https://wiki.openssl.org/index.php/Diffie-Hellman_parameters](https://wiki.openssl.org/index.php/Diffie-Hellman_parameters) - [https://wiki.mozilla.org/Security/Server_Side_TLS#DHE_handshake_and_dhparam](https://wiki.mozilla.org/Security/Server_Side_TLS#DHE_handshake_and_dhparam) -- [http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam) +- [https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam) ## ssl-protocols -Sets the [SSL protocols](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols) to use. The default is: `TLSv1.2 TLSv1.3`. +Sets the [SSL protocols](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols) to use. The default is: `TLSv1.2 TLSv1.3`. Please check the result of the configuration using `https://ssllabs.com/ssltest/analyze.html` or `https://testssl.sh`. @@ -609,34 +620,34 @@ Time Resumption (0-RTT). This requires `ssl-protocols` to have `TLSv1.3` enabled. Enable this with caution, because requests sent within early data are subject to [replay attacks](https://tools.ietf.org/html/rfc8470). -[ssl_early_data](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data). The default is: `false`. +[ssl_early_data](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data). The default is: `false`. ## ssl-session-cache -Enables or disables the use of shared [SSL cache](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache) among worker processes. +Enables or disables the use of shared [SSL cache](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache) among worker processes. ## ssl-session-cache-size -Sets the size of the [SSL shared session cache](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache) between all worker processes. +Sets the size of the [SSL shared session cache](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache) between all worker processes. ## ssl-session-tickets -Enables or disables session resumption through [TLS session tickets](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets). +Enables or disables session resumption through [TLS session tickets](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets). ## ssl-session-ticket-key Sets the secret key used to encrypt and decrypt TLS session tickets. The value must be a valid base64 string. To create a ticket: `openssl rand 80 | openssl enc -A -base64` -[TLS session ticket-key](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets), by default, a randomly generated key is used. +[TLS session ticket-key](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets), by default, a randomly generated key is used. ## ssl-session-timeout -Sets the time during which a client may [reuse the session](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_timeout) parameters stored in a cache. +Sets the time during which a client may [reuse the session](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_timeout) parameters stored in a cache. ## ssl-buffer-size -Sets the size of the [SSL buffer](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size) used for sending data. The default of 4k helps NGINX to improve TLS Time To First Byte (TTTFB). +Sets the size of the [SSL buffer](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size) used for sending data. The default of 4k helps NGINX to improve TLS Time To First Byte (TTTFB). _References:_ [https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/](https://www.igvita.com/2013/12/16/optimizing-nginx-tls-time-to-first-byte/) @@ -652,11 +663,11 @@ _**default:**_ 5s ## use-gzip -Enables or disables compression of HTTP responses using the ["gzip" module](http://nginx.org/en/docs/http/ngx_http_gzip_module.html). MIME types to compress are controlled by [gzip-types](#gzip-types). _**default:**_ false +Enables or disables compression of HTTP responses using the ["gzip" module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html). MIME types to compress are controlled by [gzip-types](#gzip-types). _**default:**_ false ## use-geoip -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](https://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 > __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. @@ -695,7 +706,7 @@ _**default:**_ `application/xml+rss application/atom+xml application/javascript ## use-http2 -Enables or disables [HTTP/2](http://nginx.org/en/docs/http/ngx_http_v2_module.html) support in secure connections. +Enables or disables [HTTP/2](https://nginx.org/en/docs/http/ngx_http_v2_module.html) support in secure connections. ## gzip-level @@ -712,12 +723,12 @@ _**default:**_ `application/atom+xml application/javascript application/x-javasc ## worker-processes -Sets the number of [worker processes](http://nginx.org/en/docs/ngx_core_module.html#worker_processes). +Sets the number of [worker processes](https://nginx.org/en/docs/ngx_core_module.html#worker_processes). The default of "auto" means number of available CPU cores. ## worker-cpu-affinity -Binds worker processes to the sets of CPUs. [worker_cpu_affinity](http://nginx.org/en/docs/ngx_core_module.html#worker_cpu_affinity). +Binds worker processes to the sets of CPUs. [worker_cpu_affinity](https://nginx.org/en/docs/ngx_core_module.html#worker_cpu_affinity). By default worker processes are not bound to any specific CPUs. The value can be: - "": empty string indicate no affinity is applied. @@ -726,7 +737,7 @@ By default worker processes are not bound to any specific CPUs. The value can be ## worker-shutdown-timeout -Sets a timeout for Nginx to [wait for worker to gracefully shutdown](http://nginx.org/en/docs/ngx_core_module.html#worker_shutdown_timeout). _**default:**_ "240s" +Sets a timeout for Nginx to [wait for worker to gracefully shutdown](https://nginx.org/en/docs/ngx_core_module.html#worker_shutdown_timeout). _**default:**_ "240s" ## load-balance @@ -742,21 +753,21 @@ The default is `round_robin`. - To load balance using session cookies, consider the `nginx.ingress.kubernetes.io/affinity` annotation. _References:_ -[http://nginx.org/en/docs/http/load_balancing.html](http://nginx.org/en/docs/http/load_balancing.html) +[https://nginx.org/en/docs/http/load_balancing.html](https://nginx.org/en/docs/http/load_balancing.html) ## variables-hash-bucket-size Sets the bucket size for the variables hash table. _References:_ -[http://nginx.org/en/docs/http/ngx_http_map_module.html#variables_hash_bucket_size](http://nginx.org/en/docs/http/ngx_http_map_module.html#variables_hash_bucket_size) +[https://nginx.org/en/docs/http/ngx_http_map_module.html#variables_hash_bucket_size](https://nginx.org/en/docs/http/ngx_http_map_module.html#variables_hash_bucket_size) ## variables-hash-max-size Sets the maximum size of the variables hash table. _References:_ -[http://nginx.org/en/docs/http/ngx_http_map_module.html#variables_hash_max_size](http://nginx.org/en/docs/http/ngx_http_map_module.html#variables_hash_max_size) +[https://nginx.org/en/docs/http/ngx_http_map_module.html#variables_hash_max_size](https://nginx.org/en/docs/http/ngx_http_map_module.html#variables_hash_max_size) ## upstream-keepalive-connections @@ -766,16 +777,24 @@ exceeded, the least recently used connections are closed. _**default:**_ 320 _References:_ -[http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) +[https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) +## upstream-keepalive-time + +Sets the maximum time during which requests can be processed through one keepalive connection. + _**default:**_ "1h" + +_References:_ +[http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_time](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_time) + ## upstream-keepalive-timeout Sets a timeout during which an idle keepalive connection to an upstream server will stay open. _**default:**_ 60 _References:_ -[http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_timeout](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_timeout) +[https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_timeout](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_timeout) ## upstream-keepalive-requests @@ -786,47 +805,47 @@ _**default:**_ 10000 _References:_ -[http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_requests](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_requests) +[https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_requests](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_requests) ## limit-conn-zone-variable -Sets parameters for a shared memory zone that will keep states for various keys of [limit_conn_zone](http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_zone). The default of "$binary_remote_addr" variable’s size is always 4 bytes for IPv4 addresses or 16 bytes for IPv6 addresses. +Sets parameters for a shared memory zone that will keep states for various keys of [limit_conn_zone](https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_zone). The default of "$binary_remote_addr" variable’s size is always 4 bytes for IPv4 addresses or 16 bytes for IPv6 addresses. ## proxy-stream-timeout Sets the timeout between two successive read or write operations on client or proxied server connections. If no data is transmitted within this time, the connection is closed. _References:_ -[http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_timeout](http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_timeout) +[https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_timeout](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_timeout) ## proxy-stream-next-upstream When a connection to the proxied server cannot be established, determines whether a client connection will be passed to the next server. _References:_ -[http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream](http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream) +[https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream) ## proxy-stream-next-upstream-timeout Limits the time allowed to pass a connection to the next server. The 0 value turns off this limitation. _References:_ -[http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream_timeout](http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream_timeout) +[https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream_timeout](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream_timeout) ## proxy-stream-next-upstream-tries Limits the number of possible tries a request should be passed to the next server. The 0 value turns off this limitation. _References:_ -[http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream_tries](http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream_timeout) +[https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream_tries](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream_timeout) ## proxy-stream-responses Sets the number of datagrams expected from the proxied server in response to the client request if the UDP protocol is used. _References:_ -[http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_responses](http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_responses) +[https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_responses](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_responses) ## bind-address @@ -840,7 +859,7 @@ If false, NGINX ignores incoming `X-Forwarded-*` headers, filling them with the ## enable-real-ip -`enable-real-ip` enables the configuration of [http://nginx.org/en/docs/http/ngx_http_realip_module.html](http://nginx.org/en/docs/http/ngx_http_realip_module.html). Specific attributes of the module can be configured further by using `forwarded-for-header` and `proxy-real-ip-cidr` settings. +`enable-real-ip` enables the configuration of [https://nginx.org/en/docs/http/ngx_http_realip_module.html](https://nginx.org/en/docs/http/ngx_http_realip_module.html). Specific attributes of the module can be configured further by using `forwarded-for-header` and `proxy-real-ip-cidr` settings. ## forwarded-for-header @@ -965,7 +984,7 @@ Specifies the environment this trace belongs to. _**default:**_ prod ## datadog-operation-name-override -Overrides the operation naem to use for any traces crated. _**default:**_ nginx.handle +Overrides the operation name to use for any traces crated. _**default:**_ nginx.handle ## datadog-priority-sampling @@ -1001,67 +1020,67 @@ You can not use this to add new locations that proxy to the Kubernetes pods, as ## custom-http-errors -Enables which HTTP codes should be passed for processing with the [error_page directive](http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page) +Enables which HTTP codes should be passed for processing with the [error_page directive](https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page) -Setting at least one code also enables [proxy_intercept_errors](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors) which are required to process error_page. +Setting at least one code also enables [proxy_intercept_errors](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors) which are required to process error_page. Example usage: `custom-http-errors: 404,415` ## proxy-body-size Sets the maximum allowed size of the client request body. -See NGINX [client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). +See NGINX [client_max_body_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). ## proxy-connect-timeout -Sets the timeout for [establishing a connection with a proxied server](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout). It should be noted that this timeout cannot usually exceed 75 seconds. +Sets the timeout for [establishing a connection with a proxied server](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout). It should be noted that this timeout cannot usually exceed 75 seconds. ## proxy-read-timeout -Sets the timeout in seconds for [reading a response from the proxied server](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout). The timeout is set only between two successive read operations, not for the transmission of the whole response. +Sets the timeout in seconds for [reading a response from the proxied server](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout). The timeout is set only between two successive read operations, not for the transmission of the whole response. ## proxy-send-timeout -Sets the timeout in seconds for [transmitting a request to the proxied server](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout). The timeout is set only between two successive write operations, not for the transmission of the whole request. +Sets the timeout in seconds for [transmitting a request to the proxied server](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout). The timeout is set only between two successive write operations, not for the transmission of the whole request. ## proxy-buffers-number -Sets the number of the buffer used for [reading the first part of the response](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers) received from the proxied server. This part usually contains a small response header. +Sets the number of the buffer used for [reading the first part of the response](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers) received from the proxied server. This part usually contains a small response header. ## proxy-buffer-size -Sets the size of the buffer used for [reading the first part of the response](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) received from the proxied server. This part usually contains a small response header. +Sets the size of the buffer used for [reading the first part of the response](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size) received from the proxied server. This part usually contains a small response header. ## proxy-cookie-path -Sets a text that [should be changed in the path attribute](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_path) of the “Set-Cookie” header fields of a proxied server response. +Sets a text that [should be changed in the path attribute](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_path) of the “Set-Cookie” header fields of a proxied server response. ## proxy-cookie-domain -Sets a text that [should be changed in the domain attribute](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain) of the “Set-Cookie” header fields of a proxied server response. +Sets a text that [should be changed in the domain attribute](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain) of the “Set-Cookie” header fields of a proxied server response. ## proxy-next-upstream -Specifies in [which cases](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream) a request should be passed to the next server. +Specifies in [which cases](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream) a request should be passed to the next server. ## proxy-next-upstream-timeout -[Limits the time](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream_timeout) in seconds during which a request can be passed to the next server. +[Limits the time](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream_timeout) in seconds during which a request can be passed to the next server. ## proxy-next-upstream-tries -Limit the number of [possible tries](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream_tries) a request should be passed to the next server. +Limit the number of [possible tries](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream_tries) a request should be passed to the next server. ## proxy-redirect-from Sets the original text that should be changed in the "Location" and "Refresh" header fields of a proxied server response. _**default:**_ off _References:_ -[http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect) +[https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect) ## proxy-request-buffering -Enables or disables [buffering of a client request body](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering). +Enables or disables [buffering of a client request body](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering). ## ssl-redirect @@ -1075,7 +1094,7 @@ _**default:**_ "false" ## whitelist-source-range Sets the default whitelisted IPs for each `server` block. This can be overwritten by an annotation on an Ingress rule. -See [ngx_http_access_module](http://nginx.org/en/docs/http/ngx_http_access_module.html). +See [ngx_http_access_module](https://nginx.org/en/docs/http/ngx_http_access_module.html). ## skip-access-log-urls @@ -1086,7 +1105,7 @@ Sets a list of URLs that should not appear in the NGINX access log. This is usef Limits the rate of response transmission to a client. The rate is specified in bytes per second. The zero value disables rate limiting. The limit is set per a request, and so if a client simultaneously opens two connections, the overall rate will be twice as much as the specified limit. _References:_ -[http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate](http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate) +[https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate](https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate) ## limit-rate-after @@ -1114,7 +1133,7 @@ lua-shared-dicts: "certificate_data: 100, my_custom_plugin: 512k" ``` _References:_ -[http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate_after](http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate_after) +[https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate_after](https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate_after) ## http-redirect-code @@ -1128,19 +1147,19 @@ _**default:**_ 308 ## proxy-buffering -Enables or disables [buffering of responses from the proxied server](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering). +Enables or disables [buffering of responses from the proxied server](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering). ## limit-req-status-code -Sets the [status code to return in response to rejected requests](http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_status). _**default:**_ 503 +Sets the [status code to return in response to rejected requests](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_status). _**default:**_ 503 ## limit-conn-status-code -Sets the [status code to return in response to rejected connections](http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_status). _**default:**_ 503 +Sets the [status code to return in response to rejected connections](https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_status). _**default:**_ 503 ## enable-syslog -Enable [syslog](http://nginx.org/en/docs/syslog.html) feature for access log and error log. _**default:**_ false +Enable [syslog](https://nginx.org/en/docs/syslog.html) feature for access log and error log. _**default:**_ false ## syslog-host @@ -1206,7 +1225,12 @@ Enables caching for global auth requests. Specify a lookup key for auth response ## global-auth-cache-duration -Set a caching time for auth responses based on their response codes, e.g. `200 202 30m`. See [proxy_cache_valid](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid) for details. You may specify multiple, comma-separated values: `200 202 10m, 401 5m`. defaults to `200 202 401 5m`. +Set a caching time for auth responses based on their response codes, e.g. `200 202 30m`. See [proxy_cache_valid](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid) for details. You may specify multiple, comma-separated values: `200 202 10m, 401 5m`. defaults to `200 202 401 5m`. + +## global-auth-always-set-cookie + +Always set a cookie returned by auth request. By default, the cookie will be set only if an upstream reports with the code 200, 201, 204, 206, 301, 302, 303, 304, 307, or 308. +_**default:**_ false ## no-auth-locations @@ -1218,7 +1242,7 @@ _**default:**_ "/.well-known/acme-challenge" A comma-separated list of IP addresses (or subnets), request from which have to be blocked globally. _References:_ -[http://nginx.org/en/docs/http/ngx_http_access_module.html#deny](http://nginx.org/en/docs/http/ngx_http_access_module.html#deny) +[https://nginx.org/en/docs/http/ngx_http_access_module.html#deny](https://nginx.org/en/docs/http/ngx_http_access_module.html#deny) ## block-user-agents @@ -1226,7 +1250,7 @@ A comma-separated list of User-Agent, request from which have to be blocked glob It's possible to use here full strings and regular expressions. More details about valid patterns can be found at `map` Nginx directive documentation. _References:_ -[http://nginx.org/en/docs/http/ngx_http_map_module.html#map](http://nginx.org/en/docs/http/ngx_http_map_module.html#map) +[https://nginx.org/en/docs/http/ngx_http_map_module.html#map](https://nginx.org/en/docs/http/ngx_http_map_module.html#map) ## block-referers @@ -1234,7 +1258,7 @@ A comma-separated list of Referers, request from which have to be blocked global It's possible to use here full strings and regular expressions. More details about valid patterns can be found at `map` Nginx directive documentation. _References:_ -[http://nginx.org/en/docs/http/ngx_http_map_module.html#map](http://nginx.org/en/docs/http/ngx_http_map_module.html#map) +[https://nginx.org/en/docs/http/ngx_http_map_module.html#map](https://nginx.org/en/docs/http/ngx_http_map_module.html#map) ## proxy-ssl-location-only @@ -1247,7 +1271,7 @@ Sets the default MIME type of a response. _**default:**_ text/html _References:_ -[http://nginx.org/en/docs/http/ngx_http_core_module.html#default_type](http://nginx.org/en/docs/http/ngx_http_core_module.html#default_type) +[https://nginx.org/en/docs/http/ngx_http_core_module.html#default_type](https://nginx.org/en/docs/http/ngx_http_core_module.html#default_type) ## global-rate-limit @@ -1258,7 +1282,7 @@ Configure `memcached` client for [Global Rate Limiting](https://github.com/kuber * `global-rate-limit-memcached-host`: IP/FQDN of memcached server to use. Required to enable Global Rate Limiting. * `global-rate-limit-memcached-port`: port of memcached server to use. Defaults default memcached port of `11211`. * `global-rate-limit-memcached-connect-timeout`: configure timeout for connect, send and receive operations. Unit is millisecond. Defaults to 50ms. -* `global-rate-limit-memcached-max-idle-timeout`: configure timeout for cleaning idle connections. Unit is millisecond. Defaults to 50ms. +* `global-rate-limit-memcached-max-idle-timeout`: configure timeout for cleaning idle connections. Unit is millisecond. Defaults to 50ms. * `global-rate-limit-memcached-pool-size`: configure number of max connections to keep alive. Make sure your `memcached` server can handle `global-rate-limit-memcached-pool-size * worker-processes * ` simultaneous connections. @@ -1277,3 +1301,10 @@ _**default:**_ "false" _References:_ [https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_reject_handshake](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_reject_handshake) + +## debug-connections +Enables debugging log for selected client connections. +_**default:**_ "" + +_References:_ +[http://nginx.org/en/docs/ngx_core_module.html#debug_connection](http://nginx.org/en/docs/ngx_core_module.html#debug_connection) diff --git a/docs/user-guide/nginx-configuration/index.md b/docs/user-guide/nginx-configuration/index.md index bace1a086..232dd5cf8 100644 --- a/docs/user-guide/nginx-configuration/index.md +++ b/docs/user-guide/nginx-configuration/index.md @@ -4,4 +4,4 @@ There are three ways to customize NGINX: 1. [ConfigMap](./configmap.md): using a Configmap to set global configurations in NGINX. 2. [Annotations](./annotations.md): use this if you want a specific configuration for a particular Ingress rule. -3. [Custom template](./custom-template.md): when more specific settings are required, like [open_file_cache](http://nginx.org/en/docs/http/ngx_http_core_module.html#open_file_cache), adjust [listen](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen) options as `rcvbuf` or when is not possible to change the configuration through the ConfigMap. +3. [Custom template](./custom-template.md): when more specific settings are required, like [open_file_cache](https://nginx.org/en/docs/http/ngx_http_core_module.html#open_file_cache), adjust [listen](https://nginx.org/en/docs/http/ngx_http_core_module.html#listen) options as `rcvbuf` or when is not possible to change the configuration through the ConfigMap. diff --git a/docs/user-guide/nginx-configuration/log-format.md b/docs/user-guide/nginx-configuration/log-format.md index 4a8a45755..9a7506480 100644 --- a/docs/user-guide/nginx-configuration/log-format.md +++ b/docs/user-guide/nginx-configuration/log-format.md @@ -43,5 +43,5 @@ Additional available variables: Sources: -- [Upstream variables](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#variables) -- [Embedded variables](http://nginx.org/en/docs/http/ngx_http_core_module.html#variables) +- [Upstream variables](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#variables) +- [Embedded variables](https://nginx.org/en/docs/http/ngx_http_core_module.html#variables) diff --git a/docs/user-guide/third-party-addons/opentracing.md b/docs/user-guide/third-party-addons/opentracing.md index 468be24f7..6ed0f195e 100644 --- a/docs/user-guide/third-party-addons/opentracing.md +++ b/docs/user-guide/third-party-addons/opentracing.md @@ -173,7 +173,7 @@ In the Zipkin interface we can see the details: 3. Apply a basic Service and Ingress Resource: ``` # Create Echoheaders Deployment - $ kubectl run echoheaders --image=k8s.gcr.io/echoserver:1.4 --replicas=1 --port=8080 + $ kubectl run echoheaders --image=registry.k8s.io/echoserver:1.4 --replicas=1 --port=8080 # Expose as a Cluster-IP $ kubectl expose deployment echoheaders --port=80 --target-port=8080 --name=echoheaders-x diff --git a/docs/user-guide/tls.md b/docs/user-guide/tls.md index 8a18069d4..3d5234c0c 100644 --- a/docs/user-guide/tls.md +++ b/docs/user-guide/tls.md @@ -28,7 +28,7 @@ Ensure that the relevant [ingress rules specify a matching host name](https://ku ## Default SSL Certificate NGINX provides the option to configure a server as a catch-all with -[server_name](http://nginx.org/en/docs/http/server_names.html) +[server_name](https://nginx.org/en/docs/http/server_names.html) for requests that do not match any of the configured server names. This configuration works out-of-the-box for HTTP traffic. For HTTPS, a certificate is naturally required. diff --git a/go.mod b/go.mod index 0def711f4..4827e2b26 100644 --- a/go.mod +++ b/go.mod @@ -1,50 +1,51 @@ module k8s.io/ingress-nginx -go 1.17 +go 1.18 require ( github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a github.com/eapache/channels v1.1.0 - github.com/fsnotify/fsnotify v1.5.1 + github.com/fsnotify/fsnotify v1.5.4 github.com/gavv/httpexpect/v2 v2.3.1 - github.com/imdario/mergo v0.3.12 + github.com/imdario/mergo v0.3.13 github.com/json-iterator/go v1.1.12 github.com/kylelemons/godebug v1.1.0 github.com/mitchellh/go-ps v1.0.0 github.com/mitchellh/hashstructure v1.1.0 - github.com/mitchellh/mapstructure v1.4.3 + github.com/mitchellh/mapstructure v1.5.0 github.com/moul/pb v0.0.0-20180404114147-54bdd96e6a52 github.com/ncabatoff/process-exporter v0.7.10 - github.com/onsi/ginkgo v1.16.4 - github.com/opencontainers/runc v1.1.0 + github.com/onsi/ginkgo v1.16.5 + github.com/opencontainers/runc v1.1.3 github.com/pmezard/go-difflib v1.0.0 - github.com/prometheus/client_golang v1.12.1 + github.com/prometheus/client_golang v1.12.2 github.com/prometheus/client_model v0.2.0 - github.com/prometheus/common v0.32.1 - github.com/spf13/cobra v1.3.0 + github.com/prometheus/common v0.35.0 + github.com/spf13/cobra v1.4.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.7.1 + github.com/stretchr/testify v1.7.2 github.com/zakjan/cert-chain-resolver v0.0.0-20211122211144-c6b0b792af9a golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 - golang.org/x/net v0.0.0-20211209124913-491a49abca63 - google.golang.org/grpc v1.44.0 + golang.org/x/net v0.0.0-20220225172249-27dd8689420f + google.golang.org/grpc v1.47.0 gopkg.in/go-playground/pool.v3 v3.1.1 - k8s.io/api v0.22.5 - k8s.io/apiextensions-apiserver v0.22.5 - k8s.io/apimachinery v0.22.5 - k8s.io/apiserver v0.22.5 - k8s.io/cli-runtime v0.22.5 - k8s.io/client-go v0.22.5 - k8s.io/code-generator v0.22.5 - k8s.io/component-base v0.22.5 - k8s.io/klog/v2 v2.9.0 + gopkg.in/mcuadros/go-syslog.v2 v2.3.0 + k8s.io/api v0.23.6 + k8s.io/apiextensions-apiserver v0.23.5 + k8s.io/apimachinery v0.23.6 + k8s.io/apiserver v0.23.5 + k8s.io/cli-runtime v0.23.5 + k8s.io/client-go v0.23.6 + k8s.io/code-generator v0.23.5 + k8s.io/component-base v0.23.6 + k8s.io/klog/v2 v2.60.1 pault.ag/go/sniff v0.0.0-20200207005214-cf7e4d167732 - sigs.k8s.io/controller-runtime v0.10.3 + sigs.k8s.io/controller-runtime v0.11.2 sigs.k8s.io/mdtoc v1.1.0 ) require ( - cloud.google.com/go v0.99.0 // indirect + cloud.google.com/go v0.81.0 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.18 // indirect github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect @@ -64,12 +65,12 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/eapache/queue v1.1.0 // indirect github.com/emicklei/go-restful v2.9.5+incompatible // indirect - github.com/evanphx/json-patch v4.11.0+incompatible // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fatih/structs v1.0.0 // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/fullsailor/pkcs7 v0.0.0-20160414161337-2585af45975b // indirect github.com/go-errors/errors v1.0.1 // indirect - github.com/go-logr/logr v0.4.0 // indirect + github.com/go-logr/logr v1.2.0 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.19.5 // indirect github.com/go-openapi/swag v0.19.14 // indirect @@ -117,28 +118,29 @@ require ( github.com/yudai/gojsondiff v1.0.0 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect - golang.org/x/mod v0.5.0 // indirect - golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect - golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect - golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect + golang.org/x/mod v0.4.2 // indirect + golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect + golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect - golang.org/x/tools v0.1.5 // indirect + golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2 // indirect + google.golang.org/protobuf v1.28.0 // indirect gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect - k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 // indirect - k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c // indirect - k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c // indirect + k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect + k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e // indirect - sigs.k8s.io/kustomize/api v0.8.11 // indirect - sigs.k8s.io/kustomize/kyaml v0.11.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect - sigs.k8s.io/yaml v1.2.0 // indirect + sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect + sigs.k8s.io/kustomize/api v0.10.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.13.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index f82322a19..9b69b1c95 100644 --- a/go.sum +++ b/go.sum @@ -17,17 +17,8 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= -cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -37,7 +28,6 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -67,7 +57,6 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -85,14 +74,13 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/andybalholm/brotli v1.0.2 h1:JKnhI/XQ75uFBTiuzXpzFrUriDPiZjlOSzh6wXogP0E= github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a h1:AP/vsCIvJZ129pdm9Ek7bH7yutN3hByqsMoNrWAxRQc= github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -102,13 +90,12 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= @@ -118,19 +105,15 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= @@ -141,7 +124,6 @@ github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -176,18 +158,14 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= -github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fasthttp/websocket v1.4.3-rc.6 h1:omHqsl8j+KXpmzRjF8bmzOSYJ8GnS0E3efi1wYT+niY= github.com/fasthttp/websocket v1.4.3-rc.6/go.mod h1:43W9OM2T8FeXpCWMsBd9Cb7nE2CACNqNvCqQCoty/Lc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.0.0 h1:BrX964Rv5uQ3wwS+KRUAJCBBw5PQmgJfJ6v4yly5QwU= github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= @@ -197,12 +175,13 @@ github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fullsailor/pkcs7 v0.0.0-20160414161337-2585af45975b h1:074/xhloHUBOpTZwlIzQ28rbPY8pNJvzY7Gcx5KnNOk= github.com/fullsailor/pkcs7 v0.0.0-20160414161337-2585af45975b/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/gavv/httpexpect/v2 v2.3.1 h1:sGLlKMn8AuHS9ztK9Sb7AJ7OxIL8v2PcLdyxfKt1Fo4= github.com/gavv/httpexpect/v2 v2.3.1/go.mod h1:yOE8m/aqFYQDNrgprMeXgq4YynfN9h1NgcE1+1suV64= +github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= @@ -213,15 +192,17 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM= -github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk= +github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -242,6 +223,7 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -256,7 +238,6 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -282,6 +263,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/cel-go v0.9.0/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= +github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -303,7 +286,6 @@ github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -315,9 +297,6 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -327,12 +306,11 @@ github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -344,23 +322,13 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -368,37 +336,27 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/imkira/go-interpol v1.0.0 h1:HrmLyvOLJyjR0YofMw8QGdCIuYOs4TJUBDNU5sJC09E= github.com/imkira/go-interpol v1.0.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -432,7 +390,6 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -442,27 +399,16 @@ github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7 github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= @@ -474,8 +420,9 @@ github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mmarkdown/mmark v2.0.40+incompatible h1:vMeUeDzBK3H+/mU0oMVfMuhSXJlIA+DE/DMPQNAj5C4= github.com/mmarkdown/mmark v2.0.40+incompatible/go.mod h1:Uvmoz7tvsWpr7bMVxIpqZPyN3FbOtzDmnsJDFp7ltJs= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= @@ -514,24 +461,22 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= -github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= -github.com/opencontainers/runc v1.1.0 h1:O9+X96OcDjkmmZyfaG996kV7yq8HsoU2h1XRRQcefG8= -github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= +github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE= +github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= +github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -543,16 +488,15 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -561,17 +505,17 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.35.0 h1:Eyr+Pw2VymWejHqCugNaQXkAi6KayVNxaHeu6khmFBE= +github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/exporter-toolkit v0.7.0/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= @@ -586,11 +530,10 @@ github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6po github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/savsgio/gotils v0.0.0-20210617111740-97865ed5a873 h1:N3Af8f13ooDKcIhsmFT7Z05CStZWu4C7Md0uDEy4q6o= github.com/savsgio/gotils v0.0.0-20210617111740-97865ed5a873/go.mod h1:dmPawKuiAeG/aFYVs2i+Dyosoo7FNcm+Pi8iK6ZUrX8= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= @@ -608,14 +551,14 @@ github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0= -github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -624,7 +567,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -637,13 +580,12 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v1.17.1-0.20160602030128-01a33823596e/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -677,16 +619,14 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zakjan/cert-chain-resolver v0.0.0-20211122211144-c6b0b792af9a h1:CbXWHAnmrtTKgX+yMVVANuRJP8ld88ELbAYAYnBdLJ4= github.com/zakjan/cert-chain-resolver v0.0.0-20211122211144-c6b0b792af9a/go.mod h1:/Hzu8ych2oXCs1iNI+MeASyFzWTncQ6nlu/wgqbqC2A= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= @@ -721,8 +661,8 @@ go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -730,11 +670,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= @@ -773,9 +711,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -796,7 +733,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -822,15 +758,14 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -842,13 +777,11 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -879,12 +812,9 @@ golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -892,9 +822,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -920,7 +848,6 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -930,28 +857,21 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -985,7 +905,6 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1025,19 +944,16 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff h1:VX/uD7MK0AHXGiScH3fsieUQUcpmRERPDYtqZdJnA+Q= +golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= -gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1059,17 +975,7 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1111,6 +1017,7 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1120,30 +1027,9 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2 h1:NHN4wOCScVzKhPenJ2dt+BTs3X/XkBVI/Rh4iDt55T8= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1165,16 +1051,10 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1187,8 +1067,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1205,7 +1086,9 @@ gopkg.in/go-playground/pool.v3 v3.1.1/go.mod h1:pUAGBximS/hccTTSzEop6wvvQhVa3QPD gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mcuadros/go-syslog.v2 v2.3.0 h1:kcsiS+WsTKyIEPABJBJtoG0KkOS6yzvJ+/eZlhD79kk= +gopkg.in/mcuadros/go-syslog.v2 v2.3.0/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -1223,8 +1106,10 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1234,41 +1119,40 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= -k8s.io/api v0.22.5 h1:xk7C+rMjF/EGELiD560jdmwzrB788mfcHiNbMQLIVI8= -k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= -k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA= -k8s.io/apiextensions-apiserver v0.22.5 h1:ML0QqT7FIlmZHN+9+2EtARJ3cJVHeoizt6GCteFRE0o= -k8s.io/apiextensions-apiserver v0.22.5/go.mod h1:tIXeZ0BrDxUb1PoAz+tgOz43Zi1Bp4BEEqVtUccMJbE= -k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= -k8s.io/apimachinery v0.22.5 h1:cIPwldOYm1Slq9VLBRPtEYpyhjIm1C6aAMAoENuvN9s= -k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= -k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI= -k8s.io/apiserver v0.22.5 h1:71krQxCUz218ecb+nPhfDsNB6QgP1/4EMvi1a2uYBlg= -k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ= -k8s.io/cli-runtime v0.22.5 h1:bZqLgx1INiPgXyMk/Hu3o5NFmdfvlvtsoE+wHJuKA2U= -k8s.io/cli-runtime v0.22.5/go.mod h1:12ah4O0kaevIYHsRcFGt8RKER0wlTN2yCgHp1c4Uxp4= -k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U= -k8s.io/client-go v0.22.5 h1:I8Zn/UqIdi2r02aZmhaJ1hqMxcpfJ3t5VqvHtctHYFo= -k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y= -k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= -k8s.io/code-generator v0.22.5 h1:jn+mYXI5q7rzo7Bz/n8xZIgbe61SeXlIjU5jA8jLVps= -k8s.io/code-generator v0.22.5/go.mod h1:sbdWCOVob+KaQ5O7xs8PNNaCTpbWVqNgA6EPwLOmRNk= -k8s.io/component-base v0.22.2/go.mod h1:5Br2QhI9OTe79p+TzPe9JKNQYvEKbq9rTJDWllunGug= -k8s.io/component-base v0.22.5 h1:U0eHqZm7mAFE42hFwYhY6ze/MmVaW00JpMrzVsQmzYE= -k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= +k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8= +k8s.io/api v0.23.6 h1:yOK34wbYECH4RsJbQ9sfkFK3O7f/DUHRlzFehkqZyVw= +k8s.io/api v0.23.6/go.mod h1:1kFaYxGCFHYp3qd6a85DAj/yW8aVD6XLZMqJclkoi9g= +k8s.io/apiextensions-apiserver v0.23.5 h1:5SKzdXyvIJKu+zbfPc3kCbWpbxi+O+zdmAJBm26UJqI= +k8s.io/apiextensions-apiserver v0.23.5/go.mod h1:ntcPWNXS8ZPKN+zTXuzYMeg731CP0heCTl6gYBxLcuQ= +k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= +k8s.io/apimachinery v0.23.6 h1:RH1UweWJkWNTlFx0D8uxOpaU1tjIOvVVWV/bu5b3/NQ= +k8s.io/apimachinery v0.23.6/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= +k8s.io/apiserver v0.23.5 h1:2Ly8oUjz5cnZRn1YwYr+aFgDZzUmEVL9RscXbnIeDSE= +k8s.io/apiserver v0.23.5/go.mod h1:7wvMtGJ42VRxzgVI7jkbKvMbuCbVbgsWFT7RyXiRNTw= +k8s.io/cli-runtime v0.23.5 h1:Z7XUpGoJZYZB2uNjQfJjMbyDKyVkoBGye62Ap0sWQHY= +k8s.io/cli-runtime v0.23.5/go.mod h1:oY6QDF2qo9xndSq32tqcmRp2UyXssdGrLfjAVymgbx4= +k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4= +k8s.io/client-go v0.23.6 h1:7h4SctDVQAQbkHQnR4Kzi7EyUyvla5G1pFWf4+Od7hQ= +k8s.io/client-go v0.23.6/go.mod h1:Umt5icFOMLV/+qbtZ3PR0D+JA6lvvb3syzodv4irpK4= +k8s.io/code-generator v0.23.5 h1:xn3a6J5pUL49AoH6SPrOFtnB5cvdMl76f/bEY176R3c= +k8s.io/code-generator v0.23.5/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk= +k8s.io/component-base v0.23.5/go.mod h1:c5Nq44KZyt1aLl0IpHX82fhsn84Sb0jjzwjpcA42bY0= +k8s.io/component-base v0.23.6 h1:8dhVZ4VrRcNdV2EGjl8tj8YOHwX6ysgCGMJ2Oyy0NW8= +k8s.io/component-base v0.23.6/go.mod h1:FGMPeMrjYu0UZBSAFcfloVDplj9IvU+uRMTOdE23Fj0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027 h1:Uusb3oh8XcdzDF/ndlI4ToKTYVlkCSJP39SRY2mfRAw= -k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c h1:GohjlNKauSai7gN4wsJkeZ3WAJx4Sh+oT/b5IYn5suA= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= -k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc= +k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c h1:jvamsI1tn9V0S8jicyX82qaFC0H/NKxv2e5mbqsgR80= -k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a h1:8dYfu/Fc9Gz2rNJKB9IQRGgQOh2clmRzNIPPY1xLY5g= -k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20211116205334-6203023598ed h1:ck1fRPWPJWsMd8ZRFsWc6mh/zHp5fZ/shhbrgPUxDAE= +k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e/go.mod h1:nejbQVfXh96n9dSF6cH3Jsk/QI1Z2oEL7sSI2ifXFNA= pault.ag/go/sniff v0.0.0-20200207005214-cf7e4d167732 h1:SAElp8THCfmBdM+4lmWX5gebiSSkEr7PAYDVF91qpfg= @@ -1276,17 +1160,20 @@ pault.ag/go/sniff v0.0.0-20200207005214-cf7e4d167732/go.mod h1:lpvCfhqEHNJSSpG5R rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/controller-runtime v0.10.3 h1:s5Ttmw/B4AuIbwrXD3sfBkXwnPMMWrqpVj4WRt1dano= -sigs.k8s.io/controller-runtime v0.10.3/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY= -sigs.k8s.io/kustomize/api v0.8.11 h1:LzQzlq6Z023b+mBtc6v72N2mSHYmN8x7ssgbf/hv0H8= -sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g= -sigs.k8s.io/kustomize/kyaml v0.11.0 h1:9KhiCPKaVyuPcgOLJXkvytOvjMJLoxpjodiycb4gHsA= -sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= +sigs.k8s.io/controller-runtime v0.11.2 h1:H5GTxQl0Mc9UjRJhORusqfJCIjBO8UtUxGggCwL1rLA= +sigs.k8s.io/controller-runtime v0.11.2/go.mod h1:P6QCzrEjLaZGqHsfd+os7JQ+WFZhvB8MRFsn4dWF7O4= +sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s= +sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= +sigs.k8s.io/kustomize/api v0.10.1 h1:KgU7hfYoscuqag84kxtzKdEC3mKMb99DPI3a0eaV1d0= +sigs.k8s.io/kustomize/api v0.10.1/go.mod h1:2FigT1QN6xKdcnGS2Ppp1uIWrtWN28Ms8A3OZUZhwr8= +sigs.k8s.io/kustomize/kyaml v0.13.0 h1:9c+ETyNfSrVhxvphs+K2dzT3dh5oVPPEqPOE/cUpScY= +sigs.k8s.io/kustomize/kyaml v0.13.0/go.mod h1:FTJxEZ86ScK184NpGSAQcfEqee0nul8oLCK30D47m4E= sigs.k8s.io/mdtoc v1.1.0 h1:q3YtqYzmC2e0hgLXRIOm7/QLuPux1CX3ZHCwlbABxZo= sigs.k8s.io/mdtoc v1.1.0/go.mod h1:QZLVEdHH2iNIR4uHAZyvFRtjloHgVItk8lo/mzCtq3w= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= -sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= +sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/hack/.tool-versions b/hack/.tool-versions index 5baa8790a..4bd118c7b 100644 --- a/hack/.tool-versions +++ b/hack/.tool-versions @@ -1,2 +1,2 @@ -kustomize 4.1.3 -helm 3.7.1 +kustomize 4.5.4 +helm 3.8.2 diff --git a/hack/generate-e2e-suite-doc.sh b/hack/generate-e2e-suite-doc.sh index c5545945e..2265bb079 100755 --- a/hack/generate-e2e-suite-doc.sh +++ b/hack/generate-e2e-suite-doc.sh @@ -25,9 +25,12 @@ set -o pipefail URL="https://github.com/kubernetes/ingress-nginx/tree/main/" DIR=$(cd $(dirname "${BASH_SOURCE}")/.. && pwd -P) -echo " +echo " -# e2e test suite for [NGINX Ingress Controller]($URL) +# e2e test suite for [Ingress NGINX Controller]($URL) " @@ -37,7 +40,7 @@ for FILE in `find $DIR/test/e2e -name "*.go"`;do # line number DESCRIBE_LINE=$(echo $DESCRIBE | cut -f1 -d ':') # clean describe, extracting the string - DESCRIBE=$(echo $DESCRIBE | sed -En 's/.*"(.*)".*/\1/p') + DESCRIBE=$(echo $DESCRIBE | sed -En 's/.*("|`)(.*)("|`).*/\2/p') FILE_URL=$(echo $FILE | sed "s|${DIR}/|${URL}|g") echo " @@ -48,7 +51,7 @@ for FILE in `find $DIR/test/e2e -name "*.go"`;do ITS=$(cat $FILE | grep -n -oP 'It\(.*') while IFS= read -r line; do IT_LINE=$(echo $line | cut -f1 -d ':') - IT=$(echo $line | sed -En 's/.*"(.*)".*/\1/p') + IT=$(echo $line | sed -En 's/.*("|`)(.*)("|`).*/\2/p') echo "- [$IT]($FILE_URL#L$IT_LINE)" done <<< "$ITS" done diff --git a/hack/manifest-templates/provider/kind/values.yaml b/hack/manifest-templates/provider/kind/values.yaml index f327c351e..ed636f372 100644 --- a/hack/manifest-templates/provider/kind/values.yaml +++ b/hack/manifest-templates/provider/kind/values.yaml @@ -17,6 +17,9 @@ controller: - key: "node-role.kubernetes.io/master" operator: "Equal" effect: "NoSchedule" + - key: "node-role.kubernetes.io/control-plane" + operator: "Equal" + effect: "NoSchedule" publishService: enabled: false diff --git a/images/custom-error-pages/rootfs/Dockerfile b/images/custom-error-pages/rootfs/Dockerfile index cdceb032b..d53228201 100755 --- a/images/custom-error-pages/rootfs/Dockerfile +++ b/images/custom-error-pages/rootfs/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.17-alpine as builder +FROM golang:1.18.2-alpine as builder RUN apk add git WORKDIR /go/src/k8s.io/ingress-nginx/images/custom-error-pages diff --git a/images/custom-error-pages/rootfs/go.mod b/images/custom-error-pages/rootfs/go.mod index 3040c5791..05bd45400 100644 --- a/images/custom-error-pages/rootfs/go.mod +++ b/images/custom-error-pages/rootfs/go.mod @@ -1,17 +1,17 @@ module k8s.io/ingress-nginx/custom-error-pages -go 1.17 +go 1.18 require github.com/prometheus/client_golang v1.11.0 require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect - github.com/golang/protobuf v1.4.3 // indirect + github.com/golang/protobuf v1.5.0 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.26.0 // indirect github.com/prometheus/procfs v0.6.0 // indirect golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 // indirect - google.golang.org/protobuf v1.26.0-rc.1 // indirect + google.golang.org/protobuf v1.28.0 // indirect ) diff --git a/images/custom-error-pages/rootfs/go.sum b/images/custom-error-pages/rootfs/go.sum index 6a42e5c54..87cd96b26 100644 --- a/images/custom-error-pages/rootfs/go.sum +++ b/images/custom-error-pages/rootfs/go.sum @@ -29,8 +29,9 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -126,8 +127,9 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/images/echo/Makefile b/images/echo/Makefile index 01d532731..fb53283f7 100644 --- a/images/echo/Makefile +++ b/images/echo/Makefile @@ -36,7 +36,7 @@ build: ensure-buildx --platform=${PLATFORMS} $(OUTPUT) \ --progress=$(PROGRESS) \ --pull \ - --build-arg BASE_IMAGE=k8s.gcr.io/ingress-nginx/nginx:5402d35663917ccbbf77ff48a22b8c6f77097f48@sha256:ec8a104df307f5c6d68157b7ac8e5e1e2c2f0ea07ddf25bb1c6c43c67e351180 \ + --build-arg BASE_IMAGE=registry.k8s.io/ingress-nginx/nginx:cd6f88af3f976a180ed966dadf273473ae768dfa@sha256:18f91105e4099941d2efee71a8ec52c6ef7702d5f7e8214b7cb5f25cc10a0b41 \ --build-arg LUAROCKS_VERSION=3.8.0 \ --build-arg LUAROCKS_SHA=ab6612ca9ab87c6984871d2712d05525775e8b50172701a0a1cabddf76de2be7 \ -t $(IMAGE):$(TAG) rootfs diff --git a/images/ext-auth-example-authsvc/rootfs/Dockerfile b/images/ext-auth-example-authsvc/rootfs/Dockerfile index ee2737286..9a52919be 100644 --- a/images/ext-auth-example-authsvc/rootfs/Dockerfile +++ b/images/ext-auth-example-authsvc/rootfs/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17.6-alpine3.15 as builder +FROM golang:1.18.2-alpine3.15 as builder RUN mkdir /authsvc WORKDIR /authsvc COPY . ./ @@ -7,4 +7,4 @@ RUN CGO_ENABLED=0 GOOS=linux go build -o authsvc authsvc.go FROM gcr.io/distroless/base-debian11 COPY --from=builder /authsvc/authsvc / EXPOSE 8080 -ENTRYPOINT ["/authsvc"] \ No newline at end of file +ENTRYPOINT ["/authsvc"] diff --git a/images/ext-auth-example-authsvc/rootfs/go.mod b/images/ext-auth-example-authsvc/rootfs/go.mod index 72f2a1049..052d17d6f 100644 --- a/images/ext-auth-example-authsvc/rootfs/go.mod +++ b/images/ext-auth-example-authsvc/rootfs/go.mod @@ -1,8 +1,7 @@ module example.com/authsvc -go 1.17 +go 1.18 -require ( - github.com/google/uuid v1.1.2 // indirect - k8s.io/apimachinery v0.23.1 // indirect -) +require k8s.io/apimachinery v0.23.1 + +require github.com/google/uuid v1.1.2 // indirect diff --git a/images/httpbin/rootfs/Dockerfile b/images/httpbin/rootfs/Dockerfile index 9ef9ccc2b..113aaaa0d 100644 --- a/images/httpbin/rootfs/Dockerfile +++ b/images/httpbin/rootfs/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.13 +FROM alpine:3.14.6 ENV LC_ALL=C.UTF-8 ENV LANG=C.UTF-8 diff --git a/images/kube-webhook-certgen/rootfs/Dockerfile b/images/kube-webhook-certgen/rootfs/Dockerfile index f9020fa41..4a60ed2ea 100644 --- a/images/kube-webhook-certgen/rootfs/Dockerfile +++ b/images/kube-webhook-certgen/rootfs/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=$BUILDPLATFORM golang:1.16 as builder +FROM --platform=$BUILDPLATFORM golang:1.18.2 as builder ARG BUILDPLATFORM ARG TARGETARCH diff --git a/images/kube-webhook-certgen/rootfs/go.mod b/images/kube-webhook-certgen/rootfs/go.mod index edd74bea3..3858ae566 100644 --- a/images/kube-webhook-certgen/rootfs/go.mod +++ b/images/kube-webhook-certgen/rootfs/go.mod @@ -1,14 +1,48 @@ module github.com/jet/kube-webhook-certgen -go 1.16 +go 1.18 require ( github.com/onrik/logrus v0.9.0 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.1.3 - github.com/tidwall/gjson v1.14.0 // indirect k8s.io/api v0.22.6 k8s.io/apimachinery v0.22.6 k8s.io/client-go v0.22.6 k8s.io/kube-aggregator v0.22.6 ) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/evanphx/json-patch v4.11.0+incompatible // indirect + github.com/go-logr/logr v0.4.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.5 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/googleapis/gnostic v0.5.5 // indirect + github.com/imdario/mergo v0.3.5 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/json-iterator/go v1.1.11 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/tidwall/gjson v1.14.0 // indirect + golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect + golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect + golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect + golang.org/x/text v0.3.6 // indirect + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + google.golang.org/appengine v1.6.5 // indirect + google.golang.org/protobuf v1.26.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + k8s.io/klog/v2 v2.9.0 // indirect + k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c // indirect + k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + sigs.k8s.io/yaml v1.2.0 // indirect +) diff --git a/images/nginx/README.md b/images/nginx/README.md index 8bd1469dd..5966a4fa1 100644 --- a/images/nginx/README.md +++ b/images/nginx/README.md @@ -20,6 +20,6 @@ This image provides a default configuration file with no backend servers. _Using docker_ ```console -docker run -v /some/nginx.conf:/etc/nginx/nginx.conf:ro k8s.gcr.io/ingress-nginx/nginx:5402d35663917ccbbf77ff48a22b8c6f77097f48@sha256:ec8a104df307f5c6d68157b7ac8e5e1e2c2f0ea07ddf25bb1c6c43c67e351180 +docker run -v /some/nginx.conf:/etc/nginx/nginx.conf:ro registry.k8s.io/ingress-nginx/nginx:cd6f88af3f976a180ed966dadf273473ae768dfa@sha256:18f91105e4099941d2efee71a8ec52c6ef7702d5f7e8214b7cb5f25cc10a0b41 ``` diff --git a/images/nginx/rc.yaml b/images/nginx/rc.yaml index cf9c59d15..632e62cdc 100644 --- a/images/nginx/rc.yaml +++ b/images/nginx/rc.yaml @@ -38,7 +38,7 @@ spec: spec: containers: - name: nginx - image: k8s.gcr.io/ingress-nginx/nginx:5402d35663917ccbbf77ff48a22b8c6f77097f48@sha256:ec8a104df307f5c6d68157b7ac8e5e1e2c2f0ea07ddf25bb1c6c43c67e351180 + image: registry.k8s.io/ingress-nginx/nginx:cd6f88af3f976a180ed966dadf273473ae768dfa@sha256:18f91105e4099941d2efee71a8ec52c6ef7702d5f7e8214b7cb5f25cc10a0b41 ports: - containerPort: 80 - containerPort: 443 diff --git a/images/nginx/rootfs/Dockerfile b/images/nginx/rootfs/Dockerfile index ccf70f143..75c63cff1 100644 --- a/images/nginx/rootfs/Dockerfile +++ b/images/nginx/rootfs/Dockerfile @@ -11,7 +11,7 @@ # 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. -FROM alpine:3.14.4 as builder +FROM alpine:3.14.6 as builder COPY . / @@ -21,7 +21,7 @@ RUN apk update \ && /build.sh # Use a multi-stage build -FROM alpine:3.14.4 +FROM alpine:3.14.6 ENV PATH=$PATH:/usr/local/luajit/bin:/usr/local/nginx/sbin:/usr/local/nginx/bin diff --git a/images/nginx/rootfs/patches/drop-alias-root.patch b/images/nginx/rootfs/patches/drop-alias-root.patch new file mode 100644 index 000000000..a92e08bd0 --- /dev/null +++ b/images/nginx/rootfs/patches/drop-alias-root.patch @@ -0,0 +1,144 @@ +:100644 100644 c7463dcd 00000000 M src/http/ngx_http_core_module.c +diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c +index c7463dcd..e2e45931 100644 +--- a/src/http/ngx_http_core_module.c ++++ b/src/http/ngx_http_core_module.c +@@ -55,7 +55,6 @@ static char *ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); + static char *ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +-static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); + static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); + static char *ngx_http_core_set_aio(ngx_conf_t *cf, ngx_command_t *cmd, +@@ -323,21 +322,6 @@ static ngx_command_t ngx_http_core_commands[] = { + offsetof(ngx_http_core_loc_conf_t, default_type), + NULL }, + +- { ngx_string("root"), +- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF +- |NGX_CONF_TAKE1, +- ngx_http_core_root, +- NGX_HTTP_LOC_CONF_OFFSET, +- 0, +- NULL }, +- +- { ngx_string("alias"), +- NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, +- ngx_http_core_root, +- NGX_HTTP_LOC_CONF_OFFSET, +- 0, +- NULL }, +- + { ngx_string("limit_except"), + NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE, + ngx_http_core_limit_except, +@@ -4312,108 +4296,6 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) + } + + +-static char * +-ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +-{ +- ngx_http_core_loc_conf_t *clcf = conf; +- +- ngx_str_t *value; +- ngx_int_t alias; +- ngx_uint_t n; +- ngx_http_script_compile_t sc; +- +- alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0; +- +- if (clcf->root.data) { +- +- if ((clcf->alias != 0) == alias) { +- return "is duplicate"; +- } +- +- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, +- "\"%V\" directive is duplicate, " +- "\"%s\" directive was specified earlier", +- &cmd->name, clcf->alias ? "alias" : "root"); +- +- return NGX_CONF_ERROR; +- } +- +- if (clcf->named && alias) { +- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, +- "the \"alias\" directive cannot be used " +- "inside the named location"); +- +- return NGX_CONF_ERROR; +- } +- +- value = cf->args->elts; +- +- if (ngx_strstr(value[1].data, "$document_root") +- || ngx_strstr(value[1].data, "${document_root}")) +- { +- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, +- "the $document_root variable cannot be used " +- "in the \"%V\" directive", +- &cmd->name); +- +- return NGX_CONF_ERROR; +- } +- +- if (ngx_strstr(value[1].data, "$realpath_root") +- || ngx_strstr(value[1].data, "${realpath_root}")) +- { +- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, +- "the $realpath_root variable cannot be used " +- "in the \"%V\" directive", +- &cmd->name); +- +- return NGX_CONF_ERROR; +- } +- +- clcf->alias = alias ? clcf->name.len : 0; +- clcf->root = value[1]; +- +- if (!alias && clcf->root.len > 0 +- && clcf->root.data[clcf->root.len - 1] == '/') +- { +- clcf->root.len--; +- } +- +- if (clcf->root.data[0] != '$') { +- if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) { +- return NGX_CONF_ERROR; +- } +- } +- +- n = ngx_http_script_variables_count(&clcf->root); +- +- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); +- sc.variables = n; +- +-#if (NGX_PCRE) +- if (alias && clcf->regex) { +- clcf->alias = NGX_MAX_SIZE_T_VALUE; +- n = 1; +- } +-#endif +- +- if (n) { +- sc.cf = cf; +- sc.source = &clcf->root; +- sc.lengths = &clcf->root_lengths; +- sc.values = &clcf->root_values; +- sc.complete_lengths = 1; +- sc.complete_values = 1; +- +- if (ngx_http_script_compile(&sc) != NGX_OK) { +- return NGX_CONF_ERROR; +- } +- } +- +- return NGX_CONF_OK; +-} +- +- + static ngx_http_method_name_t ngx_methods_names[] = { + { (u_char *) "GET", (uint32_t) ~NGX_HTTP_GET }, + { (u_char *) "HEAD", (uint32_t) ~NGX_HTTP_HEAD }, diff --git a/images/opentelemetry/rootfs/CMakeLists.txt b/images/opentelemetry/rootfs/CMakeLists.txt new file mode 100644 index 000000000..7278016a0 --- /dev/null +++ b/images/opentelemetry/rootfs/CMakeLists.txt @@ -0,0 +1,95 @@ +#!/bin/bash + +# Copyright 2021 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. + +cmake_minimum_required(VERSION 3.11 FATAL_ERROR) + +project( + dependencies + LANGUAGES CXX + VERSION 0.0.1) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_FLAGS "-O2") + +set(CMAKE_BUILD_TYPE + Release + CACHE STRING "Build type" FORCE) + +include(GNUInstallDirs) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) + +set(INSTALL_LIBDIR + ${CMAKE_INSTALL_LIBDIR} + CACHE PATH "directory for libraries") +set(INSTALL_BINDIR + ${CMAKE_INSTALL_BINDIR} + CACHE PATH "directory for executables") +set(INSTALL_INCLUDEDIR + ${CMAKE_INSTALL_INCLUDEDIR} + CACHE PATH "directory for header files") + +set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME}) +set(INSTALL_CMAKEDIR + ${DEF_INSTALL_CMAKEDIR} + CACHE PATH "directory for CMake files") + +set_property(DIRECTORY PROPERTY EP_BASE ${CMAKE_BINARY_DIR}/subs) + +set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) +message(STATUS "${PROJECT_NAME} staged install: ${STAGED_INSTALL_PREFIX}") + +find_package(OpenSSL REQUIRED) +message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}") +message("OpenSSL libraries: ${OPENSSL_LIBRARIES}") + +set(GRPC_GIT_TAG + "v1.45.2" + CACHE STRING "gRPC version") + +include(ExternalProject) +ExternalProject_Add( + gRPC + GIT_REPOSITORY https://github.com/grpc/grpc.git + GIT_TAG ${GRPC_GIT_TAG} + GIT_SHALLOW 1 + UPDATE_COMMAND "" + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${STAGED_INSTALL_PREFIX} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DgRPC_SSL_PROVIDER=package + -DOPENSSL_ROOT_DIR=OpenSSL + -DgRPC_BUILD_TESTS=OFF + -DBUILD_SHARED_LIBS=ON + -DgRPC_INSTALL=ON + CMAKE_CACHE_ARGS -DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} + TEST_AFTER_INSTALL 0 + DOWNLOAD_NO_PROGRESS 1 + LOG_CONFIGURE 1 + LOG_BUILD 0 + LOG_INSTALL 1) + +install( + DIRECTORY ${STAGED_INSTALL_PREFIX}/ + DESTINATION . + USE_SOURCE_PERMISSIONS) diff --git a/images/opentelemetry/rootfs/Dockerfile b/images/opentelemetry/rootfs/Dockerfile index 84f5a3e7c..91832fa55 100644 --- a/images/opentelemetry/rootfs/Dockerfile +++ b/images/opentelemetry/rootfs/Dockerfile @@ -13,16 +13,33 @@ # limitations under the License. -FROM alpine:3.14.4 as builder +FROM alpine:3.14.6 as base -COPY . / +RUN mkdir -p /opt/third_party/install +COPY . /opt/third_party/ +# install build tools RUN apk update \ && apk upgrade \ && apk add -U bash \ - && /build.sh + && bash /opt/third_party/build.sh -p -FROM busybox:latest +# install gRPC +FROM base as grpc +RUN bash /opt/third_party/build.sh -g v1.43.2 -COPY --from=builder init_module.sh /usr/local/bin/init_module.sh -COPY --from=builder /etc/nginx/modules /etc/nginx/modules +# install OpenTelemetry-cpp +FROM base as otel-cpp +COPY --from=grpc /opt/third_party/install/ /usr +RUN bash /opt/third_party/build.sh -o v1.3.0 + +# install otel_ngx_module.so +FROM base as nginx +COPY --from=grpc /opt/third_party/install/ /usr +COPY --from=otel-cpp /opt/third_party/install/ /usr +RUN bash /opt/third_party/build.sh -n + +FROM alpine:3.14.6 +COPY --from=base /opt/third_party/init_module.sh /usr/local/bin/init_module.sh +COPY --from=nginx /etc/nginx/modules /etc/nginx/modules +COPY --from=nginx /opt/third_party/install/lib /etc/nginx/modules diff --git a/images/opentelemetry/rootfs/build.sh b/images/opentelemetry/rootfs/build.sh index 67d1e67b2..91298274d 100755 --- a/images/opentelemetry/rootfs/build.sh +++ b/images/opentelemetry/rootfs/build.sh @@ -18,15 +18,12 @@ set -o errexit set -o nounset set -o pipefail -export NGINX_VERSION=1.19.10 - +export GRPC_GIT_TAG=${GRPC_GIT_TAG:="v1.43.2"} # Check for recent changes: https://github.com/open-telemetry/opentelemetry-cpp/compare/v1.2.0...main -export OPENTELEMETRY_CPP_VERSION=1.2.0 - -# Check for recent changes: https://github.com/open-telemetry/opentelemetry-cpp-contrib/compare/2656a4...main -export OPENTELEMETRY_CONTRIB_COMMIT=2656a4072e257b6794da86ddd1b773b49f5517b3 - -export BUILD_PATH=/tmp/build +export OPENTELEMETRY_CPP_VERSION=${OPENTELEMETRY_CPP_VERSION:="1.2.0"} +export INSTAL_DIR=/opt/third_party/install +# improve compilation times +CORES=$(($(grep -c ^processor /proc/cpuinfo) - 1)) rm -rf \ /var/cache/debconf/* \ @@ -35,15 +32,80 @@ rm -rf \ /tmp/* \ /var/tmp/* - -mkdir -p /etc/nginx +export BUILD_PATH=/tmp/build mkdir --verbose -p "$BUILD_PATH" -cd "$BUILD_PATH" -apk add \ - curl \ - git \ - build-base +Help() +{ + # Display Help + echo "Add description of the script functions here." + echo + echo "Syntax: scriptTemplate [-h|g|o|n|p|]" + echo "options:" + echo "h Print Help." + echo "g gRPC git tag" + echo "o OpenTelemetry git tag" + echo "n install nginx" + echo "p prepare" + echo +} + +prepare() +{ + apk add \ + linux-headers \ + openssl \ + curl-dev \ + openssl-dev \ + gtest-dev \ + c-ares-dev \ + pcre-dev \ + curl \ + git \ + build-base +} + +install_grpc() +{ + mkdir -p $BUILD_PATH/grpc + cd ${BUILD_PATH}/grpc + cmake -DCMAKE_INSTALL_PREFIX=${INSTAL_DIR} \ + -DGRPC_GIT_TAG=${GRPC_GIT_TAG} /opt/third_party \ + -DgRPC_BUILD_GRPC_NODE_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_PYTHON_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF + cmake --build . -j ${CORES} --target all install +} + +install_otel() +{ + cd ${BUILD_PATH} + export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+LD_LIBRARY_PATH:}${INSTAL_DIR}/lib:/usr/local" + export PATH="${PATH}:${INSTAL_DIR}/bin" + git clone --recurse-submodules -j ${CORES} --depth=1 -b \ + ${OPENTELEMETRY_CPP_VERSION} https://github.com/open-telemetry/opentelemetry-cpp.git opentelemetry-cpp-${OPENTELEMETRY_CPP_VERSION} + cd "opentelemetry-cpp-${OPENTELEMETRY_CPP_VERSION}" + mkdir -p .build + cd .build + + cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ + -DWITH_ZIPKIN=OFF \ + -DWITH_JAEGER=OFF \ + -DCMAKE_INSTALL_PREFIX=${INSTAL_DIR} \ + -DBUILD_TESTING=OFF \ + -DBUILD_SHARED_LIBS=ON \ + -DWITH_OTLP=ON \ + -DWITH_OTLP_GRPC=ON \ + -DWITH_EXAMPLES=OFF \ + -DWITH_ABSEIL=ON \ + -DWITH_OTLP_HTTP=OFF \ + .. + cmake --build . -j ${CORES} --target install +} get_src() { @@ -53,59 +115,111 @@ get_src() echo "Downloading $url" - curl -sSL "$url" -o "$f" + curl -sSL --fail-with-body "$url" -o "$f" echo "$hash $f" | sha256sum -c - || exit 10 tar xzf "$f" rm -rf "$f" } +install_nginx() +{ + export NGINX_VERSION=1.19.10 -get_src e8d0290ff561986ad7cd6c33307e12e11b137186c4403a6a5ccdb4914c082d88 \ - "https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz" + # Check for recent changes: https://github.com/open-telemetry/opentelemetry-cpp-contrib/compare/2656a4...main + export OPENTELEMETRY_CONTRIB_COMMIT=6467ec2e4d67b08b44580b7eb7a298786f4eef91 -get_src 360cdcbd1a235ec62119cc53956b2d31b6ff5f41d44415be53acc544709d58b8 \ - "https://github.com/open-telemetry/opentelemetry-cpp-contrib/archive/$OPENTELEMETRY_CONTRIB_COMMIT.tar.gz" + mkdir -p /etc/nginx + cd "$BUILD_PATH" -# improve compilation times -CORES=$(($(grep -c ^processor /proc/cpuinfo) - 1)) + # TODO fix curl + # get_src 0528e793a97f942868616449d49326160f9cb67b2253fb2c4864603ac6ab09a9 \ + # "https://github.com/open-telemetry/opentelemetry-cpp-contrib/archive/$OPENTELEMETRY_CONTRIB_COMMIT.tar.gz" -export MAKEFLAGS=-j${CORES} + git clone https://github.com/open-telemetry/opentelemetry-cpp-contrib.git \ + opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT} + cd ${BUILD_PATH}/opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT} + git reset --hard ${OPENTELEMETRY_CONTRIB_COMMIT} + cd ${BUILD_PATH}/opentelemetry-cpp-contrib-${OPENTELEMETRY_CONTRIB_COMMIT}/instrumentation/nginx + mkdir -p build + cd build + cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=${INSTAL_DIR} \ + -DBUILD_SHARED_LIBS=ON \ + -DNGINX_VERSION=${NGINX_VERSION} \ + .. + cmake --build . -j ${CORES} --target install -apk add \ - protobuf-dev \ - grpc \ - grpc-dev \ - gtest-dev \ - c-ares-dev \ - pcre-dev + mkdir -p /etc/nginx/modules + cp ${INSTAL_DIR}/otel_ngx_module.so /etc/nginx/modules/otel_ngx_module.so -cd $BUILD_PATH -git clone --recursive https://github.com/open-telemetry/opentelemetry-cpp opentelemetry-cpp-$OPENTELEMETRY_CPP_VERSION -cd "opentelemetry-cpp-$OPENTELEMETRY_CPP_VERSION" -git checkout v$OPENTELEMETRY_CPP_VERSION -mkdir .build -cd .build + mkdir -p ${INSTAL_DIR}/lib + cp /usr/lib/libopentelemetry_exporter_otlp_grpc.so* ${INSTAL_DIR}/lib + cp /usr/lib/libopentelemetry_otlp_recordable.so* ${INSTAL_DIR}/lib + cp /usr/lib/libprotobuf.so* ${INSTAL_DIR}/lib + cp /usr/lib/libopentelemetry_trace.so* ${INSTAL_DIR}/lib + cp /usr/lib/libopentelemetry_resources.so* ${INSTAL_DIR}/lib + cp /usr/lib/libopentelemetry_common.so* ${INSTAL_DIR}/lib + cp /usr/lib/libstdc++.so* ${INSTAL_DIR}/lib -cmake -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_TESTING=OFF \ - -DWITH_EXAMPLES=OFF \ - -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ - -DWITH_OTLP=ON \ - -DWITH_OTLP_HTTP=OFF \ - .. -make -make install + cp /usr/lib/libgrpc.so* ${INSTAL_DIR}/lib + cp /usr/lib/libgcc_s.so* ${INSTAL_DIR}/lib + cp /usr/lib/libgrpc++.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_bad_variant_access.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_synchronization.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_raw_hash_set.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_hash.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_statusor.so* ${INSTAL_DIR}/lib + cp /usr/lib/libgpr.so* ${INSTAL_DIR}/lib + cp /usr/lib/libupb.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_status.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_time.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_strings.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_stacktrace.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_symbolize.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_malloc_internal.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_base.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_spinlock_wait.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_raw_logging_internal.so* ${INSTAL_DIR}/lib + cp /usr/lib/libre2.so* ${INSTAL_DIR}/lib + cp /usr/lib/libaddress_sorting.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_cord.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_bad_optional_access.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_str_format_internal.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_throw_delegate.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_time_zone.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_city.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_low_level_hash.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_cordz_info.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_int128.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_strings_internal.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_debugging_internal.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_cord_internal.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_cordz_functions.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_cordz_handle.so* ${INSTAL_DIR}/lib + cp /usr/lib/libabsl_exponential_biased.so* ${INSTAL_DIR}/lib +} -# build nginx -cd "$BUILD_PATH/nginx-$NGINX_VERSION" -./configure \ - --prefix=/usr/local/nginx \ - --with-compat \ - --add-dynamic-module=$BUILD_PATH/opentelemetry-cpp-contrib-$OPENTELEMETRY_CONTRIB_COMMIT/instrumentation/nginx - -make modules -mkdir -p /etc/nginx/modules -cp objs/otel_ngx_module.so /etc/nginx/modules/otel_ngx_module.so - -# remove .a files -find /usr/local -name "*.a" -print | xargs /bin/rm +while getopts ":hpng:o:" option; do + case $option in + h) # display Help + Help + exit;; + g) # install gRPC with git tag + GRPC_GIT_TAG=${OPTARG} + install_grpc + exit;; + o) # install OpenTelemetry tag + OPENTELEMETRY_CPP_VERSION=${OPTARG} + install_otel + exit;; + p) # prepare + prepare + exit;; + n) # install nginx + install_nginx + exit;; + \?) + Help + exit;; + esac +done diff --git a/images/test-runner/Makefile b/images/test-runner/Makefile index 038d689b7..1275c7589 100644 --- a/images/test-runner/Makefile +++ b/images/test-runner/Makefile @@ -23,7 +23,7 @@ REGISTRY ?= local IMAGE = $(REGISTRY)/e2e-test-runner -NGINX_BASE_IMAGE ?= k8s.gcr.io/ingress-nginx/nginx:5402d35663917ccbbf77ff48a22b8c6f77097f48@sha256:ec8a104df307f5c6d68157b7ac8e5e1e2c2f0ea07ddf25bb1c6c43c67e351180 +NGINX_BASE_IMAGE ?= registry.k8s.io/ingress-nginx/nginx:cd6f88af3f976a180ed966dadf273473ae768dfa@sha256:18f91105e4099941d2efee71a8ec52c6ef7702d5f7e8214b7cb5f25cc10a0b41 # required to enable buildx export DOCKER_CLI_EXPERIMENTAL=enabled @@ -39,7 +39,7 @@ build: ensure-buildx --progress=$(PROGRESS) \ --pull \ --build-arg BASE_IMAGE=$(NGINX_BASE_IMAGE) \ - --build-arg GOLANG_VERSION=1.17.6 \ + --build-arg GOLANG_VERSION=1.18.2 \ --build-arg ETCD_VERSION=3.4.3-0 \ --build-arg K8S_RELEASE=v1.21.3 \ --build-arg RESTY_CLI_VERSION=0.27 \ diff --git a/images/test-runner/rootfs/Dockerfile b/images/test-runner/rootfs/Dockerfile index e58cf47ad..f7a46b180 100644 --- a/images/test-runner/rootfs/Dockerfile +++ b/images/test-runner/rootfs/Dockerfile @@ -17,7 +17,7 @@ ARG GOLANG_VERSION ARG ETCD_VERSION FROM golang:${GOLANG_VERSION}-alpine as GO -FROM k8s.gcr.io/etcd:${ETCD_VERSION} as etcd +FROM registry.k8s.io/etcd:${ETCD_VERSION} as etcd FROM ${BASE_IMAGE} @@ -49,7 +49,7 @@ ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" -RUN go get github.com/onsi/ginkgo/ginkgo golang.org/x/lint/golint +RUN go install github.com/onsi/ginkgo/ginkgo@v1.16.5 && go install golang.org/x/lint/golint@latest ARG RESTY_CLI_VERSION ARG RESTY_CLI_SHA diff --git a/internal/ingress/annotations/annotations_test.go b/internal/ingress/annotations/annotations_test.go index a253355a2..d792801bc 100644 --- a/internal/ingress/annotations/annotations_test.go +++ b/internal/ingress/annotations/annotations_test.go @@ -39,7 +39,7 @@ var ( annotationCorsExposeHeaders = parser.GetAnnotationWithPrefix("cors-expose-headers") annotationCorsAllowCredentials = parser.GetAnnotationWithPrefix("cors-allow-credentials") defaultCorsMethods = "GET, PUT, POST, DELETE, PATCH, OPTIONS" - defaultCorsHeaders = "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization" + defaultCorsHeaders = "DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" annotationAffinityCookieName = parser.GetAnnotationWithPrefix("session-cookie-name") annotationUpstreamHashBy = parser.GetAnnotationWithPrefix("upstream-hash-by") annotationCustomHTTPErrors = parser.GetAnnotationWithPrefix("custom-http-errors") diff --git a/internal/ingress/annotations/authreq/main.go b/internal/ingress/annotations/authreq/main.go index 36af0e208..b5dc4c70b 100644 --- a/internal/ingress/annotations/authreq/main.go +++ b/internal/ingress/annotations/authreq/main.go @@ -44,12 +44,23 @@ type Config struct { AuthSnippet string `json:"authSnippet"` AuthCacheKey string `json:"authCacheKey"` AuthCacheDuration []string `json:"authCacheDuration"` + KeepaliveConnections int `json:"keepaliveConnections"` + KeepaliveRequests int `json:"keepaliveRequests"` + KeepaliveTimeout int `json:"keepaliveTimeout"` ProxySetHeaders map[string]string `json:"proxySetHeaders,omitempty"` + AlwaysSetCookie bool `json:"alwaysSetCookie,omitempty"` } // DefaultCacheDuration is the fallback value if no cache duration is provided const DefaultCacheDuration = "200 202 401 5m" +// fallback values when no keepalive parameters are set +const ( + defaultKeepaliveConnections = 0 + defaultKeepaliveRequests = 1000 + defaultKeepaliveTimeout = 60 +) + // Equal tests for equality between two Config types func (e1 *Config) Equal(e2 *Config) bool { if e1 == e2 { @@ -90,6 +101,22 @@ func (e1 *Config) Equal(e2 *Config) bool { return false } + if e1.KeepaliveConnections != e2.KeepaliveConnections { + return false + } + + if e1.KeepaliveRequests != e2.KeepaliveRequests { + return false + } + + if e1.KeepaliveTimeout != e2.KeepaliveTimeout { + return false + } + + if e1.AlwaysSetCookie != e2.AlwaysSetCookie { + return false + } + return sets.StringElementsMatch(e1.AuthCacheDuration, e2.AuthCacheDuration) } @@ -193,6 +220,43 @@ func (a authReq) Parse(ing *networking.Ingress) (interface{}, error) { klog.V(3).InfoS("auth-cache-key annotation is undefined and will not be set") } + keepaliveConnections, err := parser.GetIntAnnotation("auth-keepalive", ing) + if err != nil { + klog.V(3).InfoS("auth-keepalive annotation is undefined and will be set to its default value") + keepaliveConnections = defaultKeepaliveConnections + } + switch { + case keepaliveConnections < 0: + klog.Warningf("auth-keepalive annotation (%s) contains a negative value, setting auth-keepalive to 0", authURL.Host) + keepaliveConnections = 0 + case keepaliveConnections > 0: + // NOTE: upstream block cannot reference a variable in the server directive + if strings.IndexByte(authURL.Host, '$') != -1 { + klog.Warningf("auth-url annotation (%s) contains $ in the host:port part, setting auth-keepalive to 0", authURL.Host) + keepaliveConnections = 0 + } + } + + keepaliveRequests, err := parser.GetIntAnnotation("auth-keepalive-requests", ing) + if err != nil { + klog.V(3).InfoS("auth-keepalive-requests annotation is undefined and will be set to its default value") + keepaliveRequests = defaultKeepaliveRequests + } + if keepaliveRequests <= 0 { + klog.Warningf("auth-keepalive-requests annotation (%s) should be greater than zero, setting auth-keepalive to 0", authURL.Host) + keepaliveConnections = 0 + } + + keepaliveTimeout, err := parser.GetIntAnnotation("auth-keepalive-timeout", ing) + if err != nil { + klog.V(3).InfoS("auth-keepalive-timeout annotation is undefined and will be set to its default value") + keepaliveTimeout = defaultKeepaliveTimeout + } + if keepaliveTimeout <= 0 { + klog.Warningf("auth-keepalive-timeout annotation (%s) should be greater than zero, setting auth-keepalive 0", authURL.Host) + keepaliveConnections = 0 + } + durstr, _ := parser.GetStringAnnotation("auth-cache-duration", ing) authCacheDuration, err := ParseStringToCacheDurations(durstr) if err != nil { @@ -238,6 +302,8 @@ func (a authReq) Parse(ing *networking.Ingress) (interface{}, error) { requestRedirect, _ := parser.GetStringAnnotation("auth-request-redirect", ing) + alwaysSetCookie, _ := parser.GetBoolAnnotation("auth-always-set-cookie", ing) + return &Config{ URL: urlString, Host: authURL.Hostname(), @@ -249,7 +315,11 @@ func (a authReq) Parse(ing *networking.Ingress) (interface{}, error) { AuthSnippet: authSnippet, AuthCacheKey: authCacheKey, AuthCacheDuration: authCacheDuration, + KeepaliveConnections: keepaliveConnections, + KeepaliveRequests: keepaliveRequests, + KeepaliveTimeout: keepaliveTimeout, ProxySetHeaders: proxySetHeaders, + AlwaysSetCookie: alwaysSetCookie, }, nil } diff --git a/internal/ingress/annotations/authreq/main_test.go b/internal/ingress/annotations/authreq/main_test.go index da903fe30..e1325235b 100644 --- a/internal/ingress/annotations/authreq/main_test.go +++ b/internal/ingress/annotations/authreq/main_test.go @@ -71,6 +71,13 @@ func buildIngress() *networking.Ingress { } } +func boolToString(v bool) string { + if v { + return "true" + } + return "false" +} + func TestAnnotations(t *testing.T) { ing := buildIngress() @@ -86,19 +93,20 @@ func TestAnnotations(t *testing.T) { requestRedirect string authSnippet string authCacheKey string + authAlwaysSetCookie bool expErr bool }{ - {"empty", "", "", "", "", "", "", "", true}, - {"no scheme", "bar", "bar", "", "", "", "", "", true}, - {"invalid host", "http://", "http://", "", "", "", "", "", true}, - {"invalid host (multiple dots)", "http://foo..bar.com", "http://foo..bar.com", "", "", "", "", "", true}, - {"valid URL", "http://bar.foo.com/external-auth", "http://bar.foo.com/external-auth", "", "", "", "", "", false}, - {"valid URL - send body", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "POST", "", "", "", false}, - {"valid URL - send body", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "GET", "", "", "", false}, - {"valid URL - request redirect", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "GET", "http://foo.com/redirect-me", "", "", false}, - {"auth snippet", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "", "", "proxy_set_header My-Custom-Header 42;", "", false}, - {"auth cache ", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "", "", "", "$foo$bar", false}, - {"redirect param", "http://bar.foo.com/external-auth", "http://bar.foo.com/external-auth", "origUrl", "", "", "", "", false}, + {"empty", "", "", "", "", "", "", "", false, true}, + {"no scheme", "bar", "bar", "", "", "", "", "", false, true}, + {"invalid host", "http://", "http://", "", "", "", "", "", false, true}, + {"invalid host (multiple dots)", "http://foo..bar.com", "http://foo..bar.com", "", "", "", "", "", false, true}, + {"valid URL", "http://bar.foo.com/external-auth", "http://bar.foo.com/external-auth", "", "", "", "", "", false, false}, + {"valid URL - send body", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "POST", "", "", "", false, false}, + {"valid URL - send body", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "GET", "", "", "", false, false}, + {"valid URL - request redirect", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "GET", "http://foo.com/redirect-me", "", "", false, false}, + {"auth snippet", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "", "", "proxy_set_header My-Custom-Header 42;", "", false, false}, + {"auth cache ", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "", "", "", "$foo$bar", false, false}, + {"redirect param", "http://bar.foo.com/external-auth", "http://bar.foo.com/external-auth", "origUrl", "", "", "", "", true, false}, } for _, test := range tests { @@ -109,6 +117,7 @@ func TestAnnotations(t *testing.T) { data[parser.GetAnnotationWithPrefix("auth-request-redirect")] = test.requestRedirect data[parser.GetAnnotationWithPrefix("auth-snippet")] = test.authSnippet data[parser.GetAnnotationWithPrefix("auth-cache-key")] = test.authCacheKey + data[parser.GetAnnotationWithPrefix("auth-always-set-cookie")] = boolToString(test.authAlwaysSetCookie) i, err := NewParser(&resolver.Mock{}).Parse(ing) if test.expErr { @@ -146,6 +155,10 @@ func TestAnnotations(t *testing.T) { if u.AuthCacheKey != test.authCacheKey { t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.authCacheKey, u.AuthCacheKey) } + + if u.AlwaysSetCookie != test.authAlwaysSetCookie { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.authAlwaysSetCookie, u.AlwaysSetCookie) + } } } @@ -243,6 +256,71 @@ func TestCacheDurationAnnotations(t *testing.T) { } } +func TestKeepaliveAnnotations(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + ing.SetAnnotations(data) + + tests := []struct { + title string + url string + keepaliveConnections string + keepaliveRequests string + keepaliveTimeout string + expectedConnections int + expectedRequests int + expectedTimeout int + }{ + {"all set", "http://goog.url", "5", "500", "50", 5, 500, 50}, + {"no annotation", "http://goog.url", "", "", "", defaultKeepaliveConnections, defaultKeepaliveRequests, defaultKeepaliveTimeout}, + {"default for connections", "http://goog.url", "x", "500", "50", defaultKeepaliveConnections, 500, 50}, + {"default for requests", "http://goog.url", "5", "x", "50", 5, defaultKeepaliveRequests, 50}, + {"default for invalid timeout", "http://goog.url", "5", "500", "x", 5, 500, defaultKeepaliveTimeout}, + {"variable in host", "http://$host:5000/a/b", "5", "", "", 0, defaultKeepaliveRequests, defaultKeepaliveTimeout}, + {"variable in path", "http://goog.url:5000/$path", "5", "", "", 5, defaultKeepaliveRequests, defaultKeepaliveTimeout}, + {"negative connections", "http://goog.url", "-2", "", "", 0, defaultKeepaliveRequests, defaultKeepaliveTimeout}, + {"negative requests", "http://goog.url", "5", "-1", "", 0, -1, defaultKeepaliveTimeout}, + {"negative timeout", "http://goog.url", "5", "", "-1", 0, defaultKeepaliveRequests, -1}, + {"negative request and timeout", "http://goog.url", "5", "-2", "-3", 0, -2, -3}, + } + + for _, test := range tests { + data[parser.GetAnnotationWithPrefix("auth-url")] = test.url + data[parser.GetAnnotationWithPrefix("auth-keepalive")] = test.keepaliveConnections + data[parser.GetAnnotationWithPrefix("auth-keepalive-timeout")] = test.keepaliveTimeout + data[parser.GetAnnotationWithPrefix("auth-keepalive-requests")] = test.keepaliveRequests + + i, err := NewParser(&resolver.Mock{}).Parse(ing) + if err != nil { + t.Errorf("%v: unexpected error: %v", test.title, err) + continue + } + + u, ok := i.(*Config) + if !ok { + t.Errorf("%v: expected an External type", test.title) + continue + } + + if u.URL != test.url { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.url, u.URL) + } + + if u.KeepaliveConnections != test.expectedConnections { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.expectedConnections, u.KeepaliveConnections) + } + + if u.KeepaliveRequests != test.expectedRequests { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.expectedRequests, u.KeepaliveRequests) + } + + if u.KeepaliveTimeout != test.expectedTimeout { + t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.expectedTimeout, u.KeepaliveTimeout) + } + } +} + func TestParseStringToCacheDurations(t *testing.T) { tests := []struct { diff --git a/internal/ingress/annotations/authtls/main.go b/internal/ingress/annotations/authtls/main.go index cbe014c4a..2efd6d176 100644 --- a/internal/ingress/annotations/authtls/main.go +++ b/internal/ingress/annotations/authtls/main.go @@ -18,6 +18,7 @@ package authtls import ( "fmt" + networking "k8s.io/api/networking/v1" "regexp" @@ -35,6 +36,7 @@ const ( var ( authVerifyClientRegex = regexp.MustCompile(`on|off|optional|optional_no_ca`) + commonNameRegex = regexp.MustCompile(`CN=`) ) // Config contains the AuthSSLCert used for mutual authentication @@ -45,6 +47,7 @@ type Config struct { ValidationDepth int `json:"validationDepth"` ErrorPage string `json:"errorPage"` PassCertToUpstream bool `json:"passCertToUpstream"` + MatchCN string `json:"matchCN"` AuthTLSError string } @@ -127,5 +130,10 @@ func (a authTLS) Parse(ing *networking.Ingress) (interface{}, error) { config.PassCertToUpstream = false } + config.MatchCN, err = parser.GetStringAnnotation("auth-tls-match-cn", ing) + if err != nil || !commonNameRegex.MatchString(config.MatchCN) { + config.MatchCN = "" + } + return config, nil } diff --git a/internal/ingress/annotations/authtls/main_test.go b/internal/ingress/annotations/authtls/main_test.go index f7649fe1c..569f3865b 100644 --- a/internal/ingress/annotations/authtls/main_test.go +++ b/internal/ingress/annotations/authtls/main_test.go @@ -128,11 +128,15 @@ func TestAnnotations(t *testing.T) { if u.PassCertToUpstream != false { t.Errorf("expected %v but got %v", false, u.PassCertToUpstream) } + if u.MatchCN != "" { + t.Errorf("expected empty string, but got %v", u.MatchCN) + } data[parser.GetAnnotationWithPrefix("auth-tls-verify-client")] = "off" data[parser.GetAnnotationWithPrefix("auth-tls-verify-depth")] = "2" data[parser.GetAnnotationWithPrefix("auth-tls-error-page")] = "ok.com/error" data[parser.GetAnnotationWithPrefix("auth-tls-pass-certificate-to-upstream")] = "true" + data[parser.GetAnnotationWithPrefix("auth-tls-match-cn")] = "CN=hello-app" ing.SetAnnotations(data) @@ -161,6 +165,9 @@ func TestAnnotations(t *testing.T) { if u.PassCertToUpstream != true { t.Errorf("expected %v but got %v", true, u.PassCertToUpstream) } + if u.MatchCN != "CN=hello-app" { + t.Errorf("expected %v but got %v", "CN=hello-app", u.MatchCN) + } } func TestInvalidAnnotations(t *testing.T) { @@ -195,6 +202,7 @@ func TestInvalidAnnotations(t *testing.T) { data[parser.GetAnnotationWithPrefix("auth-tls-verify-client")] = "w00t" data[parser.GetAnnotationWithPrefix("auth-tls-verify-depth")] = "abcd" data[parser.GetAnnotationWithPrefix("auth-tls-pass-certificate-to-upstream")] = "nahh" + data[parser.GetAnnotationWithPrefix("auth-tls-match-cn")] = "" ing.SetAnnotations(data) i, err := NewParser(fakeSecret).Parse(ing) @@ -215,6 +223,9 @@ func TestInvalidAnnotations(t *testing.T) { if u.PassCertToUpstream != false { t.Errorf("expected %v but got %v", false, u.PassCertToUpstream) } + if u.MatchCN != "" { + t.Errorf("expected empty string but got %v", u.MatchCN) + } } diff --git a/internal/ingress/annotations/cors/main.go b/internal/ingress/annotations/cors/main.go index de5b8c279..3888f2909 100644 --- a/internal/ingress/annotations/cors/main.go +++ b/internal/ingress/annotations/cors/main.go @@ -30,7 +30,7 @@ import ( const ( // Default values defaultCorsMethods = "GET, PUT, POST, DELETE, PATCH, OPTIONS" - defaultCorsHeaders = "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization" + defaultCorsHeaders = "DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" defaultCorsMaxAge = 1728000 ) diff --git a/internal/ingress/annotations/ipwhitelist/main.go b/internal/ingress/annotations/ipwhitelist/main.go index 77c2b6cc0..38610ade6 100644 --- a/internal/ingress/annotations/ipwhitelist/main.go +++ b/internal/ingress/annotations/ipwhitelist/main.go @@ -62,18 +62,21 @@ func NewParser(r resolver.Resolver) parser.IngressAnnotation { // e.g. `18.0.0.0/8,56.0.0.0/8` func (a ipwhitelist) Parse(ing *networking.Ingress) (interface{}, error) { defBackend := a.r.GetDefaultBackend() - sort.Strings(defBackend.WhitelistSourceRange) + + defaultWhitelistSourceRange := make([]string, len(defBackend.WhitelistSourceRange)) + copy(defaultWhitelistSourceRange, defBackend.WhitelistSourceRange) + sort.Strings(defaultWhitelistSourceRange) val, err := parser.GetStringAnnotation("whitelist-source-range", ing) // A missing annotation is not a problem, just use the default if err == ing_errors.ErrMissingAnnotations { - return &SourceRange{CIDR: defBackend.WhitelistSourceRange}, nil + return &SourceRange{CIDR: defaultWhitelistSourceRange}, nil } values := strings.Split(val, ",") ipnets, ips, err := net.ParseIPNets(values...) if err != nil && len(ips) == 0 { - return &SourceRange{CIDR: defBackend.WhitelistSourceRange}, ing_errors.LocationDenied{ + return &SourceRange{CIDR: defaultWhitelistSourceRange}, ing_errors.LocationDenied{ Reason: fmt.Errorf("the annotation does not contain a valid IP address or network: %w", err), } } diff --git a/internal/ingress/annotations/mirror/main.go b/internal/ingress/annotations/mirror/main.go index e11d4b4fb..cd54a9826 100644 --- a/internal/ingress/annotations/mirror/main.go +++ b/internal/ingress/annotations/mirror/main.go @@ -18,9 +18,9 @@ package mirror import ( "fmt" + "strings" networking "k8s.io/api/networking/v1" - "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) @@ -30,6 +30,7 @@ type Config struct { Source string `json:"source"` RequestBody string `json:"requestBody"` Target string `json:"target"` + Host string `json:"host"` } // Equal tests for equality between two Configuration types @@ -54,6 +55,10 @@ func (m1 *Config) Equal(m2 *Config) bool { return false } + if m1.Host != m2.Host { + return false + } + return true } @@ -85,5 +90,18 @@ func (a mirror) Parse(ing *networking.Ingress) (interface{}, error) { config.Source = "" } + config.Host, err = parser.GetStringAnnotation("mirror-host", ing) + if err != nil { + if config.Target != "" { + url, err := parser.StringToURL(config.Target) + if err != nil { + config.Host = "" + } else { + hostname := strings.Split(url.Hostname(), "$") + config.Host = hostname[0] + } + } + } + return config, nil } diff --git a/internal/ingress/annotations/mirror/main_test.go b/internal/ingress/annotations/mirror/main_test.go index af7ed1b1f..f744ab552 100644 --- a/internal/ingress/annotations/mirror/main_test.go +++ b/internal/ingress/annotations/mirror/main_test.go @@ -30,6 +30,7 @@ import ( func TestParse(t *testing.T) { requestBody := parser.GetAnnotationWithPrefix("mirror-request-body") backendURL := parser.GetAnnotationWithPrefix("mirror-target") + host := parser.GetAnnotationWithPrefix("mirror-host") ap := NewParser(&resolver.Mock{}) if ap == nil { @@ -45,11 +46,43 @@ func TestParse(t *testing.T) { Source: ngxURI, RequestBody: "on", Target: "https://test.env.com/$request_uri", + Host: "test.env.com", }}, {map[string]string{requestBody: "off"}, &Config{ Source: "", RequestBody: "off", Target: "", + Host: "", + }}, + {map[string]string{host: "test.env.com", backendURL: "http://some.test.env.com/$someparam"}, &Config{ + Source: ngxURI, + RequestBody: "on", + Target: "http://some.test.env.com/$someparam", + Host: "test.env.com", + }}, + {map[string]string{backendURL: "IamNotAURL"}, &Config{ + Source: ngxURI, + RequestBody: "on", + Target: "IamNotAURL", + Host: "", + }}, + {map[string]string{backendURL: "http://some.test.env.com:2121/$someparam=1&$someotherparam=2"}, &Config{ + Source: ngxURI, + RequestBody: "on", + Target: "http://some.test.env.com:2121/$someparam=1&$someotherparam=2", + Host: "some.test.env.com", + }}, + {map[string]string{backendURL: "http://some.test.env.com", host: "someInvalidParm.%^&*()_=!@#'\""}, &Config{ + Source: ngxURI, + RequestBody: "on", + Target: "http://some.test.env.com", + Host: "someInvalidParm.%^&*()_=!@#'\"", + }}, + {map[string]string{backendURL: "http://some.test.env.com", host: "_sbrubles-i\"@xpto:12345"}, &Config{ + Source: ngxURI, + RequestBody: "on", + Target: "http://some.test.env.com", + Host: "_sbrubles-i\"@xpto:12345", }}, } diff --git a/internal/ingress/controller/checker_test.go b/internal/ingress/controller/checker_test.go index 3f02f4016..fd712b6a8 100644 --- a/internal/ingress/controller/checker_test.go +++ b/internal/ingress/controller/checker_test.go @@ -76,7 +76,7 @@ func TestNginxCheck(t *testing.T) { }) // create pid file - os.MkdirAll("/tmp", file.ReadWriteByUser) + os.MkdirAll("/tmp/nginx", file.ReadWriteByUser) pidFile, err := os.Create(nginx.PID) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go index f37516e78..07f9d957a 100644 --- a/internal/ingress/controller/config/config.go +++ b/internal/ingress/controller/config/config.go @@ -468,6 +468,10 @@ type Configuration struct { // http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive UpstreamKeepaliveConnections int `json:"upstream-keepalive-connections,omitempty"` + // Sets the maximum time during which requests can be processed through one keepalive connection + // https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_time + UpstreamKeepaliveTime string `json:"upstream-keepalive-time,omitempty"` + // Sets a timeout during which an idle keepalive connection to an upstream server will stay open. // http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_timeout UpstreamKeepaliveTimeout int `json:"upstream-keepalive-timeout,omitempty"` @@ -764,6 +768,11 @@ type Configuration struct { // GlobalRateLimitStatucCode determines the HTTP status code to return // when limit is exceeding during global rate limiting. GlobalRateLimitStatucCode int `json:"global-rate-limit-status-code"` + + // DebugConnections Enables debugging log for selected client connections + // http://nginx.org/en/docs/ngx_core_module.html#debug_connection + // Default: "" + DebugConnections []string `json:"debug-connections"` } // NewDefault returns the default nginx configuration @@ -778,7 +787,7 @@ func NewDefault() Configuration { defNginxStatusIpv4Whitelist = append(defNginxStatusIpv4Whitelist, "127.0.0.1") defNginxStatusIpv6Whitelist = append(defNginxStatusIpv6Whitelist, "::1") defProxyDeadlineDuration := time.Duration(5) * time.Second - defGlobalExternalAuth := GlobalExternalAuth{"", "", "", "", "", append(defResponseHeaders, ""), "", "", "", []string{}, map[string]string{}} + defGlobalExternalAuth := GlobalExternalAuth{"", "", "", "", "", append(defResponseHeaders, ""), "", "", "", []string{}, map[string]string{}, false} cfg := Configuration{ @@ -892,6 +901,7 @@ func NewDefault() Configuration { ServiceUpstream: false, }, UpstreamKeepaliveConnections: 320, + UpstreamKeepaliveTime: "1h", UpstreamKeepaliveTimeout: 60, UpstreamKeepaliveRequests: 10000, LimitConnZoneVariable: defaultLimitConnZoneVariable, @@ -927,6 +937,7 @@ func NewDefault() Configuration { GlobalRateLimitMemcachedMaxIdleTimeout: 10000, GlobalRateLimitMemcachedPoolSize: 50, GlobalRateLimitStatucCode: 429, + DebugConnections: []string{}, } if klog.V(5).Enabled() { @@ -958,12 +969,11 @@ type TemplateConfig struct { EnableMetrics bool MaxmindEditionFiles *[]string MonitorMaxBatchSize int - - PID string - StatusPath string - StatusPort int - StreamPort int - StreamSnippets []string + PID string + StatusPath string + StatusPort int + StreamPort int + StreamSnippets []string } // ListenPorts describe the ports required to run the @@ -991,4 +1001,5 @@ type GlobalExternalAuth struct { AuthCacheKey string `json:"authCacheKey"` AuthCacheDuration []string `json:"authCacheDuration"` ProxySetHeaders map[string]string `json:"proxySetHeaders,omitempty"` + AlwaysSetCookie bool `json:"alwaysSetCookie,omitempty"` } diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index 651e983a8..44385f175 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -41,6 +41,7 @@ import ( "k8s.io/ingress-nginx/internal/ingress/controller/ingressclass" "k8s.io/ingress-nginx/internal/ingress/controller/store" "k8s.io/ingress-nginx/internal/ingress/errors" + "k8s.io/ingress-nginx/internal/ingress/inspector" "k8s.io/ingress-nginx/internal/ingress/metric/collectors" "k8s.io/ingress-nginx/internal/k8s" "k8s.io/ingress-nginx/internal/nginx" @@ -96,9 +97,10 @@ type Configuration struct { EnableProfiling bool - EnableMetrics bool - MetricsPerHost bool - MetricsBuckets *collectors.HistogramBuckets + EnableMetrics bool + MetricsPerHost bool + MetricsBuckets *collectors.HistogramBuckets + ReportStatusClasses bool FakeCertificate *ingress.SSLCert @@ -120,6 +122,12 @@ type Configuration struct { PostShutdownGracePeriod int ShutdownGracePeriod int + + InternalLoggerAddress string + IsChroot bool + DeepInspector bool + + DynamicConfigurationRetries int } // GetPublishService returns the Service used to set the load-balancer status of Ingresses. @@ -189,19 +197,24 @@ func (n *NGINXController) syncIngress(interface{}) error { } retry := wait.Backoff{ - Steps: 15, - Duration: 1 * time.Second, - Factor: 0.8, + Steps: 1 + n.cfg.DynamicConfigurationRetries, + Duration: time.Second, + Factor: 1.3, Jitter: 0.1, } + retriesRemaining := retry.Steps err := wait.ExponentialBackoff(retry, func() (bool, error) { err := n.configureDynamically(pcfg) if err == nil { klog.V(2).Infof("Dynamic reconfiguration succeeded.") return true, nil } - + retriesRemaining-- + if retriesRemaining > 0 { + klog.Warningf("Dynamic reconfiguration failed (retrying; %d retries left): %v", retriesRemaining, err) + return false, nil + } klog.Warningf("Dynamic reconfiguration failed: %v", err) return false, err }) @@ -234,7 +247,11 @@ func (n *NGINXController) CheckIngress(ing *networking.Ingress) error { if !ing.DeletionTimestamp.IsZero() { return nil } - + if n.cfg.DeepInspector { + if err := inspector.DeepInspect(ing); err != nil { + return fmt.Errorf("invalid object: %w", err) + } + } // Do not attempt to validate an ingress that's not meant to be controlled by the current instance of the controller. if ingressClass, err := n.store.GetIngressClass(ing, n.cfg.IngressClassConfiguration); ingressClass == "" { klog.Warningf("ignoring ingress %v in %v based on annotation %v: %v", ing.Name, ing.ObjectMeta.Namespace, ingressClass, err) diff --git a/internal/ingress/controller/controller_test.go b/internal/ingress/controller/controller_test.go index 5e3eb9113..398e18830 100644 --- a/internal/ingress/controller/controller_test.go +++ b/internal/ingress/controller/controller_test.go @@ -2396,6 +2396,7 @@ func newNGINXController(t *testing.T) *NGINXController { clientSet, channels.NewRingChannel(10), false, + true, &ingressclass.IngressClassConfiguration{ Controller: "k8s.io/ingress-nginx", AnnotationValue: "nginx", @@ -2460,6 +2461,7 @@ func newDynamicNginxController(t *testing.T, setConfigMap func(string) *v1.Confi clientSet, channels.NewRingChannel(10), false, + true, &ingressclass.IngressClassConfiguration{ Controller: "k8s.io/ingress-nginx", AnnotationValue: "nginx", diff --git a/internal/ingress/controller/nginx.go b/internal/ingress/controller/nginx.go index e4037dfb0..9c8e5265c 100644 --- a/internal/ingress/controller/nginx.go +++ b/internal/ingress/controller/nginx.go @@ -110,9 +110,11 @@ func NewNGINXController(config *Configuration, mc metric.Collector) *NGINXContro if n.cfg.ValidationWebhook != "" { n.validationWebhookServer = &http.Server{ - Addr: config.ValidationWebhook, - Handler: adm_controller.NewAdmissionControllerServer(&adm_controller.IngressAdmission{Checker: n}), - TLSConfig: ssl.NewTLSListener(n.cfg.ValidationWebhookCertPath, n.cfg.ValidationWebhookKeyPath).TLSConfig(), + Addr: config.ValidationWebhook, + //G112 (CWE-400): Potential Slowloris Attack + ReadHeaderTimeout: 10 * time.Second, + Handler: adm_controller.NewAdmissionControllerServer(&adm_controller.IngressAdmission{Checker: n}), + TLSConfig: ssl.NewTLSListener(n.cfg.ValidationWebhookCertPath, n.cfg.ValidationWebhookKeyPath).TLSConfig(), // disable http/2 // https://github.com/kubernetes/kubernetes/issues/80313 // https://github.com/kubernetes/ingress-nginx/issues/6323#issuecomment-737239159 @@ -131,6 +133,7 @@ func NewNGINXController(config *Configuration, mc metric.Collector) *NGINXContro config.Client, n.updateCh, config.DisableCatchAll, + config.DeepInspector, config.IngressClassConfiguration) n.syncQueue = task.NewTaskQueue(n.syncIngress) @@ -575,6 +578,15 @@ func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressC cfg.DefaultSSLCertificate = n.getDefaultSSLCertificate() + if n.cfg.IsChroot { + if cfg.AccessLogPath == "/var/log/nginx/access.log" { + cfg.AccessLogPath = fmt.Sprintf("syslog:server=%s", n.cfg.InternalLoggerAddress) + } + if cfg.ErrorLogPath == "/var/log/nginx/error.log" { + cfg.ErrorLogPath = fmt.Sprintf("syslog:server=%s", n.cfg.InternalLoggerAddress) + } + } + tc := ngx_config.TemplateConfig{ ProxySetHeaders: setHeaders, AddHeaders: addHeaders, @@ -614,7 +626,8 @@ func (n NGINXController) testTemplate(cfg []byte) error { if len(cfg) == 0 { return fmt.Errorf("invalid NGINX configuration (empty)") } - tmpfile, err := os.CreateTemp("", tempNginxPattern) + tmpDir := os.TempDir() + "/nginx" + tmpfile, err := os.CreateTemp(tmpDir, tempNginxPattern) if err != nil { return err } diff --git a/internal/ingress/controller/process/nginx.go b/internal/ingress/controller/process/nginx.go index 702f60da8..70227ac2e 100644 --- a/internal/ingress/controller/process/nginx.go +++ b/internal/ingress/controller/process/nginx.go @@ -20,7 +20,7 @@ import ( "os/exec" "syscall" - "k8s.io/klog/v2" + klog "k8s.io/klog/v2" ) // IsRespawnIfRequired checks if error type is exec.ExitError or not diff --git a/internal/ingress/controller/store/store.go b/internal/ingress/controller/store/store.go index 2b15dc74d..d29636b03 100644 --- a/internal/ingress/controller/store/store.go +++ b/internal/ingress/controller/store/store.go @@ -42,6 +42,7 @@ import ( clientcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/record" + "k8s.io/ingress-nginx/internal/ingress/inspector" "k8s.io/klog/v2" "k8s.io/ingress-nginx/internal/file" @@ -247,6 +248,7 @@ func New( client clientset.Interface, updateCh *channels.RingChannel, disableCatchAll bool, + deepInspector bool, icConfig *ingressclass.IngressClassConfiguration) Storer { store := &k8sStore{ @@ -426,6 +428,12 @@ func New( klog.InfoS("Found valid IngressClass", "ingress", klog.KObj(ing), "ingressclass", ic) + if deepInspector { + if err := inspector.DeepInspect(ing); err != nil { + klog.ErrorS(err, "received invalid ingress", "ingress", klog.KObj(ing)) + return + } + } if hasCatchAllIngressRule(ing.Spec) && disableCatchAll { klog.InfoS("Ignoring add for catch-all ingress because of --disable-catch-all", "ingress", klog.KObj(ing)) return @@ -482,6 +490,13 @@ func New( return } + if deepInspector { + if err := inspector.DeepInspect(curIng); err != nil { + klog.ErrorS(err, "received invalid ingress", "ingress", klog.KObj(curIng)) + return + } + } + store.syncIngress(curIng) store.updateSecretIngressMap(curIng) store.syncSecrets(curIng) diff --git a/internal/ingress/controller/store/store_test.go b/internal/ingress/controller/store/store_test.go index 735208001..4868f792f 100644 --- a/internal/ingress/controller/store/store_test.go +++ b/internal/ingress/controller/store/store_test.go @@ -124,6 +124,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, DefaultClassConfig) storer.Run(stopCh) @@ -204,6 +205,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, DefaultClassConfig) storer.Run(stopCh) @@ -307,6 +309,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, DefaultClassConfig) storer.Run(stopCh) @@ -422,6 +425,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, ingressClassconfig) storer.Run(stopCh) @@ -551,6 +555,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, ingressClassconfig) storer.Run(stopCh) @@ -650,6 +655,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, DefaultClassConfig) storer.Run(stopCh) @@ -743,6 +749,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, DefaultClassConfig) storer.Run(stopCh) @@ -828,6 +835,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, DefaultClassConfig) storer.Run(stopCh) @@ -923,6 +931,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, DefaultClassConfig) storer.Run(stopCh) @@ -1046,6 +1055,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, DefaultClassConfig) storer.Run(stopCh) @@ -1166,6 +1176,7 @@ func TestStore(t *testing.T) { clientSet, updateCh, false, + true, DefaultClassConfig) storer.Run(stopCh) diff --git a/internal/ingress/controller/template/configmap.go b/internal/ingress/controller/template/configmap.go index 4f3aca444..bcd985f7f 100644 --- a/internal/ingress/controller/template/configmap.go +++ b/internal/ingress/controller/template/configmap.go @@ -62,8 +62,10 @@ const ( globalAuthSnippet = "global-auth-snippet" globalAuthCacheKey = "global-auth-cache-key" globalAuthCacheDuration = "global-auth-cache-duration" + globalAuthAlwaysSetCookie = "global-auth-always-set-cookie" luaSharedDictsKey = "lua-shared-dicts" plugins = "plugins" + debugConnections = "debug-connections" ) var ( @@ -110,6 +112,7 @@ func ReadConfig(src map[string]string) config.Configuration { blockRefererList := make([]string, 0) responseHeaders := make([]string, 0) luaSharedDicts := make(map[string]int) + debugConnectionsList := make([]string, 0) //parse lua shared dict values if val, ok := conf[luaSharedDictsKey]; ok { @@ -315,6 +318,16 @@ func ReadConfig(src map[string]string) config.Configuration { to.GlobalExternalAuth.AuthCacheDuration = cacheDurations } + if val, ok := conf[globalAuthAlwaysSetCookie]; ok { + delete(conf, globalAuthAlwaysSetCookie) + + alwaysSetCookie, err := strconv.ParseBool(val) + if err != nil { + klog.Warningf("Global auth location denied - %s", fmt.Errorf("cannot convert %s to bool: %v", globalAuthAlwaysSetCookie, err)) + } + to.GlobalExternalAuth.AlwaysSetCookie = alwaysSetCookie + } + // Verify that the configured timeout is parsable as a duration. if not, set the default value if val, ok := conf[proxyHeaderTimeout]; ok { delete(conf, proxyHeaderTimeout) @@ -362,6 +375,24 @@ func ReadConfig(src map[string]string) config.Configuration { delete(conf, plugins) } + if val, ok := conf[debugConnections]; ok { + delete(conf, debugConnections) + for _, i := range splitAndTrimSpace(val, ",") { + validIp := net.ParseIP(i) + if validIp != nil { + debugConnectionsList = append(debugConnectionsList, i) + } else { + _, _, err := net.ParseCIDR(i) + if err == nil { + debugConnectionsList = append(debugConnectionsList, i) + } else { + klog.Warningf("%v is not a valid IP or CIDR address", i) + } + } + } + to.DebugConnections = debugConnectionsList + } + to.CustomHTTPErrors = filterErrors(errors) to.SkipAccessLogURLs = skipUrls to.WhitelistSourceRange = whiteList diff --git a/internal/ingress/controller/template/configmap_test.go b/internal/ingress/controller/template/configmap_test.go index 1f6ce2fe6..be3ffb0ce 100644 --- a/internal/ingress/controller/template/configmap_test.go +++ b/internal/ingress/controller/template/configmap_test.go @@ -75,6 +75,7 @@ func TestMergeConfigMapToStruct(t *testing.T) { "proxy-add-original-uri-header": "false", "disable-ipv6-dns": "true", "default-type": "text/plain", + "debug-connections": "127.0.0.1,1.1.1.1/24,::1", } def := config.NewDefault() def.CustomHTTPErrors = []int{300, 400} @@ -99,6 +100,7 @@ func TestMergeConfigMapToStruct(t *testing.T) { def.LuaSharedDicts = defaultLuaSharedDicts def.DisableIpv6DNS = true def.DefaultType = "text/plain" + def.DebugConnections = []string{"127.0.0.1", "1.1.1.1/24", "::1"} hash, err := hashstructure.Hash(def, &hashstructure.HashOptions{ TagName: "json", @@ -229,6 +231,34 @@ func TestGlobalExternalAuthSigninParsing(t *testing.T) { } } +func TestGlobalExternalAlwaysSetCookie(t *testing.T) { + testCases := map[string]struct { + alwaysSetCookie string + result bool + }{ + "true": { + alwaysSetCookie: "true", + result: true, + }, + "false": { + alwaysSetCookie: "false", + }, + "set empty": { + alwaysSetCookie: "", + }, + "error": { + alwaysSetCookie: "error string", + }, + } + + for n, tc := range testCases { + cfg := ReadConfig(map[string]string{"global-auth-always-set-cookie": tc.alwaysSetCookie}) + if cfg.GlobalExternalAuth.AlwaysSetCookie != tc.result { + t.Errorf("Testing %v. Expected \"%v\" but \"%v\" was returned", n, tc.result, cfg.GlobalExternalAuth.AlwaysSetCookie) + } + } +} + func TestGlobalExternalAuthSigninRedirectParamParsing(t *testing.T) { testCases := map[string]struct { param string diff --git a/internal/ingress/controller/template/template.go b/internal/ingress/controller/template/template.go index 9b61d059a..a331c196a 100644 --- a/internal/ingress/controller/template/template.go +++ b/internal/ingress/controller/template/template.go @@ -42,6 +42,7 @@ import ( "k8s.io/ingress-nginx/internal/ingress" "k8s.io/ingress-nginx/internal/ingress/annotations/influxdb" + "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/annotations/ratelimit" "k8s.io/ingress-nginx/internal/ingress/controller/config" ing_net "k8s.io/ingress-nginx/internal/net" @@ -227,7 +228,12 @@ var ( "buildAuthLocation": buildAuthLocation, "shouldApplyGlobalAuth": shouldApplyGlobalAuth, "buildAuthResponseHeaders": buildAuthResponseHeaders, + "buildAuthUpstreamLuaHeaders": buildAuthUpstreamLuaHeaders, "buildAuthProxySetHeaders": buildAuthProxySetHeaders, + "buildAuthUpstreamName": buildAuthUpstreamName, + "shouldApplyAuthUpstream": shouldApplyAuthUpstream, + "extractHostPort": extractHostPort, + "changeHostPort": changeHostPort, "buildProxyPass": buildProxyPass, "filterRateLimits": filterRateLimits, "buildRateLimitZones": buildRateLimitZones, @@ -572,7 +578,14 @@ func shouldApplyGlobalAuth(input interface{}, globalExternalAuthURL string) bool return false } -func buildAuthResponseHeaders(proxySetHeader string, headers []string) []string { +// buildAuthResponseHeaders sets HTTP response headers when `auth-url` is used. +// Based on `auth-keepalive` value we use auth_request_set Nginx directives, or +// we use Lua and Nginx variables instead. +// +// NOTE: Unfortunately auth_request module ignores the keepalive directive (see: +// https://trac.nginx.org/nginx/ticket/1579), that is why we mimic the same +// functionality with access_by_lua_block. +func buildAuthResponseHeaders(proxySetHeader string, headers []string, lua bool) []string { res := []string{} if len(headers) == 0 { @@ -580,14 +593,31 @@ func buildAuthResponseHeaders(proxySetHeader string, headers []string) []string } for i, h := range headers { - hvar := strings.ToLower(h) - hvar = strings.NewReplacer("-", "_").Replace(hvar) - res = append(res, fmt.Sprintf("auth_request_set $authHeader%v $upstream_http_%v;", i, hvar)) + if lua { + res = append(res, fmt.Sprintf("set $authHeader%d '';", i)) + } else { + hvar := strings.ToLower(h) + hvar = strings.NewReplacer("-", "_").Replace(hvar) + res = append(res, fmt.Sprintf("auth_request_set $authHeader%v $upstream_http_%v;", i, hvar)) + } res = append(res, fmt.Sprintf("%s '%v' $authHeader%v;", proxySetHeader, h, i)) } return res } +func buildAuthUpstreamLuaHeaders(headers []string) []string { + res := []string{} + + if len(headers) == 0 { + return res + } + + for i, h := range headers { + res = append(res, fmt.Sprintf("ngx.var.authHeader%d = res.header['%s']", i, h)) + } + return res +} + func buildAuthProxySetHeaders(headers map[string]string) []string { res := []string{} @@ -602,6 +632,76 @@ func buildAuthProxySetHeaders(headers map[string]string) []string { return res } +func buildAuthUpstreamName(input interface{}, host string) string { + authPath := buildAuthLocation(input, "") + if authPath == "" || host == "" { + return "" + } + + return fmt.Sprintf("%s-%s", host, authPath[2:]) +} + +// shouldApplyAuthUpstream returns true only in case when ExternalAuth.URL and +// ExternalAuth.KeepaliveConnections are all set +func shouldApplyAuthUpstream(l interface{}, c interface{}) bool { + location, ok := l.(*ingress.Location) + if !ok { + klog.Errorf("expected an '*ingress.Location' type but %T was returned", l) + return false + } + + cfg, ok := c.(config.Configuration) + if !ok { + klog.Errorf("expected a 'config.Configuration' type but %T was returned", c) + return false + } + + if location.ExternalAuth.URL == "" || location.ExternalAuth.KeepaliveConnections == 0 { + return false + } + + // Unfortunately, `auth_request` module ignores keepalive in upstream block: https://trac.nginx.org/nginx/ticket/1579 + // The workaround is to use `ngx.location.capture` Lua subrequests but it is not supported with HTTP/2 + if cfg.UseHTTP2 { + klog.Warning("Upstream keepalive is not supported with HTTP/2") + return false + } + + return true +} + +// extractHostPort will extract the host:port part from the URL specified by url +func extractHostPort(url string) string { + if url == "" { + return "" + } + + authURL, err := parser.StringToURL(url) + if err != nil { + klog.Errorf("expected a valid URL but %s was returned", url) + return "" + } + + return authURL.Host +} + +// changeHostPort will change the host:port part of the url to value +func changeHostPort(url string, value string) string { + if url == "" { + return "" + } + + authURL, err := parser.StringToURL(url) + if err != nil { + klog.Errorf("expected a valid URL but %s was returned", url) + return "" + } + + authURL.Host = value + + return authURL.String() +} + // buildProxyPass produces the proxy pass string, if the ingress has redirects // (specified through the nginx.ingress.kubernetes.io/rewrite-target annotation) // If the annotation nginx.ingress.kubernetes.io/add-base-url:"true" is specified it will @@ -1177,15 +1277,17 @@ func proxySetHeader(loc interface{}) string { // buildCustomErrorDeps is a utility function returning a struct wrapper with // the data required to build the 'CUSTOM_ERRORS' template -func buildCustomErrorDeps(upstreamName string, errorCodes []int, enableMetrics bool) interface{} { +func buildCustomErrorDeps(upstreamName string, errorCodes []int, enableMetrics bool, modsecurityEnabled bool) interface{} { return struct { - UpstreamName string - ErrorCodes []int - EnableMetrics bool + UpstreamName string + ErrorCodes []int + EnableMetrics bool + ModsecurityEnabled bool }{ - UpstreamName: upstreamName, - ErrorCodes: errorCodes, - EnableMetrics: enableMetrics, + UpstreamName: upstreamName, + ErrorCodes: errorCodes, + EnableMetrics: enableMetrics, + ModsecurityEnabled: modsecurityEnabled, } } @@ -1565,10 +1667,11 @@ func buildMirrorLocations(locs []*ingress.Location) string { mapped.Insert(loc.Mirror.Source) buffer.WriteString(fmt.Sprintf(`location = %v { internal; +proxy_set_header Host %v; proxy_pass %v; } -`, loc.Mirror.Source, loc.Mirror.Target)) +`, loc.Mirror.Source, loc.Mirror.Host, loc.Mirror.Target)) } return buffer.String() diff --git a/internal/ingress/controller/template/template_test.go b/internal/ingress/controller/template/template_test.go index b65e33c32..a741919ed 100644 --- a/internal/ingress/controller/template/template_test.go +++ b/internal/ingress/controller/template/template_test.go @@ -502,14 +502,49 @@ func TestShouldApplyGlobalAuth(t *testing.T) { func TestBuildAuthResponseHeaders(t *testing.T) { externalAuthResponseHeaders := []string{"h1", "H-With-Caps-And-Dashes"} - expected := []string{ - "auth_request_set $authHeader0 $upstream_http_h1;", - "proxy_set_header 'h1' $authHeader0;", - "auth_request_set $authHeader1 $upstream_http_h_with_caps_and_dashes;", - "proxy_set_header 'H-With-Caps-And-Dashes' $authHeader1;", + tests := []struct { + headers []string + expected []string + lua bool + }{ + { + headers: externalAuthResponseHeaders, + lua: false, + expected: []string{ + "auth_request_set $authHeader0 $upstream_http_h1;", + "proxy_set_header 'h1' $authHeader0;", + "auth_request_set $authHeader1 $upstream_http_h_with_caps_and_dashes;", + "proxy_set_header 'H-With-Caps-And-Dashes' $authHeader1;", + }, + }, + { + headers: externalAuthResponseHeaders, + lua: true, + expected: []string{ + "set $authHeader0 '';", + "proxy_set_header 'h1' $authHeader0;", + "set $authHeader1 '';", + "proxy_set_header 'H-With-Caps-And-Dashes' $authHeader1;", + }, + }, } - headers := buildAuthResponseHeaders(proxySetHeader(nil), externalAuthResponseHeaders) + for _, test := range tests { + got := buildAuthResponseHeaders(proxySetHeader(nil), test.headers, test.lua) + if !reflect.DeepEqual(test.expected, got) { + t.Errorf("Expected \n'%v'\nbut returned \n'%v'", test.expected, got) + } + } +} + +func TestBuildAuthResponseLua(t *testing.T) { + externalAuthResponseHeaders := []string{"h1", "H-With-Caps-And-Dashes"} + expected := []string{ + "ngx.var.authHeader0 = res.header['h1']", + "ngx.var.authHeader1 = res.header['H-With-Caps-And-Dashes']", + } + + headers := buildAuthUpstreamLuaHeaders(externalAuthResponseHeaders) if !reflect.DeepEqual(expected, headers) { t.Errorf("Expected \n'%v'\nbut returned \n'%v'", expected, headers) @@ -533,6 +568,139 @@ func TestBuildAuthProxySetHeaders(t *testing.T) { } } +func TestBuildAuthUpstreamName(t *testing.T) { + invalidType := &ingress.Ingress{} + expected := "" + actual := buildAuthUpstreamName(invalidType, "") + + if !reflect.DeepEqual(expected, actual) { + t.Errorf("Expected '%v' but returned '%v'", expected, actual) + } + + loc := &ingress.Location{ + ExternalAuth: authreq.Config{ + URL: "foo.com/auth", + }, + Path: "/cat", + } + + encodedAuthURL := strings.Replace(base64.URLEncoding.EncodeToString([]byte(loc.Path)), "=", "", -1) + externalAuthPath := fmt.Sprintf("external-auth-%v-default", encodedAuthURL) + + testCases := []struct { + title string + host string + expected string + }{ + {"valid host", "auth.my.site", fmt.Sprintf("%s-%s", "auth.my.site", externalAuthPath)}, + {"valid host", "your.auth.site", fmt.Sprintf("%s-%s", "your.auth.site", externalAuthPath)}, + {"empty host", "", ""}, + } + + for _, testCase := range testCases { + str := buildAuthUpstreamName(loc, testCase.host) + if str != testCase.expected { + t.Errorf("%v: expected '%v' but returned '%v'", testCase.title, testCase.expected, str) + } + } +} + +func TestShouldApplyAuthUpstream(t *testing.T) { + authURL := "foo.com/auth" + + loc := &ingress.Location{ + ExternalAuth: authreq.Config{ + URL: authURL, + KeepaliveConnections: 0, + }, + Path: "/cat", + } + + cfg := config.Configuration{ + UseHTTP2: false, + } + + testCases := []struct { + title string + authURL string + keepaliveConnections int + expected bool + }{ + {"authURL, no keepalive", authURL, 0, false}, + {"authURL, keepalive", authURL, 10, true}, + {"empty, no keepalive", "", 0, false}, + {"empty, keepalive", "", 10, false}, + } + + for _, testCase := range testCases { + loc.ExternalAuth.URL = testCase.authURL + loc.ExternalAuth.KeepaliveConnections = testCase.keepaliveConnections + + result := shouldApplyAuthUpstream(loc, cfg) + if result != testCase.expected { + t.Errorf("%v: expected '%v' but returned '%v'", testCase.title, testCase.expected, result) + } + } + + // keepalive is not supported with UseHTTP2 + cfg.UseHTTP2 = true + for _, testCase := range testCases { + loc.ExternalAuth.URL = testCase.authURL + loc.ExternalAuth.KeepaliveConnections = testCase.keepaliveConnections + + result := shouldApplyAuthUpstream(loc, cfg) + if result != false { + t.Errorf("%v: expected '%v' but returned '%v'", testCase.title, false, result) + } + } +} + +func TestExtractHostPort(t *testing.T) { + testCases := []struct { + title string + url string + expected string + }{ + {"full URL", "https://my.auth.site:5000/path", "my.auth.site:5000"}, + {"URL with no port", "http://my.auth.site/path", "my.auth.site"}, + {"URL with no path", "https://my.auth.site:5000", "my.auth.site:5000"}, + {"URL no port and path", "http://my.auth.site", "my.auth.site"}, + {"missing method", "my.auth.site/path", ""}, + {"all empty", "", ""}, + } + + for _, testCase := range testCases { + result := extractHostPort(testCase.url) + if result != testCase.expected { + t.Errorf("%v: expected '%v' but returned '%v'", testCase.title, testCase.expected, result) + } + } +} + +func TestChangeHostPort(t *testing.T) { + testCases := []struct { + title string + url string + host string + expected string + }{ + {"full URL", "https://my.auth.site:5000/path", "your.domain", "https://your.domain/path"}, + {"URL with no port", "http://my.auth.site/path", "your.domain", "http://your.domain/path"}, + {"URL with no path", "http://my.auth.site:5000", "your.domain:8888", "http://your.domain:8888"}, + {"URL with no port and path", "https://my.auth.site", "your.domain:8888", "https://your.domain:8888"}, + {"invalid host", "my.auth.site/path", "", ""}, + {"missing method", "my.auth.site/path", "your.domain", ""}, + {"all empty", "", "", ""}, + } + + for _, testCase := range testCases { + result := changeHostPort(testCase.url, testCase.host) + if result != testCase.expected { + t.Errorf("%v: expected '%v' but returned '%v'", testCase.title, testCase.expected, result) + } + } +} + func TestTemplateWithData(t *testing.T) { pwd, _ := os.Getwd() f, err := os.Open(path.Join(pwd, "../../../../test/data/config.json")) diff --git a/internal/ingress/controller/util.go b/internal/ingress/controller/util.go index 91e0c3acf..a8232ed0e 100644 --- a/internal/ingress/controller/util.go +++ b/internal/ingress/controller/util.go @@ -29,7 +29,7 @@ import ( networking "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress" - "k8s.io/klog/v2" + klog "k8s.io/klog/v2" ) // newUpstream creates an upstream without servers. @@ -98,7 +98,7 @@ func rlimitMaxNumFiles() int { } const ( - defBinary = "/usr/local/nginx/sbin/nginx" + defBinary = "/usr/bin/nginx" cfgPath = "/etc/nginx/nginx.conf" ) diff --git a/internal/ingress/inspector/ingress.go b/internal/ingress/inspector/ingress.go new file mode 100644 index 000000000..12db946ea --- /dev/null +++ b/internal/ingress/inspector/ingress.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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 inspector + +import ( + "fmt" + + networking "k8s.io/api/networking/v1" +) + +// InspectIngress is used to do the deep inspection of an ingress object, walking through all +// of the spec fields and checking for matching strings and configurations that may represent +// an attempt to escape configs +func InspectIngress(ingress *networking.Ingress) error { + for _, rule := range ingress.Spec.Rules { + if rule.Host != "" { + if err := CheckRegex(rule.Host); err != nil { + return fmt.Errorf("invalid host in ingress %s/%s: %s", ingress.Namespace, ingress.Name, err) + } + } + if rule.HTTP != nil { + if err := inspectIngressRule(rule.HTTP); err != nil { + return fmt.Errorf("invalid rule in ingress %s/%s: %s", ingress.Namespace, ingress.Name, err) + } + } + } + + for _, tls := range ingress.Spec.TLS { + if err := CheckRegex(tls.SecretName); err != nil { + return fmt.Errorf("invalid secret in ingress %s/%s: %s", ingress.Namespace, ingress.Name, err) + } + for _, host := range tls.Hosts { + if err := CheckRegex(host); err != nil { + return fmt.Errorf("invalid host in ingress tls config %s/%s: %s", ingress.Namespace, ingress.Name, err) + } + } + } + return nil +} + +func inspectIngressRule(httprule *networking.HTTPIngressRuleValue) error { + for _, path := range httprule.Paths { + if err := CheckRegex(path.Path); err != nil { + return fmt.Errorf("invalid http path: %s", err) + } + } + return nil +} diff --git a/internal/ingress/inspector/ingress_test.go b/internal/ingress/inspector/ingress_test.go new file mode 100644 index 000000000..bfd9f6b93 --- /dev/null +++ b/internal/ingress/inspector/ingress_test.go @@ -0,0 +1,99 @@ +/* +Copyright 2022 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 inspector + +import ( + "testing" + + networking "k8s.io/api/networking/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func makeSimpleIngress(hostname string, paths ...string) *networking.Ingress { + + newIngress := networking.Ingress{ + ObjectMeta: v1.ObjectMeta{ + Name: "test1", + Namespace: "default", + }, + Spec: networking.IngressSpec{ + Rules: []networking.IngressRule{ + { + Host: hostname, + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{}, + }, + }, + }, + }, + }, + } + + prefix := networking.PathTypePrefix + for _, path := range paths { + newPath := networking.HTTPIngressPath{ + Path: path, + PathType: &prefix, + } + newIngress.Spec.Rules[0].IngressRuleValue.HTTP.Paths = append(newIngress.Spec.Rules[0].IngressRuleValue.HTTP.Paths, newPath) + } + return &newIngress +} + +func TestInspectIngress(t *testing.T) { + tests := []struct { + name string + hostname string + path []string + wantErr bool + }{ + { + name: "invalid-path-etc", + hostname: "invalid.etc.com", + path: []string{ + "/var/run/secrets", + "/mypage", + }, + wantErr: true, + }, + { + name: "invalid-path-etc", + hostname: "invalid.etc.com", + path: []string{ + "/etc/nginx", + }, + wantErr: true, + }, + { + name: "invalid-path-etc", + hostname: "invalid.etc.com", + path: []string{ + "/mypage", + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ingress := makeSimpleIngress(tt.hostname, tt.path...) + if err := InspectIngress(ingress); (err != nil) != tt.wantErr { + t.Errorf("InspectIngress() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/ingress/inspector/inspector.go b/internal/ingress/inspector/inspector.go new file mode 100644 index 000000000..98f257997 --- /dev/null +++ b/internal/ingress/inspector/inspector.go @@ -0,0 +1,38 @@ +/* +Copyright 2022 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 inspector + +import ( + corev1 "k8s.io/api/core/v1" + networking "k8s.io/api/networking/v1" + "k8s.io/klog/v2" +) + +// DeepInspect is the function called by admissionwebhook and store syncer to check +// if an object contains invalid configurations that may represent a security risk, +// and returning an error in this case +func DeepInspect(obj interface{}) error { + switch obj.(type) { + case *networking.Ingress: + return InspectIngress(obj.(*networking.Ingress)) + case *corev1.Service: + return InspectService(obj.(*corev1.Service)) + default: + klog.Warningf("received invalid object to inspect: %T", obj) + return nil + } +} diff --git a/internal/ingress/inspector/rules.go b/internal/ingress/inspector/rules.go new file mode 100644 index 000000000..ab573b7fe --- /dev/null +++ b/internal/ingress/inspector/rules.go @@ -0,0 +1,53 @@ +/* +Copyright 2022 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 inspector + +import ( + "fmt" + "regexp" +) + +var ( + invalidAliasDirective = regexp.MustCompile(`(?s)\s*alias\s*.*;`) + invalidRootDirective = regexp.MustCompile(`(?s)\s*root\s*.*;`) + invalidEtcDir = regexp.MustCompile(`/etc/(passwd|shadow|group|nginx|ingress-controller)`) + invalidSecretsDir = regexp.MustCompile(`/var/run/secrets`) + invalidByLuaDirective = regexp.MustCompile(`.*_by_lua.*`) + + invalidRegex = []regexp.Regexp{} +) + +func init() { + invalidRegex = []regexp.Regexp{ + *invalidAliasDirective, + *invalidRootDirective, + *invalidEtcDir, + *invalidSecretsDir, + *invalidByLuaDirective, + } +} + +// CheckRegex receives a value/configuration and validates if it matches with one of the +// forbidden regexes. +func CheckRegex(value string) error { + for _, regex := range invalidRegex { + if regex.MatchString(value) { + return fmt.Errorf("invalid value found: %s", value) + } + } + return nil +} diff --git a/internal/ingress/inspector/rules_test.go b/internal/ingress/inspector/rules_test.go new file mode 100644 index 000000000..6ed6dbe87 --- /dev/null +++ b/internal/ingress/inspector/rules_test.go @@ -0,0 +1,71 @@ +/* +Copyright 2022 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 inspector + +import "testing" + +func TestCheckRegex(t *testing.T) { + + tests := []struct { + name string + value string + wantErr bool + }{ + { + name: "must refuse invalid root", + wantErr: true, + value: " root blabla/lala ;", + }, + { + name: "must refuse invalid alias", + wantErr: true, + value: " alias blabla/lala ;", + }, + { + name: "must refuse invalid alias with line break", + wantErr: true, + value: "alias #\n/lalala/1/;", + }, + { + name: "must refuse invalid attempt to call /etc", + wantErr: true, + value: "location /etc/nginx/lalala", + }, + { + name: "must refuse invalid attempt to call k8s secret", + wantErr: true, + value: "ssl_cert /var/run/secrets/kubernetes.io/lalala; xpto", + }, + { + name: "must refuse invalid attempt to call lua directives", + wantErr: true, + value: "set_by_lua lala", + }, + { + name: "must pass with valid configuration", + wantErr: false, + value: "/test/mypage1", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := CheckRegex(tt.value); (err != nil) != tt.wantErr { + t.Errorf("CheckRegex() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/internal/ingress/inspector/service.go b/internal/ingress/inspector/service.go new file mode 100644 index 000000000..27ed27a8c --- /dev/null +++ b/internal/ingress/inspector/service.go @@ -0,0 +1,26 @@ +/* +Copyright 2022 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 inspector + +import ( + corev1 "k8s.io/api/core/v1" +) + +// InspectService will be used to inspect service objects for possible invalid configurations +func InspectService(svc *corev1.Service) error { + return nil +} diff --git a/internal/ingress/metric/collectors/socket.go b/internal/ingress/metric/collectors/socket.go index 0cbeeb4a6..26aebbaef 100644 --- a/internal/ingress/metric/collectors/socket.go +++ b/internal/ingress/metric/collectors/socket.go @@ -85,7 +85,8 @@ type SocketCollector struct { hosts sets.String - metricsPerHost bool + metricsPerHost bool + reportStatusClasses bool buckets HistogramBuckets } @@ -110,8 +111,8 @@ var defObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001} // NewSocketCollector creates a new SocketCollector instance using // the ingress watch namespace and class used by the controller -func NewSocketCollector(pod, namespace, class string, metricsPerHost bool, buckets HistogramBuckets) (*SocketCollector, error) { - socket := "/tmp/prometheus-nginx.socket" +func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStatusClasses bool, buckets HistogramBuckets) (*SocketCollector, error) { + socket := "/tmp/nginx/prometheus-nginx.socket" // unix sockets must be unlink()ed before being used _ = syscall.Unlink(socket) @@ -139,7 +140,8 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost bool, bucke sc := &SocketCollector{ listener: listener, - metricsPerHost: metricsPerHost, + metricsPerHost: metricsPerHost, + reportStatusClasses: reportStatusClasses, responseTime: prometheus.NewHistogramVec( prometheus.HistogramOpts{ @@ -249,6 +251,10 @@ func (sc *SocketCollector) handleMessage(msg []byte) { continue } + if sc.reportStatusClasses && len(stats.Status) > 0 { + stats.Status = fmt.Sprintf("%cxx", stats.Status[0]) + } + // Note these must match the order in requestTags at the top requestLabels := prometheus.Labels{ "status": stats.Status, diff --git a/internal/ingress/metric/collectors/socket_test.go b/internal/ingress/metric/collectors/socket_test.go index 8542d273c..11af7c06d 100644 --- a/internal/ingress/metric/collectors/socket_test.go +++ b/internal/ingress/metric/collectors/socket_test.go @@ -80,12 +80,13 @@ func TestCollector(t *testing.T) { } cases := []struct { - name string - data []string - metrics []string - wantBefore string - removeIngresses []string - wantAfter string + name string + data []string + metrics []string + useStatusClasses bool + wantBefore string + removeIngresses []string + wantAfter string }{ { name: "invalid metric object should not increase prometheus metrics", @@ -371,13 +372,55 @@ func TestCollector(t *testing.T) { wantAfter: ` `, }, + { + name: "valid metric object with status classes should update prometheus metrics", + data: []string{`[{ + "host":"testshop.com", + "status":"200", + "bytesSent":150.0, + "method":"GET", + "path":"/admin", + "requestLength":300.0, + "requestTime":60.0, + "upstreamName":"test-upstream", + "upstreamIP":"1.1.1.1:8080", + "upstreamResponseTime":200, + "upstreamStatus":"220", + "namespace":"test-app-production", + "ingress":"web-yml", + "service":"test-app", + "canary":"" + }]`}, + metrics: []string{"nginx_ingress_controller_response_duration_seconds"}, + useStatusClasses: true, + wantBefore: ` + # HELP nginx_ingress_controller_response_duration_seconds The time spent on receiving the response from the upstream server + # TYPE nginx_ingress_controller_response_duration_seconds histogram + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.005"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.01"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.025"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.05"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.1"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.25"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.5"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="1"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="2.5"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="5"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="10"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="+Inf"} 1 + nginx_ingress_controller_response_duration_seconds_sum{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx"} 200 + nginx_ingress_controller_response_duration_seconds_count{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx"} 1 + `, + wantAfter: ` + `, + }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { registry := prometheus.NewPedanticRegistry() - sc, err := NewSocketCollector("pod", "default", "ingress", true, buckets) + sc, err := NewSocketCollector("pod", "default", "ingress", true, c.useStatusClasses, buckets) if err != nil { t.Errorf("%v: unexpected error creating new SocketCollector: %v", c.name, err) } diff --git a/internal/ingress/metric/main.go b/internal/ingress/metric/main.go index 97a8ca7d4..a0aea1e71 100644 --- a/internal/ingress/metric/main.go +++ b/internal/ingress/metric/main.go @@ -69,7 +69,7 @@ type collector struct { } // NewCollector creates a new metric collector the for ingress controller -func NewCollector(metricsPerHost bool, registry *prometheus.Registry, ingressclass string, buckets collectors.HistogramBuckets) (Collector, error) { +func NewCollector(metricsPerHost, reportStatusClasses bool, registry *prometheus.Registry, ingressclass string, buckets collectors.HistogramBuckets) (Collector, error) { podNamespace := os.Getenv("POD_NAMESPACE") if podNamespace == "" { podNamespace = "default" @@ -87,7 +87,7 @@ func NewCollector(metricsPerHost bool, registry *prometheus.Registry, ingresscla return nil, err } - s, err := collectors.NewSocketCollector(podName, podNamespace, ingressclass, metricsPerHost, buckets) + s, err := collectors.NewSocketCollector(podName, podNamespace, ingressclass, metricsPerHost, reportStatusClasses, buckets) if err != nil { return nil, err } diff --git a/internal/nginx/main.go b/internal/nginx/main.go index 485b7d229..88d2ee877 100644 --- a/internal/nginx/main.go +++ b/internal/nginx/main.go @@ -28,7 +28,7 @@ import ( "time" ps "github.com/mitchellh/go-ps" - "k8s.io/klog/v2" + klog "k8s.io/klog/v2" ) // TODO: Check https://github.com/kubernetes/kubernetes/blob/master/pkg/master/ports/ports.go for ports already being used @@ -40,7 +40,7 @@ var ProfilerPort = 10245 var TemplatePath = "/etc/nginx/template/nginx.tmpl" // PID defines the location of the pid file used by NGINX -var PID = "/tmp/nginx.pid" +var PID = "/tmp/nginx/nginx.pid" // StatusPort port used by NGINX for the status server var StatusPort = 10246 diff --git a/rootfs/Dockerfile b/rootfs/Dockerfile index 5a8af2a6d..0bf9a0304 100644 --- a/rootfs/Dockerfile +++ b/rootfs/Dockerfile @@ -31,6 +31,8 @@ LABEL org.opencontainers.image.revision="${COMMIT_SHA}" LABEL build_id="${BUILD_ID}" +ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/modules_mount/etc/nginx/modules/modules + WORKDIR /etc/nginx RUN apk update \ @@ -54,6 +56,7 @@ RUN bash -xeu -c ' \ /etc/ingress-controller/auth \ /var/log \ /var/log/nginx \ + /tmp/nginx \ ); \ for dir in "${writeDirs[@]}"; do \ mkdir -p ${dir}; \ @@ -67,7 +70,8 @@ RUN apk add --no-cache libcap \ && setcap -v cap_net_bind_service=+ep /usr/local/nginx/sbin/nginx \ && setcap cap_net_bind_service=+ep /usr/bin/dumb-init \ && setcap -v cap_net_bind_service=+ep /usr/bin/dumb-init \ - && apk del libcap + && apk del libcap \ + && ln -sf /usr/local/nginx/sbin/nginx /usr/bin/nginx USER www-data diff --git a/rootfs/Dockerfile.chroot b/rootfs/Dockerfile.chroot new file mode 100644 index 000000000..04adccf8a --- /dev/null +++ b/rootfs/Dockerfile.chroot @@ -0,0 +1,120 @@ +# Copyright 2022 The Kubernetes Authors. All rights reserved. +# +# 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 + +ARG BASE_IMAGE + +FROM ${BASE_IMAGE} as chroot + +# This intermediary image will be used only to copy all the required files to the chroot +# TODO: Simplify in a future to a single Dockerfile +COPY chroot.sh /chroot.sh +RUN apk update \ + && apk upgrade \ + && /chroot.sh + +FROM alpine:3.14.6 + +ARG TARGETARCH +ARG VERSION +ARG COMMIT_SHA +ARG BUILD_ID=UNSET + +LABEL org.opencontainers.image.title="NGINX Ingress Controller for Kubernetes" +LABEL org.opencontainers.image.documentation="https://kubernetes.github.io/ingress-nginx/" +LABEL org.opencontainers.image.source="https://github.com/kubernetes/ingress-nginx" +LABEL org.opencontainers.image.vendor="The Kubernetes Authors" +LABEL org.opencontainers.image.licenses="Apache-2.0" +LABEL org.opencontainers.image.version="${VERSION}" +LABEL org.opencontainers.image.revision="${COMMIT_SHA}" + +LABEL build_id="${BUILD_ID}" + +# This will be injected in the chroot. Don't change :) +ENV LUA_PATH="/usr/local/share/luajit-2.1.0-beta3/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/lib/lua/?.lua;;" +ENV LUA_CPATH="/usr/local/lib/lua/?/?.so;/usr/local/lib/lua/?.so;;" +ENV PATH=$PATH:/usr/local/luajit/bin:/usr/local/nginx/sbin:/usr/local/nginx/bin +ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/modules_mount/etc/nginx/modules/modules + +RUN apk update \ + && apk upgrade \ + && apk add -U --no-cache \ + bash \ + curl \ + openssl \ + ca-certificates \ + dumb-init \ + tzdata \ + diffutils \ + util-linux \ + && ln -s /usr/local/nginx/sbin/nginx /sbin/nginx \ + && adduser -S -D -H -u 101 -h /usr/local/nginx \ + -s /sbin/nologin -G www-data -g www-data www-data + +COPY --from=chroot /chroot /chroot + +COPY --chown=www-data:www-data etc /chroot/etc + +COPY --chown=www-data:www-data bin/${TARGETARCH}/dbg / +COPY --chown=www-data:www-data bin/${TARGETARCH}/nginx-ingress-controller / +COPY --chown=www-data:www-data bin/${TARGETARCH}/wait-shutdown / +COPY --chown=www-data:www-data nginx-chroot-wrapper.sh /usr/bin/nginx + +WORKDIR /chroot/etc/nginx + +# Fix permission during the build to avoid issues at runtime +# with volumes (custom templates) +RUN bash -xeu -c ' \ + writeDirs=( \ + /var/log \ + ); \ + for dir in "${writeDirs[@]}"; do \ + mkdir -p ${dir}; \ + chown -R www-data.www-data ${dir}; \ + done' + +RUN apk add --no-cache libcap \ + && setcap cap_sys_chroot,cap_net_bind_service=+ep /nginx-ingress-controller \ + && setcap -v cap_sys_chroot,cap_net_bind_service=+ep /nginx-ingress-controller \ + && setcap cap_sys_chroot,cap_net_bind_service=+ep /usr/bin/unshare \ + && setcap -v cap_sys_chroot,cap_net_bind_service=+ep /usr/bin/unshare \ + && setcap cap_net_bind_service=+ep /chroot/usr/local/nginx/sbin/nginx \ + && setcap -v cap_net_bind_service=+ep /chroot/usr/local/nginx/sbin/nginx \ + && setcap cap_sys_chroot,cap_net_bind_service=+ep /usr/bin/dumb-init \ + && setcap -v cap_sys_chroot,cap_net_bind_service=+ep /usr/bin/dumb-init \ + && apk del libcap + +RUN ln -sf /chroot/etc/nginx /etc/nginx \ + && ln -sf /chroot/tmp/nginx /tmp/nginx \ + && ln -sf /chroot/etc/ingress-controller /etc/ingress-controller \ + && ln -sf /chroot/var/log/nginx /var/log/nginx \ + && touch /chroot/var/log/nginx/access.log \ + && chown www-data:www-data /chroot/var/log/nginx/access.log \ + && echo "" > /chroot/etc/resolv.conf \ + && chown -R www-data.www-data /chroot/var/log/nginx /chroot/etc/resolv.conf \ + && mknod -m 0666 /chroot/dev/null c 1 3 \ + && mknod -m 0666 /chroot/dev/random c 1 8 \ + && mknod -m 0666 /chroot/dev/urandom c 1 9 \ + && mknod -m 0666 /chroot/dev/full c 1 7 \ + && mknod -m 0666 /chroot/dev/ptmx c 5 2 \ + && mknod -m 0666 /chroot/dev/zero c 1 5 \ + && mknod -m 0666 /chroot/dev/tty c 5 0 + +USER www-data + +EXPOSE 80 443 + +ENTRYPOINT ["/usr/bin/dumb-init", "--"] + +CMD ["/nginx-ingress-controller"] + diff --git a/rootfs/chroot.sh b/rootfs/chroot.sh new file mode 100755 index 000000000..9f3cbd804 --- /dev/null +++ b/rootfs/chroot.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Copyright 2022 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. + +set -x +writeDirs=( \ + /chroot/etc/nginx \ + /chroot/usr/local/ \ + /chroot/etc/ingress-controller \ + /chroot/etc/ingress-controller/ssl \ + /chroot/etc/ingress-controller/auth \ + /chroot/opt/modsecurity/var/log \ + /chroot/opt/modsecurity/var/upload \ + /chroot/opt/modsecurity/var/audit \ + /chroot/var/log/audit \ + /chroot/var/lib/nginx \ + /chroot/var/log/nginx \ + /chroot/var/lib/nginx/body \ + /chroot/var/lib/nginx/fastcgi \ + /chroot/var/lib/nginx/proxy \ + /chroot/var/lib/nginx/scgi \ + /chroot/var/lib/nginx/uwsgi \ + /chroot/tmp/nginx +); + +for dir in "${writeDirs[@]}"; do + mkdir -p ${dir}; + chown -R www-data.www-data ${dir}; +done + +mkdir -p /chroot/lib /chroot/proc /chroot/usr /chroot/bin /chroot/dev /chroot/run +cp /etc/passwd /etc/group /chroot/etc/ +cp -a /usr/* /chroot/usr/ +cp -a /etc/nginx/* /chroot/etc/nginx/ +cp /lib/ld-musl-* /lib/libcrypto* /lib/libssl* /lib/libz* /chroot/lib/ diff --git a/rootfs/etc/nginx/lua/monitor.lua b/rootfs/etc/nginx/lua/monitor.lua index be7a173ee..8b0e18596 100644 --- a/rootfs/etc/nginx/lua/monitor.lua +++ b/rootfs/etc/nginx/lua/monitor.lua @@ -26,7 +26,7 @@ local _M = {} local function send(payload) local s = assert(socket()) - assert(s:connect("unix:/tmp/prometheus-nginx.socket")) + assert(s:connect("unix:/tmp/nginx/prometheus-nginx.socket")) assert(s:send(payload)) assert(s:close()) end diff --git a/rootfs/etc/nginx/lua/plugins/README.md b/rootfs/etc/nginx/lua/plugins/README.md index 0626a48ff..64f4912f0 100644 --- a/rootfs/etc/nginx/lua/plugins/README.md +++ b/rootfs/etc/nginx/lua/plugins/README.md @@ -9,7 +9,7 @@ Every ingress-nginx Lua plugin is expected to have `main.lua` file and all of it `main.lua` is the entry point of the plugin. The plugin manager uses convention over configuration strategy and automatically runs functions defined in `main.lua` in the corresponding Nginx phase based on their name. -Nginx has different [request processing phases](http://nginx.org/en/docs/dev/development_guide.html#http_phases). +Nginx has different [request processing phases](https://nginx.org/en/docs/dev/development_guide.html#http_phases). By defining functions with the following names, you can run your custom Lua code in the corresponding Nginx phase: - `init_worker`: useful for initializing some data per Nginx worker process diff --git a/rootfs/etc/nginx/lua/test/monitor_test.lua b/rootfs/etc/nginx/lua/test/monitor_test.lua index 2762a980d..e75018adf 100644 --- a/rootfs/etc/nginx/lua/test/monitor_test.lua +++ b/rootfs/etc/nginx/lua/test/monitor_test.lua @@ -148,7 +148,7 @@ describe("Monitor", function() }, }) - assert.stub(tcp_mock.connect).was_called_with(tcp_mock, "unix:/tmp/prometheus-nginx.socket") + assert.stub(tcp_mock.connect).was_called_with(tcp_mock, "unix:/tmp/nginx/prometheus-nginx.socket") assert.stub(tcp_mock.send).was_called_with(tcp_mock, expected_payload) assert.stub(tcp_mock.close).was_called_with(tcp_mock) end) diff --git a/rootfs/etc/nginx/nginx.conf b/rootfs/etc/nginx/nginx.conf index 6f8e86b90..7f60b846d 100644 --- a/rootfs/etc/nginx/nginx.conf +++ b/rootfs/etc/nginx/nginx.conf @@ -1,6 +1,8 @@ # A very simple nginx configuration file that forces nginx to start. -pid /tmp/nginx.pid; +pid /tmp/nginx/nginx.pid; + +error_log stderr; events {} http {} -daemon off; \ No newline at end of file +daemon off; diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index 2ee76831c..561278b6f 100755 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -58,6 +58,9 @@ events { multi_accept {{ if $cfg.EnableMultiAccept }}on{{ else }}off{{ end }}; worker_connections {{ $cfg.MaxWorkerConnections }}; use epoll; + {{ range $index , $v := $cfg.DebugConnections }} + debug_connection {{ $v }}; + {{ end }} } http { @@ -156,7 +159,7 @@ http { {{ else }} modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf; {{ end }} - + {{ if $all.Cfg.EnableOWASPCoreRules }} modsecurity_rules_file /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf; {{ end }} @@ -285,10 +288,10 @@ http { keepalive_timeout {{ $cfg.KeepAlive }}s; keepalive_requests {{ $cfg.KeepAliveRequests }}; - client_body_temp_path /tmp/client-body; - fastcgi_temp_path /tmp/fastcgi-temp; - proxy_temp_path /tmp/proxy-temp; - ajp_temp_path /tmp/ajp-temp; + client_body_temp_path /tmp/nginx/client-body; + fastcgi_temp_path /tmp/nginx/fastcgi-temp; + proxy_temp_path /tmp/nginx/proxy-temp; + ajp_temp_path /tmp/nginx/ajp-temp; client_header_buffer_size {{ $cfg.ClientHeaderBufferSize }}; client_header_timeout {{ $cfg.ClientHeaderTimeout }}s; @@ -508,7 +511,7 @@ http { {{ if (gt $cfg.UpstreamKeepaliveConnections 0) }} keepalive {{ $cfg.UpstreamKeepaliveConnections }}; - + keepalive_time {{ $cfg.UpstreamKeepaliveTime }}; keepalive_timeout {{ $cfg.UpstreamKeepaliveTimeout }}s; keepalive_requests {{ $cfg.UpstreamKeepaliveRequests }}; {{ end }} @@ -536,7 +539,7 @@ http { {{ end }} # Cache for internal auth checks - proxy_cache_path /tmp/nginx-cache-auth levels=1:2 keys_zone=auth_cache:10m max_size=128m inactive=30m use_temp_path=off; + proxy_cache_path /tmp/nginx/nginx-cache-auth levels=1:2 keys_zone=auth_cache:10m max_size=128m inactive=30m use_temp_path=off; # Global filters {{ range $ip := $cfg.BlockCIDRs }}deny {{ trimSpace $ip }}; @@ -591,7 +594,12 @@ http { end {{ if $cfg.UseForwardedHeaders }} - local redirectScheme = ngx.var.http_x_forwarded_proto + local redirectScheme + if not ngx.var.http_x_forwarded_proto then + redirectScheme = ngx.var.scheme + else + redirectScheme = ngx.var.http_x_forwarded_proto + end {{ else }} local redirectScheme = ngx.var.scheme {{ end }} @@ -610,7 +618,25 @@ http { {{ end }} {{ range $server := $servers }} + {{ range $location := $server.Locations }} + {{ $applyGlobalAuth := shouldApplyGlobalAuth $location $all.Cfg.GlobalExternalAuth.URL }} + {{ $applyAuthUpstream := shouldApplyAuthUpstream $location $all.Cfg }} + {{ if and (eq $applyAuthUpstream true) (eq $applyGlobalAuth false) }} + ## start auth upstream {{ $server.Hostname }}{{ $location.Path }} + upstream {{ buildAuthUpstreamName $location $server.Hostname }} { + {{- $externalAuth := $location.ExternalAuth }} + server {{ extractHostPort $externalAuth.URL }}; + keepalive {{ $externalAuth.KeepaliveConnections }}; + keepalive_requests {{ $externalAuth.KeepaliveRequests }}; + keepalive_timeout {{ $externalAuth.KeepaliveTimeout }}s; + } + ## end auth upstream {{ $server.Hostname }}{{ $location.Path }} + {{ end }} + {{ end }} + {{ end }} + + {{ range $server := $servers }} ## start server {{ $server.Hostname }} server { server_name {{ buildServerName $server.Hostname }} {{range $server.Aliases }}{{ . }} {{ end }}; @@ -633,7 +659,7 @@ http { {{ $cfg.ServerSnippet }} {{ end }} - {{ template "CUSTOM_ERRORS" (buildCustomErrorDeps "upstream-default-backend" $cfg.CustomHTTPErrors $all.EnableMetrics) }} + {{ template "CUSTOM_ERRORS" (buildCustomErrorDeps "upstream-default-backend" $cfg.CustomHTTPErrors $all.EnableMetrics $cfg.EnableModsecurity) }} } ## end server {{ $server.Hostname }} @@ -755,8 +781,8 @@ stream { access_log {{ or $cfg.StreamAccessLogPath $cfg.AccessLogPath }} log_stream {{ $cfg.AccessLogParams }}; {{ end }} - error_log {{ $cfg.ErrorLogPath }} {{ $cfg.ErrorLogLevel }}; + error_log {{ $cfg.ErrorLogPath }} {{ $cfg.ErrorLogLevel }}; {{ if $cfg.EnableRealIp }} {{ range $trusted_ip := $cfg.ProxyRealIPCIDR }} set_real_ip_from {{ $trusted_ip }}; @@ -849,11 +875,17 @@ stream { {{/* definition of templates to avoid repetitions */}} {{ define "CUSTOM_ERRORS" }} {{ $enableMetrics := .EnableMetrics }} + {{ $modsecurityEnabled := .ModsecurityEnabled }} {{ $upstreamName := .UpstreamName }} {{ range $errCode := .ErrorCodes }} location @custom_{{ $upstreamName }}_{{ $errCode }} { internal; + # Ensure that modsecurity will not run on custom error pages or they might be blocked + {{ if $modsecurityEnabled }} + modsecurity off; + {{ end }} + proxy_intercept_errors off; proxy_set_header X-Code {{ $errCode }}; @@ -923,6 +955,14 @@ stream { set $proxy_upstream_name "-"; + {{ if not ( empty $server.CertificateAuth.MatchCN ) }} + {{ if gt (len $server.CertificateAuth.MatchCN) 0 }} + if ( $ssl_client_s_dn !~ {{ $server.CertificateAuth.MatchCN }} ) { + return 403 "client certificate unauthorized"; + } + {{ end }} + {{ end }} + {{ if eq $server.Hostname "_" }} ssl_reject_handshake {{ if $all.Cfg.SSLRejectHandshake }}on{{ else }}off{{ end }}; {{ end }} @@ -984,7 +1024,7 @@ stream { {{ end }} {{ range $errorLocation := (buildCustomErrorLocationsPerServer $server) }} - {{ template "CUSTOM_ERRORS" (buildCustomErrorDeps $errorLocation.UpstreamName $errorLocation.Codes $all.EnableMetrics) }} + {{ template "CUSTOM_ERRORS" (buildCustomErrorDeps $errorLocation.UpstreamName $errorLocation.Codes $all.EnableMetrics $all.Cfg.EnableModsecurity) }} {{ end }} {{ buildMirrorLocations $server.Locations }} @@ -995,6 +1035,7 @@ stream { {{ $proxySetHeader := proxySetHeader $location }} {{ $authPath := buildAuthLocation $location $all.Cfg.GlobalExternalAuth.URL }} {{ $applyGlobalAuth := shouldApplyGlobalAuth $location $all.Cfg.GlobalExternalAuth.URL }} + {{ $applyAuthUpstream := shouldApplyAuthUpstream $location $all.Cfg }} {{ $externalAuth := $location.ExternalAuth }} {{ if eq $applyGlobalAuth true }} @@ -1016,6 +1057,11 @@ stream { opentracing_propagate_context; {{ end }} + # Ensure that modsecurity will not run on an internal location as this is not accessible from outside + {{ if $all.Cfg.EnableModsecurity }} + modsecurity off; + {{ end }} + {{ if $externalAuth.AuthCacheKey }} set $tmp_cache_key '{{ $server.Hostname }}{{ $authPath }}{{ $externalAuth.AuthCacheKey }}'; set $cache_key ''; @@ -1074,7 +1120,6 @@ stream { proxy_buffer_size {{ $location.Proxy.BufferSize }}; proxy_buffers {{ $location.Proxy.BuffersNumber }} {{ $location.Proxy.BufferSize }}; proxy_request_buffering {{ $location.Proxy.RequestBuffering }}; - proxy_http_version {{ $location.Proxy.ProxyHTTPVersion }}; proxy_ssl_server_name on; proxy_pass_request_headers on; @@ -1103,7 +1148,19 @@ stream { {{ $externalAuth.AuthSnippet }} {{ end }} + {{ if and (eq $applyAuthUpstream true) (eq $applyGlobalAuth false) }} + {{ $authUpstreamName := buildAuthUpstreamName $location $server.Hostname }} + # The target is an upstream with HTTP keepalive, that is why the + # Connection header is cleared and the HTTP version is set to 1.1 as + # the Nginx documentation suggests: + # http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive + proxy_http_version 1.1; + proxy_set_header Connection ""; + set $target {{ changeHostPort $externalAuth.URL $authUpstreamName }}; + {{ else }} + proxy_http_version {{ $location.Proxy.ProxyHTTPVersion }}; set $target {{ $externalAuth.URL }}; + {{ end }} proxy_pass $target; } {{ end }} @@ -1115,6 +1172,11 @@ stream { add_header Set-Cookie $auth_cookie; + # Ensure that modsecurity will not run on an internal location as this is not accessible from outside + {{ if $all.Cfg.EnableModsecurity }} + modsecurity off; + {{ end }} + return 302 {{ buildAuthSignURL $externalAuth.SigninURL $externalAuth.SigninURLRedirectParam }}; } {{ end }} @@ -1208,12 +1270,40 @@ stream { {{ if not (isLocationInLocationList $location $all.Cfg.NoAuthLocations) }} {{ if $authPath }} # this location requires authentication - auth_request {{ $authPath }}; - auth_request_set $auth_cookie $upstream_http_set_cookie; - add_header Set-Cookie $auth_cookie; - {{- range $line := buildAuthResponseHeaders $proxySetHeader $externalAuth.ResponseHeaders }} + {{ if and (eq $applyAuthUpstream true) (eq $applyGlobalAuth false) }} + set $auth_cookie ''; + add_header Set-Cookie $auth_cookie; + {{- range $line := buildAuthResponseHeaders $proxySetHeader $externalAuth.ResponseHeaders true }} {{ $line }} {{- end }} + # `auth_request` module does not support HTTP keepalives in upstream block: + # https://trac.nginx.org/nginx/ticket/1579 + access_by_lua_block { + local res = ngx.location.capture('{{ $authPath }}', { method = ngx.HTTP_GET, body = '' }) + if res.status == ngx.HTTP_OK then + ngx.var.auth_cookie = res.header['Set-Cookie'] + {{- range $line := buildAuthUpstreamLuaHeaders $externalAuth.ResponseHeaders }} + {{ $line }} + {{- end }} + return + end + if res.status == ngx.HTTP_FORBIDDEN then + ngx.exit(res.status) + end + ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) + } + {{ else }} + auth_request {{ $authPath }}; + auth_request_set $auth_cookie $upstream_http_set_cookie; + {{ if $externalAuth.AlwaysSetCookie }} + add_header Set-Cookie $auth_cookie always; + {{ else }} + add_header Set-Cookie $auth_cookie; + {{ end }} + {{- range $line := buildAuthResponseHeaders $proxySetHeader $externalAuth.ResponseHeaders false }} + {{ $line }} + {{- end }} + {{ end }} {{ end }} {{ if $externalAuth.SigninURL }} diff --git a/rootfs/nginx-chroot-wrapper.sh b/rootfs/nginx-chroot-wrapper.sh new file mode 100755 index 000000000..f7318142f --- /dev/null +++ b/rootfs/nginx-chroot-wrapper.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Copyright 2022 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. + +cat /etc/resolv.conf > /chroot/etc/resolv.conf +unshare -S 101 -R /chroot nginx "$@" diff --git a/test/data/cleanConf.expected.conf b/test/data/cleanConf.expected.conf index 5edad651b..1666c19f6 100644 --- a/test/data/cleanConf.expected.conf +++ b/test/data/cleanConf.expected.conf @@ -1,7 +1,7 @@ # Configuration checksum: # setup custom paths that do not require root access -pid /tmp/nginx.pid; +pid /tmp/nginx/nginx.pid; daemon off; diff --git a/test/data/cleanConf.src.conf b/test/data/cleanConf.src.conf index 81944e1ce..0e572faa5 100644 --- a/test/data/cleanConf.src.conf +++ b/test/data/cleanConf.src.conf @@ -1,7 +1,7 @@ # Configuration checksum: # setup custom paths that do not require root access -pid /tmp/nginx.pid; +pid /tmp/nginx/nginx.pid; diff --git a/test/e2e-image/Dockerfile b/test/e2e-image/Dockerfile index 002a002cd..ff6e9684a 100644 --- a/test/e2e-image/Dockerfile +++ b/test/e2e-image/Dockerfile @@ -1,6 +1,6 @@ -FROM k8s.gcr.io/ingress-nginx/e2e-test-runner:v20220331-controller-v1.1.2-31-gf1cb2b73c@sha256:baa326f5c726d65be828852943a259c1f0572883590b9081b7e8fa982d64d96e AS BASE +FROM registry.k8s.io/ingress-nginx/e2e-test-runner:v20220524-g8963ed17e@sha256:4fbcbeebd4c24587699b027ad0f0aa7cd9d76b58177a3b50c228bae8141bcf95 AS BASE -FROM alpine:3.14.4 +FROM alpine:3.14.6 RUN apk add -U --no-cache \ ca-certificates \ diff --git a/test/e2e-image/Makefile b/test/e2e-image/Makefile index f35c5db5b..3a012a2df 100644 --- a/test/e2e-image/Makefile +++ b/test/e2e-image/Makefile @@ -2,7 +2,10 @@ DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) image: + echo "..entered Makefile in /test/e2e-image" + echo "..calling Make target <> in /Makefile from inside /test/e2e-image/Makefile" make -C $(DIR)/../../ e2e-test-binary + echo "..done building e2e-test-binary from /test/e2e-image/Makefile" cp $(DIR)/../e2e/e2e.test . cp $(DIR)/../e2e/wait-for-nginx.sh . @@ -19,4 +22,4 @@ clean: docker rmi -f nginx-ingress-controller:e2e || true -.PHONY: image clean \ No newline at end of file +.PHONY: image clean diff --git a/test/e2e-image/namespace-overlays/admission/values.yaml b/test/e2e-image/namespace-overlays/admission/values.yaml index b88e8a02e..d423217db 100644 --- a/test/e2e-image/namespace-overlays/admission/values.yaml +++ b/test/e2e-image/namespace-overlays/admission/values.yaml @@ -3,8 +3,10 @@ fullnameOverride: nginx-ingress controller: image: repository: ingress-controller/controller + chroot: true tag: 1.0.0-dev digest: + digestChroot: containerPort: http: "1080" https: "1443" diff --git a/test/e2e-image/namespace-overlays/custom-health-check-path/values.yaml b/test/e2e-image/namespace-overlays/custom-health-check-path/values.yaml index 57bd1d105..4c6bef855 100644 --- a/test/e2e-image/namespace-overlays/custom-health-check-path/values.yaml +++ b/test/e2e-image/namespace-overlays/custom-health-check-path/values.yaml @@ -3,8 +3,10 @@ fullnameOverride: nginx-ingress controller: image: repository: ingress-controller/controller + chroot: true tag: 1.0.0-dev digest: + digestChroot: extraArgs: healthz-port: "9090" # e2e tests do not require information about ingress status diff --git a/test/e2e-image/namespace-overlays/forwarded-port-headers/values.yaml b/test/e2e-image/namespace-overlays/forwarded-port-headers/values.yaml index 4fef671a7..68b4a074c 100644 --- a/test/e2e-image/namespace-overlays/forwarded-port-headers/values.yaml +++ b/test/e2e-image/namespace-overlays/forwarded-port-headers/values.yaml @@ -3,8 +3,10 @@ fullnameOverride: nginx-ingress controller: image: repository: ingress-controller/controller + chroot: true tag: 1.0.0-dev digest: + digestChroot: containerPort: http: "1080" https: "1443" diff --git a/test/e2e-image/namespace-overlays/namespace-selector/values.yaml b/test/e2e-image/namespace-overlays/namespace-selector/values.yaml index e4c0e7a87..2c8957f66 100644 --- a/test/e2e-image/namespace-overlays/namespace-selector/values.yaml +++ b/test/e2e-image/namespace-overlays/namespace-selector/values.yaml @@ -3,8 +3,10 @@ fullnameOverride: nginx-ingress controller: image: repository: ingress-controller/controller + chroot: true tag: 1.0.0-dev digest: + digestChroot: containerPort: http: "1080" https: "1443" diff --git a/test/e2e/admission/admission.go b/test/e2e/admission/admission.go index c4c1ef76d..c03a10ecc 100644 --- a/test/e2e/admission/admission.go +++ b/test/e2e/admission/admission.go @@ -110,6 +110,23 @@ var _ = framework.IngressNginxDescribe("[Serial] admission controller", func() { assert.Nil(ginkgo.GinkgoT(), err, "creating an ingress with the same host and path should not return an error using a canary annotation") }) + ginkgo.It("should block ingress with invalid path", func() { + host := "invalid-path" + + firstIngress := framework.NewSingleIngress("valid-path", "/mypage", host, f.Namespace, framework.EchoService, 80, nil) + _, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Create(context.TODO(), firstIngress, metav1.CreateOptions{}) + assert.Nil(ginkgo.GinkgoT(), err, "creating ingress") + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, fmt.Sprintf("server_name %v", host)) + }) + + secondIngress := framework.NewSingleIngress("second-ingress", "/etc/nginx", host, f.Namespace, framework.EchoService, 80, nil) + _, err = f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Create(context.TODO(), secondIngress, metav1.CreateOptions{}) + assert.NotNil(ginkgo.GinkgoT(), err, "creating an ingress with invalid path should return an error") + }) + ginkgo.It("should return an error if there is an error validating the ingress definition", func() { host := "admission-test" diff --git a/test/e2e/annotations/auth.go b/test/e2e/annotations/auth.go index 7ca2fff45..d0ca5cf12 100644 --- a/test/e2e/annotations/auth.go +++ b/test/e2e/annotations/auth.go @@ -313,9 +313,12 @@ var _ = framework.DescribeAnnotation("auth-*", func() { }) }) - ginkgo.It("retains cookie set by external authentication server", func() { + ginkgo.Context("cookie set by external authentication server", func() { host := "auth-check-cookies" + var annotations map[string]string + var ing1, ing2 *networking.Ingress + cfg := `# events { worker_connections 1024; @@ -342,40 +345,81 @@ http { location / { return 200; } + + location /error { + return 503; + } } } ` + ginkgo.BeforeEach(func() { + f.NGINXWithConfigDeployment("http-cookie-with-error", cfg) - f.NGINXWithConfigDeployment(framework.HTTPBinService, cfg) + e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), "http-cookie-with-error", metav1.GetOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) - e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBinService, metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err) + assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets), 1, "expected at least one endpoint") + assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets[0].Addresses), 1, "expected at least one address ready in the endpoint") - assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets), 1, "expected at least one endpoint") - assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets[0].Addresses), 1, "expected at least one address ready in the endpoint") + httpbinIP := e.Subsets[0].Addresses[0].IP - httpbinIP := e.Subsets[0].Addresses[0].IP + annotations = map[string]string{ + "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/cookies/set/alma/armud", httpbinIP), + "nginx.ingress.kubernetes.io/auth-signin": "http://$host/auth/start", + } - annotations := map[string]string{ - "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/cookies/set/alma/armud", httpbinIP), - "nginx.ingress.kubernetes.io/auth-signin": "http://$host/auth/start", - } + ing1 = framework.NewSingleIngress(host, "/", host, f.Namespace, "http-cookie-with-error", 80, annotations) + f.EnsureIngress(ing1) - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) - f.EnsureIngress(ing) + ing2 = framework.NewSingleIngress(host+"-error", "/error", host, f.Namespace, "http-cookie-with-error", 80, annotations) + f.EnsureIngress(ing2) + + f.WaitForNginxServer(host, func(server string) bool { + return strings.Contains(server, "server_name "+host) + }) - f.WaitForNginxServer(host, func(server string) bool { - return strings.Contains(server, "server_name auth") }) - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - WithQuery("a", "b"). - WithQuery("c", "d"). - Expect(). - Status(http.StatusOK). - Header("Set-Cookie").Contains("alma=armud") + ginkgo.It("user retains cookie by default", func() { + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", host). + WithQuery("a", "b"). + WithQuery("c", "d"). + Expect(). + Status(http.StatusOK). + Header("Set-Cookie").Contains("alma=armud") + }) + + ginkgo.It("user does not retain cookie if upstream returns error status code", func() { + f.HTTPTestClient(). + GET("/error"). + WithHeader("Host", host). + WithQuery("a", "b"). + WithQuery("c", "d"). + Expect(). + Status(http.StatusServiceUnavailable). + Header("Set-Cookie").Contains("") + }) + + ginkgo.It("user with annotated ingress retains cookie if upstream returns error status code", func() { + annotations["nginx.ingress.kubernetes.io/auth-always-set-cookie"] = "true" + f.UpdateIngress(ing1) + f.UpdateIngress(ing2) + + f.WaitForNginxServer(host, func(server string) bool { + return strings.Contains(server, "server_name "+host) + }) + + f.HTTPTestClient(). + GET("/error"). + WithHeader("Host", host). + WithQuery("a", "b"). + WithQuery("c", "d"). + Expect(). + Status(http.StatusServiceUnavailable). + Header("Set-Cookie").Contains("alma=armud") + }) }) ginkgo.Context("when external authentication is configured", func() { @@ -476,6 +520,99 @@ http { Body(). NotContainsFold(fmt.Sprintf("%s=%s", rewriteHeader, rewriteVal)) }) + + ginkgo.It(`should not create additional upstream block when auth-keepalive is not set`, func() { + f.UpdateNginxConfigMapData("use-http2", "false") + defer func() { + f.UpdateNginxConfigMapData("use-http2", "true") + }() + // Sleep a while just to guarantee that the configmap is applied + framework.Sleep() + + annotations["nginx.ingress.kubernetes.io/auth-url"] = "http://foo.bar.baz:5000/path" + f.UpdateIngress(ing) + + f.WaitForNginxServer("", + func(server string) bool { + return strings.Contains(server, "http://foo.bar.baz:5000/path") && + !strings.Contains(server, `upstream auth-external-auth`) + }) + }) + + ginkgo.It(`should not create additional upstream block when host part of auth-url contains a variable`, func() { + f.UpdateNginxConfigMapData("use-http2", "false") + defer func() { + f.UpdateNginxConfigMapData("use-http2", "true") + }() + // Sleep a while just to guarantee that the configmap is applied + framework.Sleep() + + annotations["nginx.ingress.kubernetes.io/auth-url"] = "http://$host/path" + annotations["nginx.ingress.kubernetes.io/auth-keepalive"] = "123" + f.UpdateIngress(ing) + + f.WaitForNginxServer("", + func(server string) bool { + return strings.Contains(server, "http://$host/path") && + !strings.Contains(server, `upstream auth-external-auth`) && + !strings.Contains(server, `keepalive 123;`) + }) + }) + + ginkgo.It(`should not create additional upstream block when auth-keepalive is negative`, func() { + f.UpdateNginxConfigMapData("use-http2", "false") + defer func() { + f.UpdateNginxConfigMapData("use-http2", "true") + }() + // Sleep a while just to guarantee that the configmap is applied + framework.Sleep() + + annotations["nginx.ingress.kubernetes.io/auth-url"] = "http://foo.bar.baz:5000/path" + annotations["nginx.ingress.kubernetes.io/auth-keepalive"] = "-1" + f.UpdateIngress(ing) + + f.WaitForNginxServer("", + func(server string) bool { + return strings.Contains(server, "http://foo.bar.baz:5000/path") && + !strings.Contains(server, `upstream auth-external-auth`) + }) + }) + + ginkgo.It(`should not create additional upstream block when auth-keepalive is set with HTTP/2`, func() { + annotations["nginx.ingress.kubernetes.io/auth-url"] = "http://foo.bar.baz:5000/path" + annotations["nginx.ingress.kubernetes.io/auth-keepalive"] = "123" + annotations["nginx.ingress.kubernetes.io/auth-keepalive-requests"] = "456" + annotations["nginx.ingress.kubernetes.io/auth-keepalive-timeout"] = "789" + f.UpdateIngress(ing) + + f.WaitForNginxServer("", + func(server string) bool { + return strings.Contains(server, "http://foo.bar.baz:5000/path") && + !strings.Contains(server, `upstream auth-external-auth`) + }) + }) + + ginkgo.It(`should create additional upstream block when auth-keepalive is set with HTTP/1.x`, func() { + f.UpdateNginxConfigMapData("use-http2", "false") + defer func() { + f.UpdateNginxConfigMapData("use-http2", "true") + }() + // Sleep a while just to guarantee that the configmap is applied + framework.Sleep() + + annotations["nginx.ingress.kubernetes.io/auth-keepalive"] = "123" + annotations["nginx.ingress.kubernetes.io/auth-keepalive-requests"] = "456" + annotations["nginx.ingress.kubernetes.io/auth-keepalive-timeout"] = "789" + f.UpdateIngress(ing) + + f.WaitForNginxServer("", + func(server string) bool { + return strings.Contains(server, `upstream auth-external-auth`) && + strings.Contains(server, `keepalive 123;`) && + strings.Contains(server, `keepalive_requests 456;`) && + strings.Contains(server, `keepalive_timeout 789s;`) + }) + }) }) ginkgo.Context("when external authentication is configured with a custom redirect param", func() { diff --git a/test/e2e/annotations/authtls.go b/test/e2e/annotations/authtls.go index 790165475..dbf4f2a76 100644 --- a/test/e2e/annotations/authtls.go +++ b/test/e2e/annotations/authtls.go @@ -262,6 +262,93 @@ var _ = framework.DescribeAnnotation("auth-tls-*", func() { Status(http.StatusOK) }) + + ginkgo.It("should return 403 using auth-tls-match-cn with no matching CN from client", func() { + host := "authtls.foo.com" + nameSpace := f.Namespace + + clientConfig, err := framework.CreateIngressMASecret( + f.KubeClientSet, + host, + host, + nameSpace) + assert.Nil(ginkgo.GinkgoT(), err) + + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/auth-tls-secret": nameSpace + "/" + host, + "nginx.ingress.kubernetes.io/auth-tls-verify-client": "on", + "nginx.ingress.kubernetes.io/auth-tls-match-cn": "CN=notgonnamatch", + } + + f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, nameSpace, framework.EchoService, 80, annotations)) + + assertSslClientCertificateConfig(f, host, "on", "1") + + f.HTTPTestClientWithTLSConfig(clientConfig). + GET("/"). + WithURL(f.GetURL(framework.HTTPS)). + WithHeader("Host", host). + Expect(). + Status(http.StatusForbidden) + }) + + ginkgo.It("should return 200 using auth-tls-match-cn with matching CN from client", func() { + host := "authtls.foo.com" + nameSpace := f.Namespace + + clientConfig, err := framework.CreateIngressMASecret( + f.KubeClientSet, + host, + host, + nameSpace) + assert.Nil(ginkgo.GinkgoT(), err) + + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/auth-tls-secret": nameSpace + "/" + host, + "nginx.ingress.kubernetes.io/auth-tls-verify-client": "on", + "nginx.ingress.kubernetes.io/auth-tls-match-cn": "CN=authtls", + } + + f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, nameSpace, framework.EchoService, 80, annotations)) + + assertSslClientCertificateConfig(f, host, "on", "1") + + f.HTTPTestClientWithTLSConfig(clientConfig). + GET("/"). + WithURL(f.GetURL(framework.HTTPS)). + WithHeader("Host", host). + Expect(). + Status(http.StatusOK) + }) + + ginkgo.It("should return 200 using auth-tls-match-cn where atleast one of the regex options matches CN from client", func() { + host := "authtls.foo.com" + nameSpace := f.Namespace + + clientConfig, err := framework.CreateIngressMASecret( + f.KubeClientSet, + host, + host, + nameSpace) + assert.Nil(ginkgo.GinkgoT(), err) + + annotations := map[string]string{ + "nginx.ingress.kubernetes.io/auth-tls-secret": nameSpace + "/" + host, + "nginx.ingress.kubernetes.io/auth-tls-verify-client": "on", + "nginx.ingress.kubernetes.io/auth-tls-match-cn": "CN=(itwillmatch|withthenextoption|authtls)", + } + + f.EnsureIngress(framework.NewSingleIngressWithTLS(host, "/", host, []string{host}, nameSpace, framework.EchoService, 80, annotations)) + + assertSslClientCertificateConfig(f, host, "on", "1") + + f.HTTPTestClientWithTLSConfig(clientConfig). + GET("/"). + WithURL(f.GetURL(framework.HTTPS)). + WithHeader("Host", host). + Expect(). + Status(http.StatusOK) + }) }) func assertSslClientCertificateConfig(f *framework.Framework, host string, verifyClient string, verifyDepth string) { diff --git a/test/e2e/annotations/canary.go b/test/e2e/annotations/canary.go index 99d164f98..b62ba5a70 100644 --- a/test/e2e/annotations/canary.go +++ b/test/e2e/annotations/canary.go @@ -145,7 +145,7 @@ var _ = framework.DescribeAnnotation("canary-*", func() { ginkgo.By("returning a 200 status when the canary deployment has 0 replicas and a request is sent to the mainline ingress") f.NewEchoDeployment() - f.NewDeployment(canaryService, "k8s.gcr.io/e2e-test-images/echoserver:2.3", 8080, 0) + f.NewDeployment(canaryService, "registry.k8s.io/e2e-test-images/echoserver:2.3", 8080, 0) resp, _, errs = gorequest.New(). Get(f.GetURL(framework.HTTP)). diff --git a/test/e2e/annotations/cors.go b/test/e2e/annotations/cors.go index c249b3877..f88459bce 100644 --- a/test/e2e/annotations/cors.go +++ b/test/e2e/annotations/cors.go @@ -45,7 +45,7 @@ var _ = framework.DescribeAnnotation("cors-*", func() { func(server string) bool { return strings.Contains(server, "more_set_headers 'Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH, OPTIONS';") && strings.Contains(server, "more_set_headers 'Access-Control-Allow-Origin: $http_origin';") && - strings.Contains(server, "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';") && + strings.Contains(server, "more_set_headers 'Access-Control-Allow-Headers: DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';") && strings.Contains(server, "more_set_headers 'Access-Control-Max-Age: 1728000';") && strings.Contains(server, "more_set_headers 'Access-Control-Allow-Credentials: true';") && strings.Contains(server, "set $http_origin *;") && diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go index c0829f5ee..f96d06833 100644 --- a/test/e2e/e2e.go +++ b/test/e2e/e2e.go @@ -40,6 +40,7 @@ import ( _ "k8s.io/ingress-nginx/test/e2e/leaks" _ "k8s.io/ingress-nginx/test/e2e/loadbalance" _ "k8s.io/ingress-nginx/test/e2e/lua" + _ "k8s.io/ingress-nginx/test/e2e/nginx" _ "k8s.io/ingress-nginx/test/e2e/security" _ "k8s.io/ingress-nginx/test/e2e/servicebackend" _ "k8s.io/ingress-nginx/test/e2e/settings" diff --git a/test/e2e/framework/deployment.go b/test/e2e/framework/deployment.go index 0e886aff5..228c35434 100644 --- a/test/e2e/framework/deployment.go +++ b/test/e2e/framework/deployment.go @@ -38,7 +38,7 @@ const SlowEchoService = "slow-echo" const HTTPBinService = "httpbin" // NginxBaseImage use for testing -const NginxBaseImage = "k8s.gcr.io/ingress-nginx/nginx:5402d35663917ccbbf77ff48a22b8c6f77097f48@sha256:ec8a104df307f5c6d68157b7ac8e5e1e2c2f0ea07ddf25bb1c6c43c67e351180" +const NginxBaseImage = "registry.k8s.io/ingress-nginx/nginx:cd6f88af3f976a180ed966dadf273473ae768dfa@sha256:18f91105e4099941d2efee71a8ec52c6ef7702d5f7e8214b7cb5f25cc10a0b41" type deploymentOptions struct { namespace string @@ -78,7 +78,7 @@ func (f *Framework) NewEchoDeployment(opts ...func(*deploymentOptions)) { o(options) } - deployment := newDeployment(options.name, options.namespace, "k8s.gcr.io/ingress-nginx/e2e-test-echo@sha256:131ece0637b29231470cfaa04690c2966a2e0b147d3c9df080a0857b78982410", 80, int32(options.replicas), + deployment := newDeployment(options.name, options.namespace, "registry.k8s.io/ingress-nginx/e2e-test-echo@sha256:131ece0637b29231470cfaa04690c2966a2e0b147d3c9df080a0857b78982410", 80, int32(options.replicas), nil, []corev1.VolumeMount{}, []corev1.Volume{}, @@ -150,8 +150,9 @@ http { f.NGINXWithConfigDeployment(SlowEchoService, cfg) } -// NGINXWithConfigDeployment creates an NGINX deployment using a configmap containing the nginx.conf configuration -func (f *Framework) NGINXWithConfigDeployment(name string, cfg string) { +// NGINXDeployment creates a new simple NGINX Deployment using NGINX base image +// and passing the desired configuration +func (f *Framework) NGINXDeployment(name string, cfg string, waitendpoint bool) { cfgMap := map[string]string{ "nginx.conf": cfg, } @@ -213,8 +214,15 @@ func (f *Framework) NGINXWithConfigDeployment(name string, cfg string) { f.EnsureService(service) - err = WaitForEndpoints(f.KubeClientSet, DefaultTimeout, name, f.Namespace, 1) - assert.Nil(ginkgo.GinkgoT(), err, "waiting for endpoints to become ready") + if waitendpoint { + err = WaitForEndpoints(f.KubeClientSet, DefaultTimeout, name, f.Namespace, 1) + assert.Nil(ginkgo.GinkgoT(), err, "waiting for endpoints to become ready") + } +} + +// NGINXWithConfigDeployment creates an NGINX deployment using a configmap containing the nginx.conf configuration +func (f *Framework) NGINXWithConfigDeployment(name string, cfg string) { + f.NGINXDeployment(name, cfg, true) } // NewGRPCBinDeployment creates a new deployment of the @@ -227,7 +235,7 @@ func (f *Framework) NewGRPCBinDeployment() { PeriodSeconds: 1, SuccessThreshold: 1, TimeoutSeconds: 1, - Handler: corev1.Handler{ + ProbeHandler: corev1.ProbeHandler{ TCPSocket: &corev1.TCPSocketAction{ Port: intstr.FromInt(9000), }, @@ -318,7 +326,7 @@ func newDeployment(name, namespace, image string, port int32, replicas int32, co SuccessThreshold: 1, TimeoutSeconds: 2, FailureThreshold: 6, - Handler: corev1.Handler{ + ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Port: intstr.FromString("http"), Path: "/", @@ -377,7 +385,7 @@ func newDeployment(name, namespace, image string, port int32, replicas int32, co // NewHttpbinDeployment creates a new single replica deployment of the httpbin image in a particular namespace. func (f *Framework) NewHttpbinDeployment() { - f.NewDeployment(HTTPBinService, "k8s.gcr.io/ingress-nginx/e2e-test-httpbin@sha256:c6372ef57a775b95f18e19d4c735a9819f2e7bb4641e5e3f27287d831dfeb7e8", 80, 1) + f.NewDeployment(HTTPBinService, "registry.k8s.io/ingress-nginx/e2e-test-httpbin@sha256:c6372ef57a775b95f18e19d4c735a9819f2e7bb4641e5e3f27287d831dfeb7e8", 80, 1) } // NewDeployment creates a new deployment in a particular namespace. diff --git a/test/e2e/framework/fastcgi_helloserver.go b/test/e2e/framework/fastcgi_helloserver.go index 75a8d098a..c757ba86f 100644 --- a/test/e2e/framework/fastcgi_helloserver.go +++ b/test/e2e/framework/fastcgi_helloserver.go @@ -58,7 +58,7 @@ func (f *Framework) NewNewFastCGIHelloServerDeploymentWithReplicas(replicas int3 Containers: []corev1.Container{ { Name: "fastcgi-helloserver", - Image: "k8s.gcr.io/ingress-nginx/e2e-test-fastcgi-helloserver@sha256:723b8187e1768d199b93fd939c37c1ce9427dcbca72ec6415f4d890bca637fcc", + Image: "registry.k8s.io/ingress-nginx/e2e-test-fastcgi-helloserver@sha256:723b8187e1768d199b93fd939c37c1ce9427dcbca72ec6415f4d890bca637fcc", Env: []corev1.EnvVar{}, Ports: []corev1.ContainerPort{ { diff --git a/test/e2e/framework/framework.go b/test/e2e/framework/framework.go index f0463bd0d..cd18a9738 100644 --- a/test/e2e/framework/framework.go +++ b/test/e2e/framework/framework.go @@ -88,8 +88,22 @@ func NewDefaultFramework(baseName string) *Framework { return f } -// BeforeEach gets a client and makes a namespace. -func (f *Framework) BeforeEach() { +// NewSimpleFramework makes a new framework that allows the usage of a namespace +// for arbitraty tests. +func NewSimpleFramework(baseName string) *Framework { + defer ginkgo.GinkgoRecover() + + f := &Framework{ + BaseName: baseName, + } + + ginkgo.BeforeEach(f.CreateEnvironment) + ginkgo.AfterEach(f.DestroyEnvironment) + + return f +} + +func (f *Framework) CreateEnvironment() { var err error if f.KubeClientSet == nil { @@ -107,6 +121,21 @@ func (f *Framework) BeforeEach() { f.Namespace, err = CreateKubeNamespace(f.BaseName, f.KubeClientSet) assert.Nil(ginkgo.GinkgoT(), err, "creating namespace") +} + +func (f *Framework) DestroyEnvironment() { + go func() { + defer ginkgo.GinkgoRecover() + err := DeleteKubeNamespace(f.KubeClientSet, f.Namespace) + assert.Nil(ginkgo.GinkgoT(), err, "deleting namespace %v", f.Namespace) + }() +} + +// BeforeEach gets a client and makes a namespace. +func (f *Framework) BeforeEach() { + var err error + + f.CreateEnvironment() f.IngressClass, err = CreateIngressClass(f.Namespace, f.KubeClientSet) assert.Nil(ginkgo.GinkgoT(), err, "creating IngressClass") @@ -122,13 +151,7 @@ func (f *Framework) BeforeEach() { // AfterEach deletes the namespace, after reading its events. func (f *Framework) AfterEach() { - defer func(kubeClient kubernetes.Interface, ns string) { - go func() { - defer ginkgo.GinkgoRecover() - err := DeleteKubeNamespace(kubeClient, ns) - assert.Nil(ginkgo.GinkgoT(), err, "deleting namespace %v", f.Namespace) - }() - }(f.KubeClientSet, f.Namespace) + defer f.DestroyEnvironment() defer func(kubeClient kubernetes.Interface, ingressclass string) { go func() { @@ -425,26 +448,35 @@ func (f *Framework) DeleteNGINXPod(grace int64) { assert.Nil(ginkgo.GinkgoT(), err, "while waiting for ingress nginx pod to come up again") } +// HTTPDumbTestClient returns a new httpexpect client without BaseURL. +func (f *Framework) HTTPDumbTestClient() *httpexpect.Expect { + return f.newTestClient(nil, false) +} + // HTTPTestClient returns a new httpexpect client for end-to-end HTTP testing. func (f *Framework) HTTPTestClient() *httpexpect.Expect { - return f.newTestClient(nil) + return f.newTestClient(nil, true) } // HTTPTestClientWithTLSConfig returns a new httpexpect client for end-to-end // HTTP testing with a custom TLS configuration. func (f *Framework) HTTPTestClientWithTLSConfig(config *tls.Config) *httpexpect.Expect { - return f.newTestClient(config) + return f.newTestClient(config, true) } -func (f *Framework) newTestClient(config *tls.Config) *httpexpect.Expect { +func (f *Framework) newTestClient(config *tls.Config, setIngressURL bool) *httpexpect.Expect { if config == nil { config = &tls.Config{ InsecureSkipVerify: true, } } + var baseURL string + if setIngressURL { + baseURL = f.GetURL(HTTP) + } return httpexpect.WithConfig(httpexpect.Config{ - BaseURL: f.GetURL(HTTP), + BaseURL: baseURL, Client: &http.Client{ Transport: &http.Transport{ TLSClientConfig: config, @@ -485,6 +517,19 @@ func (f *Framework) WaitForNginxListening(port int) { assert.Nil(ginkgo.GinkgoT(), err, "waiting for ingress controller pod listening on port 80") } +// WaitForPod waits for a specific Pod to be ready, using a label selector +func (f *Framework) WaitForPod(selector string, timeout time.Duration, shouldFail bool) { + err := waitForPodsReady(f.KubeClientSet, timeout, 1, f.Namespace, metav1.ListOptions{ + LabelSelector: selector, + }) + + if shouldFail { + assert.NotNil(ginkgo.GinkgoT(), err, "waiting for pods to be ready") + } else { + assert.Nil(ginkgo.GinkgoT(), err, "waiting for pods to be ready") + } +} + // UpdateDeployment runs the given updateFunc on the deployment and waits for it to be updated func UpdateDeployment(kubeClientSet kubernetes.Interface, namespace string, name string, replicas int, updateFunc func(d *appsv1.Deployment) error) error { deployment, err := kubeClientSet.AppsV1().Deployments(namespace).Get(context.TODO(), name, metav1.GetOptions{}) diff --git a/test/e2e/framework/logs.go b/test/e2e/framework/logs.go index a4b645695..db3eb4a6c 100644 --- a/test/e2e/framework/logs.go +++ b/test/e2e/framework/logs.go @@ -18,12 +18,15 @@ package framework import ( "context" + "time" "k8s.io/client-go/kubernetes" ) // Logs returns the log entries of a given Pod. func Logs(client kubernetes.Interface, namespace, podName string) (string, error) { + // Logs from jails take a bigger time to get shipped due to the need of tailing them + Sleep(3 * time.Second) logs, err := client.CoreV1().RESTClient().Get(). Resource("pods"). Namespace(namespace). diff --git a/test/e2e/ingress/deep_inspection.go b/test/e2e/ingress/deep_inspection.go new file mode 100644 index 000000000..0a4c3c539 --- /dev/null +++ b/test/e2e/ingress/deep_inspection.go @@ -0,0 +1,67 @@ +/* +Copyright 2022 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 ingress + +import ( + "net/http" + "strings" + + "github.com/onsi/ginkgo" + "k8s.io/ingress-nginx/test/e2e/framework" +) + +var _ = framework.IngressNginxDescribe("[Ingress] DeepInspection", func() { + f := framework.NewDefaultFramework("deep-inspection") + + ginkgo.BeforeEach(func() { + f.NewEchoDeployment() + }) + + ginkgo.It("should drop whole ingress if one path matches invalid regex", func() { + host := "inspection123.com" + + ingInvalid := framework.NewSingleIngress("invalidregex", "/bla{alias /var/run/secrets/;}location ~* ^/abcd", host, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ingInvalid) + ingValid := framework.NewSingleIngress("valid", "/xpto", host, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ingValid) + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, host) && + strings.Contains(server, "location /xpto") && + !strings.Contains(server, "location /bla") + }) + + f.HTTPTestClient(). + GET("/xpto"). + WithHeader("Host", host). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/bla"). + WithHeader("Host", host). + Expect(). + Status(http.StatusNotFound) + + f.HTTPTestClient(). + GET("/abcd/"). + WithHeader("Host", host). + Expect(). + Status(http.StatusNotFound) + }) +}) diff --git a/test/e2e/kind.yaml b/test/e2e/kind.yaml index 6fddba4e2..97dc7082d 100644 --- a/test/e2e/kind.yaml +++ b/test/e2e/kind.yaml @@ -13,4 +13,3 @@ kubeadmConfigPatches: extraArgs: namespace-sync-period: 10s concurrent-deployment-syncs: "30" - deployment-controller-sync-period: 10s diff --git a/test/e2e/nginx/nginx.go b/test/e2e/nginx/nginx.go new file mode 100644 index 000000000..74a6d64be --- /dev/null +++ b/test/e2e/nginx/nginx.go @@ -0,0 +1,132 @@ +/* +Copyright 2022 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 nginx + +import ( + "fmt" + "net/http" + "time" + + "github.com/onsi/ginkgo" + + "k8s.io/ingress-nginx/test/e2e/framework" +) + +var ( + cfgOK = `# + events { + worker_connections 1024; + multi_accept on; + } + + http { + default_type 'text/plain'; + client_max_body_size 0; + + server { + access_log on; + access_log /dev/stdout; + + listen 80; + + location / { + content_by_lua_block { + ngx.print("ok") + } + } + } + } + ` + + cfgAlias = `# + events { + worker_connections 1024; + multi_accept on; + } + + http { + default_type 'text/plain'; + client_max_body_size 0; + + server { + access_log on; + access_log /dev/stdout; + + listen 80; + + location / { + alias /www/html; + } + } + } + ` + + cfgRoot = `# + events { + worker_connections 1024; + multi_accept on; + } + + http { + default_type 'text/plain'; + client_max_body_size 0; + root /srv/www; + server { + access_log on; + access_log /dev/stdout; + + listen 80; + + } + } + ` +) + +var _ = framework.DescribeSetting("nginx-configuration", func() { + f := framework.NewSimpleFramework("nginxconfiguration") + + ginkgo.It("start nginx with default configuration", func() { + + f.NGINXWithConfigDeployment("default-nginx", cfgOK) + f.WaitForPod("app=default-nginx", 60*time.Second, false) + framework.Sleep(5 * time.Second) + + f.HTTPDumbTestClient(). + GET("/"). + WithURL(fmt.Sprintf("http://default-nginx.%s", f.Namespace)). + Expect(). + Status(http.StatusOK).Body().Contains("ok") + }) + + ginkgo.It("fails when using alias directive", func() { + + f.NGINXDeployment("alias-nginx", cfgAlias, false) + // This should fail with a crashloopback because our NGINX does not have + // alias directive! + f.WaitForPod("app=alias-nginx", 60*time.Second, true) + + }) + + ginkgo.It("fails when using root directive", func() { + + f.NGINXDeployment("root-nginx", cfgRoot, false) + // This should fail with a crashloopback because our NGINX does not have + // root directive! + f.WaitForPod("app=root-nginx", 60*time.Second, true) + + }) +}) diff --git a/test/e2e/run.sh b/test/e2e/run.sh index bfe13b428..00ea73299 100755 --- a/test/e2e/run.sh +++ b/test/e2e/run.sh @@ -58,7 +58,7 @@ export KUBECONFIG="${KUBECONFIG:-$HOME/.kube/kind-config-$KIND_CLUSTER_NAME}" if [ "${SKIP_CLUSTER_CREATION:-false}" = "false" ]; then echo "[dev-env] creating Kubernetes cluster with kind" - export K8S_VERSION=${K8S_VERSION:-v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6} + export K8S_VERSION=${K8S_VERSION:-v1.21.10@sha256:84709f09756ba4f863769bdcabe5edafc2ada72d3c8c44d6515fc581b66b029c} kind create cluster \ --verbosity=${KIND_LOG_LEVEL} \ @@ -77,8 +77,11 @@ if [ "${SKIP_IMAGE_CREATION:-false}" = "false" ]; then fi echo "[dev-env] building image" - make -C ${DIR}/../../ clean-image build image + make -C ${DIR}/../../ clean-image build image image-chroot + echo "[dev-env] .. done building controller images" + echo "[dev-env] now building e2e-image.." make -C ${DIR}/../e2e-image image + echo "[dev-env] ..done building e2e-image" fi # Preload images used in e2e tests @@ -87,6 +90,11 @@ KIND_WORKERS=$(kind get nodes --name="${KIND_CLUSTER_NAME}" | grep worker | awk echo "[dev-env] copying docker images to cluster..." kind load docker-image --name="${KIND_CLUSTER_NAME}" --nodes=${KIND_WORKERS} nginx-ingress-controller:e2e + +if [ "${IS_CHROOT:-false}" = "true" ]; then + docker tag ${REGISTRY}/controller-chroot:${TAG} ${REGISTRY}/controller:${TAG} +fi + kind load docker-image --name="${KIND_CLUSTER_NAME}" --nodes=${KIND_WORKERS} ${REGISTRY}/controller:${TAG} echo "[dev-env] running e2e tests..." diff --git a/test/e2e/settings/access_log.go b/test/e2e/settings/access_log.go index 0e4c1d827..0e50205e5 100644 --- a/test/e2e/settings/access_log.go +++ b/test/e2e/settings/access_log.go @@ -31,17 +31,19 @@ var _ = framework.DescribeSetting("access-log", func() { ginkgo.It("use the default configuration", func() { f.WaitForNginxConfiguration( func(cfg string) bool { - return strings.Contains(cfg, "access_log /var/log/nginx/access.log upstreaminfo") && - strings.Contains(cfg, "access_log /var/log/nginx/access.log log_stream") + return (strings.Contains(cfg, "access_log /var/log/nginx/access.log upstreaminfo") && + strings.Contains(cfg, "access_log /var/log/nginx/access.log log_stream")) || + (strings.Contains(cfg, "access_log syslog:server=127.0.0.1:11514 upstreaminfo") && + strings.Contains(cfg, "access_log syslog:server=127.0.0.1:11514 log_stream")) }) }) ginkgo.It("use the specified configuration", func() { - f.UpdateNginxConfigMapData("access-log-path", "/tmp/access.log") + f.UpdateNginxConfigMapData("access-log-path", "/tmp/nginx/access.log") f.WaitForNginxConfiguration( func(cfg string) bool { - return strings.Contains(cfg, "access_log /tmp/access.log upstreaminfo") && - strings.Contains(cfg, "access_log /tmp/access.log log_stream") + return strings.Contains(cfg, "access_log /tmp/nginx/access.log upstreaminfo") && + strings.Contains(cfg, "access_log /tmp/nginx/access.log log_stream") }) }) }) @@ -49,11 +51,12 @@ var _ = framework.DescribeSetting("access-log", func() { ginkgo.Context("http-access-log-path", func() { ginkgo.It("use the specified configuration", func() { - f.UpdateNginxConfigMapData("http-access-log-path", "/tmp/http-access.log") + f.UpdateNginxConfigMapData("http-access-log-path", "/tmp/nginx/http-access.log") f.WaitForNginxConfiguration( func(cfg string) bool { - return strings.Contains(cfg, "access_log /tmp/http-access.log upstreaminfo") && - strings.Contains(cfg, "access_log /var/log/nginx/access.log log_stream") + return strings.Contains(cfg, "access_log /tmp/nginx/http-access.log upstreaminfo") && + (strings.Contains(cfg, "access_log /var/log/nginx/access.log log_stream") || + strings.Contains(cfg, "access_log syslog:server=127.0.0.1:11514 log_stream")) }) }) }) @@ -61,11 +64,12 @@ var _ = framework.DescribeSetting("access-log", func() { ginkgo.Context("stream-access-log-path", func() { ginkgo.It("use the specified configuration", func() { - f.UpdateNginxConfigMapData("stream-access-log-path", "/tmp/stream-access.log") + f.UpdateNginxConfigMapData("stream-access-log-path", "/tmp/nginx/stream-access.log") f.WaitForNginxConfiguration( func(cfg string) bool { - return strings.Contains(cfg, "access_log /tmp/stream-access.log log_stream") && - strings.Contains(cfg, "access_log /var/log/nginx/access.log upstreaminfo") + return strings.Contains(cfg, "access_log /tmp/nginx/stream-access.log log_stream") && + (strings.Contains(cfg, "access_log /var/log/nginx/access.log upstreaminfo") || + strings.Contains(cfg, "access_log syslog:server=127.0.0.1:11514 upstreaminfo")) }) }) }) @@ -74,13 +78,13 @@ var _ = framework.DescribeSetting("access-log", func() { ginkgo.It("use the specified configuration", func() { f.SetNginxConfigMapData(map[string]string{ - "http-access-log-path": "/tmp/http-access.log", - "stream-access-log-path": "/tmp/stream-access.log", + "http-access-log-path": "/tmp/nginx/http-access.log", + "stream-access-log-path": "/tmp/nginx/stream-access.log", }) f.WaitForNginxConfiguration( func(cfg string) bool { - return strings.Contains(cfg, "access_log /tmp/http-access.log upstreaminfo") && - strings.Contains(cfg, "access_log /tmp/stream-access.log log_stream") + return strings.Contains(cfg, "access_log /tmp/nginx/http-access.log upstreaminfo") && + strings.Contains(cfg, "access_log /tmp/nginx/stream-access.log log_stream") }) }) }) diff --git a/test/e2e/settings/global_external_auth.go b/test/e2e/settings/global_external_auth.go index 1e5bf4301..d514080a0 100644 --- a/test/e2e/settings/global_external_auth.go +++ b/test/e2e/settings/global_external_auth.go @@ -17,6 +17,7 @@ limitations under the License. package settings import ( + "context" "fmt" "net/http" "regexp" @@ -24,6 +25,7 @@ import ( "github.com/onsi/ginkgo" "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/test/e2e/framework" @@ -150,7 +152,7 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() { Status(http.StatusOK) }) - ginkgo.It("should still return status code 200 after auth backend is deleted using cache ", func() { + ginkgo.It("should still return status code 200 after auth backend is deleted using cache", func() { globalExternalAuthCacheKeySetting := "global-auth-cache-key" globalExternalAuthCacheKey := "foo" @@ -259,4 +261,101 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() { }) + ginkgo.Context("cookie set by external authentication server", func() { + host := "global-external-auth-check-cookies" + var ing1, ing2 *networking.Ingress + + cfg := `# +events { + worker_connections 1024; + multi_accept on; +} + +http { + default_type 'text/plain'; + client_max_body_size 0; + + server { + access_log on; + access_log /dev/stdout; + + listen 80; + + location ~ ^/cookies/set/(?.*)/(?.*) { + content_by_lua_block { + ngx.header['Set-Cookie'] = {ngx.var.key.."="..ngx.var.value} + ngx.say("OK") + } + } + + location / { + return 200; + } + + location /error { + return 503; + } + } +} +` + ginkgo.BeforeEach(func() { + f.NGINXWithConfigDeployment("http-cookie-with-error", cfg) + + e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), "http-cookie-with-error", metav1.GetOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets), 1, "expected at least one endpoint") + assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets[0].Addresses), 1, "expected at least one address ready in the endpoint") + + httpbinIP := e.Subsets[0].Addresses[0].IP + + f.UpdateNginxConfigMapData(globalExternalAuthURLSetting, fmt.Sprintf("http://%s/cookies/set/alma/armud", httpbinIP)) + + ing1 = framework.NewSingleIngress(host, "/", host, f.Namespace, "http-cookie-with-error", 80, nil) + f.EnsureIngress(ing1) + + ing2 = framework.NewSingleIngress(host+"-error", "/error", host, f.Namespace, "http-cookie-with-error", 80, nil) + f.EnsureIngress(ing2) + + f.WaitForNginxServer(host, func(server string) bool { + return strings.Contains(server, "server_name "+host) + }) + + }) + + ginkgo.It("user retains cookie by default", func() { + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", host). + WithQuery("a", "b"). + WithQuery("c", "d"). + Expect(). + Status(http.StatusOK). + Header("Set-Cookie").Contains("alma=armud") + }) + + ginkgo.It("user does not retain cookie if upstream returns error status code", func() { + f.HTTPTestClient(). + GET("/error"). + WithHeader("Host", host). + WithQuery("a", "b"). + WithQuery("c", "d"). + Expect(). + Status(http.StatusServiceUnavailable). + Header("Set-Cookie").Contains("") + }) + + ginkgo.It("user with global-auth-always-set-cookie key in configmap retains cookie if upstream returns error status code", func() { + f.UpdateNginxConfigMapData("global-auth-always-set-cookie", "true") + + f.HTTPTestClient(). + GET("/error"). + WithHeader("Host", host). + WithQuery("a", "b"). + WithQuery("c", "d"). + Expect(). + Status(http.StatusServiceUnavailable). + Header("Set-Cookie").Contains("alma=armud") + }) + }) }) diff --git a/test/e2e/settings/keep-alive.go b/test/e2e/settings/keep-alive.go index 5a2b5189e..6ef09b78c 100644 --- a/test/e2e/settings/keep-alive.go +++ b/test/e2e/settings/keep-alive.go @@ -74,6 +74,15 @@ var _ = framework.DescribeSetting("keep-alive keep-alive-requests", func() { }) }) + ginkgo.It("should set keepalive time to upstream server", func() { + f.UpdateNginxConfigMapData("upstream-keepalive-time", "75s") + + f.WaitForNginxConfiguration(func(server string) bool { + match, _ := regexp.MatchString(`upstream\supstream_balancer\s\{[\s\S]*keepalive_time\s*75s;`, server) + return match + }) + }) + ginkgo.It("should set the request count to upstream server through one keep alive connection", func() { f.UpdateNginxConfigMapData("upstream-keepalive-requests", "200") diff --git a/test/e2e/settings/ocsp/ocsp.go b/test/e2e/settings/ocsp/ocsp.go index 161815aed..3e9852082 100644 --- a/test/e2e/settings/ocsp/ocsp.go +++ b/test/e2e/settings/ocsp/ocsp.go @@ -292,7 +292,7 @@ func ocspserveDeployment(namespace string) (*appsv1.Deployment, *corev1.Service) Containers: []corev1.Container{ { Name: name, - Image: "k8s.gcr.io/ingress-nginx/e2e-test-cfssl@sha256:be2f69024f7b7053f35b86677de16bdaa5d3ff0f81b17581ef0b0c6804188b03", + Image: "registry.k8s.io/ingress-nginx/e2e-test-cfssl@sha256:be2f69024f7b7053f35b86677de16bdaa5d3ff0f81b17581ef0b0c6804188b03", Command: []string{ "/bin/bash", "-c", diff --git a/test/e2e/settings/pod_security_policy_volumes.go b/test/e2e/settings/pod_security_policy_volumes.go index da88ed5be..384f8c46c 100644 --- a/test/e2e/settings/pod_security_policy_volumes.go +++ b/test/e2e/settings/pod_security_policy_volumes.go @@ -82,10 +82,10 @@ var _ = framework.IngressNginxDescribe("[Security] Pod Security Policies with vo deployment.Spec.Template.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{ { - Name: "ssl", MountPath: "/etc/ingress-controller", + Name: "ssl", MountPath: "/etc/my-amazing-ssl", }, { - Name: "tmp", MountPath: "/tmp", + Name: "tmp", MountPath: "/my-other-tmp", }, } diff --git a/test/e2e/settings/tls.go b/test/e2e/settings/tls.go index b3026aa8c..739e44490 100644 --- a/test/e2e/settings/tls.go +++ b/test/e2e/settings/tls.go @@ -84,28 +84,6 @@ var _ = framework.DescribeSetting("[SSL] TLS protocols, ciphers and headers)", f assert.Equal(ginkgo.GinkgoT(), int(resp.TLS.Version), tls.VersionTLS12) assert.Equal(ginkgo.GinkgoT(), resp.TLS.CipherSuite, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) }) - ginkgo.It("enforcing TLS v1.0", func() { - f.SetNginxConfigMapData(map[string]string{ - sslCiphers: testCiphers, - sslProtocols: "TLSv1", - }) - - f.WaitForNginxConfiguration( - func(cfg string) bool { - return strings.Contains(cfg, "ssl_protocols TLSv1;") - }) - - resp := f.HTTPTestClientWithTLSConfig(tlsConfig). - GET("/"). - WithURL(f.GetURL(framework.HTTPS)). - WithHeader("Host", host). - Expect(). - Status(http.StatusOK). - Raw() - - assert.Equal(ginkgo.GinkgoT(), int(resp.TLS.Version), tls.VersionTLS10) - assert.Equal(ginkgo.GinkgoT(), resp.TLS.CipherSuite, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA) - }) }) ginkgo.Context("should configure HSTS policy header", func() { diff --git a/test/e2e/wait-for-nginx.sh b/test/e2e/wait-for-nginx.sh index 9a37d1ffc..190f71e6d 100755 --- a/test/e2e/wait-for-nginx.sh +++ b/test/e2e/wait-for-nginx.sh @@ -59,8 +59,10 @@ fullnameOverride: nginx-ingress controller: image: repository: ingress-controller/controller + chroot: true tag: 1.0.0-dev digest: + digestChroot: scope: enabled: true config: