Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Sandor Szombat 2020-02-13 10:46:27 +01:00
commit 4ed3d29a89
46 changed files with 228 additions and 143 deletions

View file

@ -232,11 +232,15 @@ dep-ensure: check-go-version ## Update and vendo go dependencies.
.PHONY: dev-env
dev-env: check-go-version ## Starts a local Kubernetes cluster using minikube, building and deploying the ingress controller.
@DIND_TASKS=0 USE_DOCKER=false build/dev-env.sh
@build/dev-env.sh
.PHONY: live-docs
live-docs: ## Build and launch a local copy of the documentation website in http://localhost:3000
@docker build --pull -t ingress-nginx/mkdocs images/mkdocs
@docker buildx build \
--pull \
--load \
--progress plain \
-t ingress-nginx/mkdocs images/mkdocs
@docker run --rm -it -p 3000:3000 -v ${PWD}:/docs ingress-nginx/mkdocs
.PHONY: build-docs

View file

@ -22,10 +22,7 @@ set -o errexit
set -o nounset
set -o pipefail
NAMESPACE="${NAMESPACE:-ingress-nginx}"
echo "NAMESPACE is set to ${NAMESPACE}"
kubectl config use-context minikube
DIR=$(cd $(dirname "${BASH_SOURCE}") && pwd -P)
export TAG=dev
export ARCH=amd64
@ -33,46 +30,77 @@ export REGISTRY=${REGISTRY:-ingress-controller}
DEV_IMAGE=${REGISTRY}/nginx-ingress-controller:${TAG}
{ [ "$(minikube status | grep -c Running)" -ge 2 ] && minikube status | grep -qE ': Configured$|Correctly Configured'; } \
|| minikube start \
--extra-config=kubelet.sync-frequency=1s \
--extra-config=apiserver.authorization-mode=RBAC
if ! command -v kind &> /dev/null; then
echo "kind is not installed"
echo "Use a package manager or visit the official site https://kind.sigs.k8s.io"
exit 1
fi
# shellcheck disable=SC2046
eval $(minikube docker-env --shell bash)
if ! command -v kubectl &> /dev/null; then
echo "Please install kubectl 1.15 or higher"
exit 1
fi
KUBE_CLIENT_VERSION=$(kubectl version --client --short | awk '{print $3}' | cut -d. -f2) || true
if [[ ${KUBE_CLIENT_VERSION} -lt 14 ]]; then
echo "Please update kubectl to 1.15 or higher"
exit 1
fi
echo "[dev-env] building container"
make build container
docker tag "${REGISTRY}/nginx-ingress-controller-${ARCH}:${TAG}" "${DEV_IMAGE}"
# kubectl >= 1.14 includes Kustomize via "apply -k". Makes it easier to use on Linux as well, assuming kubectl installed
KUBE_CLIENT_VERSION=$(kubectl version --client --short | awk '{print $3}' | cut -d. -f2) || true
if [[ ${KUBE_CLIENT_VERSION} -lt 14 ]]; then
for tool in kubectl kustomize; do
echo "[dev-env] installing $tool"
$tool version || brew install $tool
done
fi
export K8S_VERSION=${K8S_VERSION:-v1.17.2@sha256:59df31fc61d1da5f46e8a61ef612fa53d3f9140f82419d1ef1a6b9656c6b737c}
if ! kubectl get namespace "${NAMESPACE}"; then
kubectl create namespace "${NAMESPACE}"
fi
export DOCKER_CLI_EXPERIMENTAL=enabled
kubectl get deploy nginx-ingress-controller -n "${NAMESPACE}" && kubectl delete deploy nginx-ingress-controller -n "${NAMESPACE}"
KIND_CLUSTER_NAME="ingress-nginx-dev"
ROOT=./deploy/minikube
if [[ ${KUBE_CLIENT_VERSION} -lt 14 ]]; then
pushd $ROOT
kustomize edit set namespace "${NAMESPACE}"
kustomize edit set image "quay.io/kubernetes-ingress-controller/nginx-ingress-controller=${DEV_IMAGE}"
popd
echo "[dev-env] deploying NGINX Ingress controller in namespace $NAMESPACE"
kustomize build $ROOT | kubectl apply -f -
if ! kind get clusters -q | grep -q ${KIND_CLUSTER_NAME}; then
echo "[dev-env] creating Kubernetes cluster with kind"
cat <<EOF | kind create cluster --name ${KIND_CLUSTER_NAME} --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
authorization-mode: "AlwaysAllow"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
EOF
else
sed -i -e "s|^namespace: .*|namespace: ${NAMESPACE}|g" "${ROOT}/kustomization.yaml"
echo "[dev-env] deploying NGINX Ingress controller in namespace $NAMESPACE"
kubectl apply -k "${ROOT}"
echo "[dev-env] using existing Kubernetes kind cluster"
fi
echo "[dev-env] copying docker images to cluster..."
kind load docker-image --name="${KIND_CLUSTER_NAME}" "${DEV_IMAGE}"
echo "[dev-env] deploying NGINX Ingress controller..."
kubectl create namespace ingress-nginx || true
kubectl apply -k ${DIR}/../deploy/kind
echo "[dev-env] deleting old ingress-nginx pods..."
MINUTE_AGO=$(python -c "from datetime import datetime,timedelta; print((datetime.utcnow()-timedelta(seconds=60)).strftime('%Y-%m-%dT%H:%M:%SZ'))")
kubectl get pods --namespace ingress-nginx -o go-template \
--template '{{range .items}}{{.metadata.name}} {{.metadata.creationTimestamp}}{{"\n"}}{{end}}' | \
awk -v MINUTE_AGO=$MINUTE_AGO '$2 <= MINUTE_AGO { print $1 }' | \
xargs kubectl delete pod --namespace ingress-nginx
cat <<EOF
Kubernetes cluster ready and ingress-nginx listening in localhost using ports 80 and 443
To delete the dev cluster execute: 'kind delete cluster --name ingress-nginx-dev'
EOF

View file

@ -45,13 +45,6 @@ FLAGS=$@
PKG=k8s.io/ingress-nginx
ARCH=$(go env GOARCH)
MINIKUBE_PATH=${HOME}/.minikube
MINIKUBE_VOLUME="-v ${MINIKUBE_PATH}:${MINIKUBE_PATH}"
if [ ! -d "${MINIKUBE_PATH}" ]; then
echo "Minikube directory not found! Volume will be excluded from docker build."
MINIKUBE_VOLUME=""
fi
# create output directory as current user to avoid problem with docker.
mkdir -p "${KUBE_ROOT}/bin" "${KUBE_ROOT}/bin/${ARCH}"
@ -67,7 +60,6 @@ docker run \
-v "${KUBE_ROOT}/bin/${ARCH}:/go/bin/linux_${ARCH}" \
-v "/var/run/docker.sock:/var/run/docker.sock" \
-v "${INGRESS_VOLUME}:/etc/ingress-controller/" \
${MINIKUBE_VOLUME} \
-w "/go/src/${PKG}" \
-u $(id -u ${USER}):$(id -g ${USER}) \
${E2E_IMAGE} /bin/bash -c "${FLAGS}"

View file

@ -94,11 +94,6 @@ until curl --output /dev/null -fsSL http://localhost:8001/; do
sleep 5
done
MINIKUBE_VOLUME=
if [[ -d "${HOME}/.minikube" ]]; then
MINIKUBE_VOLUME=" -v ${HOME}/.minikube:${HOME}/.minikube "
fi
# if we run as user we cannot bind to port 80 and 443
docker run \
--rm \
@ -109,7 +104,6 @@ docker run \
-e POD_NAME="${POD_NAME}" \
-v "${SSL_VOLUME}:/etc/ingress-controller/ssl/" \
-v "${HOME}/.kube:${HOME}/.kube:ro" \
${MINIKUBE_VOLUME} \
"${IMAGE}-${ARCH}:${TAG}" /nginx-ingress-controller \
--update-status=false \
--v=2 \

View file

@ -31,6 +31,7 @@ import (
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
"k8s.io/ingress-nginx/internal/ingress/controller"
ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config"
"k8s.io/ingress-nginx/internal/ingress/status"
ing_net "k8s.io/ingress-nginx/internal/net"
"k8s.io/ingress-nginx/internal/nginx"
)
@ -175,6 +176,8 @@ Takes the form "<host>:port". If not provided, no admission controller is starte
streamPort = flags.Int("stream-port", 10247, "Port to use for the lua TCP/UDP endpoint configuration.")
profilerPort = flags.Int("profiler-port", 10245, "Port to use for expose the ingress controller Go profiler when it is enabled.")
statusUpdateInterval = flags.Int("status-update-interval", status.UpdateInterval, "Time interval in seconds in which the status should check if an update is required. Default is 60 seconds")
)
flags.MarkDeprecated("force-namespace-isolation", `This flag doesn't do anything.`)
@ -201,6 +204,13 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g
return true, nil, nil
}
if *statusUpdateInterval < 5 {
klog.Warningf("The defined time to update the Ingress status too low (%v seconds). Adjusting to 5 seconds", *statusUpdateInterval)
status.UpdateInterval = 5
} else {
status.UpdateInterval = *statusUpdateInterval
}
if *ingressClass != "" {
klog.Infof("Watching for Ingress class: %s", *ingressClass)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 KiB

After

Width:  |  Height:  |  Size: 329 KiB

View file

@ -7,3 +7,5 @@ bases:
images:
- name: quay.io/kubernetes-ingress-controller/nginx-ingress-controller
newTag: dev
patchesStrategicMerge:
- service-hostport.yaml

View file

@ -0,0 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
spec:
replicas: 1
template:
metadata:
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
containers:
- name: nginx-ingress-controller
ports:
- containerPort: 80
hostPort: 80
- containerPort: 443
hostPort: 443
nodeSelector:
ingress-ready: "true"
tolerations:
- key: node-role.kubernetes.io/master
operator: Equal
effect: NoSchedule

View file

@ -78,7 +78,6 @@ minikube addons disable ingress
```console
$ kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
default-http-backend-66b447d9cf-rrlf9 1/1 Running 0 12s
nginx-ingress-controller-fdcdcd6dd-vvpgs 1/1 Running 0 11s
```

View file

@ -19,11 +19,6 @@ cd ingress-nginx
### Initial developer environment build
>**Prequisites**: Minikube must be installed.
See [releases](https://github.com/kubernetes/minikube/releases) for installation instructions.
If you are using **MacOS** and deploying to **minikube**, the following command will build the local nginx controller container image and deploy the ingress controller onto a minikube cluster with RBAC enabled in the namespace `ingress-nginx`:
```
$ make dev-env
```

View file

@ -40,7 +40,7 @@ If you do not already have an instance of the NGINX Ingress controller running,
ingress-nginx ClusterIP 10.0.0.13 <none> 80/TCP,443/TCP 10m
```
!!! Note
!!! note
The `ingress-nginx` Service is of type `ClusterIP` in this example. This may vary depending on your environment.
Make sure you can use the Service to reach NGINX before proceeding with the rest of this example.

View file

@ -26,9 +26,9 @@ wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/docs/exam
```
!!! Important
Running a docker registry without TLS requires we configure our local docker daemon with the insecure registry flag.
Running a docker registry without TLS requires we configure our local docker daemon with the insecure registry flag.
Please check [deploy a plain http registry](https://docs.docker.com/registry/insecure/#deploy-a-plain-http-registry)
Please check [deploy a plain http registry](https://docs.docker.com/registry/insecure/#deploy-a-plain-http-registry)
### With TLS

View file

@ -7,6 +7,9 @@ metadata:
namespace: default
spec:
replicas: 1
selector:
matchLabels:
k8s-app: fortune-teller-app
template:
metadata:
labels:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View file

@ -44,6 +44,7 @@ They are set in the container spec of the `nginx-ingress-controller` Deployment
| `--udp-services-configmap string` | Name of the ConfigMap containing the definition of the UDP services to expose. The key in the map indicates the external port to be used. The value is a reference to a Service in the form "namespace/name:port", where "port" can either be a port name or number. |
| `--update-status` | Update the load-balancer status of Ingress objects this controller satisfies. Requires setting the publish-service parameter to a valid Service reference. (default true) |
| `--update-status-on-shutdown` | Update the load-balancer status of Ingress objects when the controller shuts down. Requires the update-status parameter. (default true) |
| `--status-update-interval` | Time interval in seconds in which the status should check if an update is required. (default 60 seconds) |
| `-v`, `--v Level` | log level for V logs |
| `--version` | Show release information about the NGINX Ingress controller and exit. |
| `--vmodule moduleSpec` | comma-separated list of pattern=N settings for file-filtered logging |

View file

@ -79,15 +79,13 @@ spec:
servicePort: fastcgi
```
## The FastCGI Ingress Annotations
## FastCGI Ingress Annotations
### The `nginx.ingress.kubernetes.io/backend-protocol` Annotation
To enable FastCGI, the `backend-protocol` annotation needs to be set to `FCGI`, which overrides the default `HTTP` value.
To enable FastCGI, the `nginx.ingress.kubernetes.io/backend-protocol` annotation needs to be set to `FCGI`, which overrides the default `HTTP` value.
> `nginx.ingress.kubernetes.io/backend-protocol: "FCGI"`
This enables the _FastCGI_ mode for the whole _Ingress_ object.
**This enables the _FastCGI_ mode for all paths defined in the _Ingress_ object**
### The `nginx.ingress.kubernetes.io/fastcgi-index` Annotation

View file

@ -9,8 +9,8 @@ The ingress controller supports **case insensitive** regular expressions in the
This can be enabled by setting the `nginx.ingress.kubernetes.io/use-regex` annotation to `true` (the default is false).
!!! hint
Kubernetes only accept expressions that comply with the RE2 engine syntax. It is possible that valid expressions accepted by NGINX cannot be used with ingress-nginx, because the PCRE library (used in NGINX) supports a wider syntax than RE2.
See the [RE2 Syntax](https://github.com/google/re2/wiki/Syntax) documentation for differences.
Kubernetes only accept expressions that comply with the RE2 engine syntax. It is possible that valid expressions accepted by NGINX cannot be used with ingress-nginx, because the PCRE library (used in NGINX) supports a wider syntax than RE2.
See the [RE2 Syntax](https://github.com/google/re2/wiki/Syntax) documentation for differences.
See the [description](./nginx-configuration/annotations.md#use-regex) of the `use-regex` annotation for more details.

View file

@ -171,7 +171,7 @@ If you use the ``cookie`` affinity type you can also specify the name of the coo
The NGINX annotation `nginx.ingress.kubernetes.io/session-cookie-path` defines the path that will be set on the cookie. This is optional unless the annotation `nginx.ingress.kubernetes.io/use-regex` is set to true; Session cookie paths do not support regex.
Use `nginx.ingress.kubernetes.io/session-cookie-samesite` to apply a `SameSite` attribute to the sticky cookie. Browser accepted values are `None`, `Lax`, and `Strict`. Some older browsers reject cookies with the more-recently-defined `SameSite=None`. To omit `SameSite=None` from these older browsers, add the annotation `nginx.ingress.kubernetes.io/session-cookie-conditional-samesite-none: "true"`.
Use `nginx.ingress.kubernetes.io/session-cookie-samesite` to apply a `SameSite` attribute to the sticky cookie. Browser accepted values are `None`, `Lax`, and `Strict`. Some browsers reject cookies with `SameSite=None`, including those created before the `SameSite=None` specification (e.g. Chrome 5X). Other browsers mistakenly treat `SameSite=None` cookies as `SameSite=Strict` (e.g. Safari running on OSX 14). To omit `SameSite=None` from browsers with these incompatibilities, add the annotation `nginx.ingress.kubernetes.io/session-cookie-conditional-samesite-none: "true"`.
### Authentication
@ -352,7 +352,7 @@ Enables automatic conversion of preload links specified in the “Link” respon
Allows the definition of one or more aliases in the server definition of the NGINX configuration using the annotation `nginx.ingress.kubernetes.io/server-alias: "<alias 1>,<alias 2>"`.
This will create a server with the same configuration, but adding new values to the `server_name` directive.
!!! Note
!!! note
A server-alias name cannot conflict with the hostname of an existing server. If it does, the server-alias annotation will be ignored.
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.
@ -446,7 +446,8 @@ By default the controller redirects all requests to an existing service that pro
`nginx.ingress.kubernetes.io/enable-global-auth`:
indicates if GlobalExternalAuth configuration should be applied or not to this Ingress rule. Default values is set to `"true"`.
!!! note For more information please see [global-auth-url](./configmap.md#global-auth-url).
!!! note
For more information please see [global-auth-url](./configmap.md#global-auth-url).
### Rate limiting
@ -837,7 +838,7 @@ nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
### Use Regex
!!! attention
When using this annotation with the NGINX annotation `nginx.ingress.kubernetes.io/affinity` of type `cookie`, `nginx.ingress.kubernetes.io/session-cookie-path` must be also set; Session cookie paths do not support regex.
When using this annotation with the NGINX annotation `nginx.ingress.kubernetes.io/affinity` of type `cookie`, `nginx.ingress.kubernetes.io/session-cookie-path` must be also set; Session cookie paths do not support regex.
Using the `nginx.ingress.kubernetes.io/use-regex` annotation will indicate whether or not the paths defined on an Ingress use regular expressions. The default value is `false`.
@ -885,4 +886,4 @@ nginx.ingress.kubernetes.io/mirror-request-body: "off"
The request sent to the mirror is linked to the orignial request. If you have a slow mirror backend, then the orignial request will throttle.
For more information on the mirror module see https://nginx.org/en/docs/http/ngx_http_mirror_module.html
For more information on the mirror module see [ngx_http_mirror_module](https://nginx.org/en/docs/http/ngx_http_mirror_module.html)

View file

@ -14,7 +14,7 @@ data:
ssl-protocols: SSLv2
```
!!! Important
!!! important
The key and values in a ConfigMap can only be strings.
This means that we want a value with boolean values we need to quote the values, like "true" or "false".
Same for numbers, like "100".
@ -567,7 +567,7 @@ Since `0.27.0` and due to a [change in the MaxMind databases](https://blog.maxmi
For this reason, it is required to define a new flag `--maxmind-license-key` in the ingress controller deployment to download the databases needed during the initialization of the ingress controller.
Alternatively, it is possible to use a volume to mount the files `/etc/nginx/geoip/GeoLite2-City.mmdb` and `/etc/nginx/geoip/GeoLite2-ASN.mmdb`, avoiding the overhead of the download.
!!! Important
!!! important
If the feature is enabled but the files are missing, GeoIP2 will not be enabled.
_**default:**_ false

View file

@ -100,8 +100,7 @@ All these options (including host) allow environment variables, such as `$HOSTNA
## Examples
The following examples show how to deploy and test different distributed tracing systems. These example can be performed
using Minikube.
The following examples show how to deploy and test different distributed tracing systems. These example can be performed using Minikube.
### Zipkin

View file

@ -78,7 +78,6 @@ or per-Ingress with the `nginx.ingress.kubernetes.io/ssl-redirect: "false"`
annotation in the particular resource.
!!! tip
When using SSL offloading outside of cluster (e.g. AWS ELB) it may be useful to enforce a
redirect to HTTPS even when there is no TLS certificate available.
This can be achieved by using the `nginx.ingress.kubernetes.io/force-ssl-redirect: "true"`

View file

@ -218,8 +218,8 @@ func (a authReq) Parse(ing *networking.Ingress) (interface{}, error) {
return nil, ing_errors.NewLocationDenied(fmt.Sprintf("unable to find configMap %q", proxySetHeaderMap))
}
for header, value := range proxySetHeadersMapContents.Data {
if !ValidHeader(header) || !ValidHeader(value) {
for header := range proxySetHeadersMapContents.Data {
if !ValidHeader(header) {
return nil, ing_errors.NewLocationDenied("invalid proxy-set-headers in configmap")
}
}

View file

@ -276,8 +276,8 @@ func TestProxySetHeaders(t *testing.T) {
}{
{"single header", "http://goog.url", map[string]string{"header": "h1"}, false},
{"no header map", "http://goog.url", nil, true},
{"header with spaces", "http://goog.url", map[string]string{"header": "bad value"}, true},
{"header with other bad symbols", "http://goog.url", map[string]string{"header": "bad+value"}, true},
{"header with spaces", "http://goog.url", map[string]string{"header": "bad value"}, false},
{"header with other bad symbols", "http://goog.url", map[string]string{"header": "bad+value"}, false},
}
for _, test := range tests {

View file

@ -82,6 +82,7 @@ func (a mirror) Parse(ing *networking.Ingress) (interface{}, error) {
config.Target, err = parser.GetStringAnnotation("mirror-target", ing)
if err != nil {
config.Target = ""
config.Source = ""
}
return config, nil

View file

@ -47,7 +47,7 @@ func TestParse(t *testing.T) {
Target: "https://test.env.com/$request_uri",
}},
{map[string]string{requestBody: "off"}, &Config{
Source: ngxURI,
Source: "",
RequestBody: "off",
Target: "",
}},

View file

@ -535,18 +535,39 @@ func New(
AddFunc: func(obj interface{}) {
cm := obj.(*corev1.ConfigMap)
key := k8s.MetaNamespaceKey(cm)
triggerUpdate := false
// updates to configuration configmaps can trigger an update
if changeTriggerUpdate(key) {
recorder.Eventf(cm, corev1.EventTypeNormal, "CREATE", fmt.Sprintf("ConfigMap %v", key))
triggerUpdate = true
if key == configmap {
store.setConfig(cm)
}
}
updateCh.In() <- Event{
Type: ConfigurationEvent,
Obj: obj,
ings := store.listers.IngressWithAnnotation.List()
for _, ingKey := range ings {
key := k8s.MetaNamespaceKey(ingKey)
ing, err := store.getIngress(key)
if err != nil {
klog.Errorf("could not find Ingress %v in local store: %v", key, err)
continue
}
if parser.AnnotationsReferencesConfigmap(ing) {
recorder.Eventf(cm, corev1.EventTypeNormal, "CREATE", fmt.Sprintf("ConfigMap %v", key))
store.syncIngress(ing)
triggerUpdate = true
}
}
if triggerUpdate {
updateCh.In() <- Event{
Type: ConfigurationEvent,
Obj: obj,
}
}
},
UpdateFunc: func(old, cur interface{}) {

View file

@ -275,6 +275,7 @@ func configForLua(input interface{}) string {
return fmt.Sprintf(`{
use_forwarded_headers = %t,
use_proxy_protocol = %t,
is_ssl_passthrough_enabled = %t,
http_redirect_code = %v,
listen_ports = { ssl_proxy = "%v", https = "%v" },
@ -285,6 +286,7 @@ func configForLua(input interface{}) string {
hsts_preload = %t,
}`,
all.Cfg.UseForwardedHeaders,
all.Cfg.UseProxyProtocol,
all.IsSSLPassthroughEnabled,
all.Cfg.HTTPRedirectCode,
all.ListenPorts.SSLProxy,

View file

@ -40,9 +40,9 @@ import (
"k8s.io/ingress-nginx/internal/task"
)
const (
updateInterval = 60 * time.Second
)
// UpdateInterval defines the time interval, in seconds, in
// which the status should check if an update is required.
var UpdateInterval = 60
// Syncer ...
type Syncer interface {
@ -98,7 +98,7 @@ func (s statusSync) Run(stopCh chan struct{}) {
// when this instance is the leader we need to enqueue
// an item to trigger the update of the Ingress status.
wait.PollUntil(updateInterval, func() (bool, error) {
wait.PollUntil(time.Duration(UpdateInterval)*time.Second, func() (bool, error) {
s.syncQueue.EnqueueTask(task.GetDummyObject("sync status"))
return false, nil
}, stopCh)

View file

@ -1,34 +0,0 @@
repo: kubernetes/ingress
labels:
- name: area/api
color: ededed
- name: area/docs
color: 1d76db
- name: area/infra
color: bfdadc
- name: backend/gce
color: "5319e7"
- name: backend/generic
color: c2e0c6
- name: backend/nginx
color: c5def5
- name: bug
color: ee0701
- name: 'cncf-cla: no'
color: ededed
- name: 'cncf-cla: yes'
color: ededed
- name: duplicate
color: cccccc
- name: enhancement
color: 84b6eb
- name: help wanted
color: 128A0C
- name: invalid
color: e6e6e6
- name: lgtm
color: 15dd18
- name: question
color: cc317c
- name: wontfix
color: ffffff

View file

@ -1,4 +1,4 @@
mkdocs-material~=4.4.0
mkdocs-material~=4.6.2
mkdocs~=1.0.4
pymdown-extensions~=6.0
pygments~=2.3.1
pymdown-extensions~=6.3
pygments~=2.5.2

View file

@ -54,15 +54,12 @@ function _M.set_cookie(self, value)
end
end
if cookie_samesite then
cookie_path = cookie_path .. "; SameSite=" .. cookie_samesite
end
local cookie_data = {
key = self:cookie_name(),
value = value,
path = cookie_path,
httponly = true,
samesite = cookie_samesite,
secure = ngx.var.https == "on",
}

View file

@ -123,6 +123,12 @@ function _M.rewrite(location_config)
end
end
if config.use_proxy_protocol then
if ngx.var.proxy_protocol_server_port == "443" then
ngx.var.pass_access_scheme = "https"
end
end
ngx.var.pass_port = ngx.var.pass_server_port
if config.is_ssl_passthrough_enabled then
if ngx.var.pass_server_port == config.listen_ports.ssl_proxy then

View file

@ -114,6 +114,7 @@ describe("Sticky", function()
set = function(self, payload)
assert.equal(payload.key, test_backend.sessionAffinityConfig.cookieSessionAffinity.name)
assert.equal(payload.path, ngx.var.location_path)
assert.equal(payload.samesite, nil)
assert.equal(payload.domain, nil)
assert.equal(payload.httponly, true)
assert.equal(payload.secure, false)
@ -143,6 +144,7 @@ describe("Sticky", function()
set = function(self, payload)
assert.equal(payload.key, test_backend.sessionAffinityConfig.cookieSessionAffinity.name)
assert.equal(payload.path, ngx.var.location_path)
assert.equal(payload.samesite, nil)
assert.equal(payload.domain, nil)
assert.equal(payload.httponly, true)
assert.equal(payload.secure, true)
@ -185,6 +187,7 @@ describe("Sticky", function()
set = function(self, payload)
assert.equal(payload.key, test_backend.sessionAffinityConfig.cookieSessionAffinity.name)
assert.equal(payload.path, ngx.var.location_path)
assert.equal(payload.samesite, nil)
assert.equal(payload.domain, nil)
assert.equal(payload.httponly, true)
assert.equal(payload.secure, false)
@ -228,6 +231,7 @@ describe("Sticky", function()
assert.equal(payload.path, ngx.var.location_path)
assert.equal(payload.domain, ngx.var.host)
assert.equal(payload.httponly, true)
assert.equal(payload.samesite, nil)
return true, nil
end,
get = function(k) return false end,
@ -368,6 +372,7 @@ describe("Sticky", function()
set = function(self, payload)
assert.equal(payload.key, test_backend.sessionAffinityConfig.cookieSessionAffinity.name)
assert.equal(payload.path, ngx.var.location_path)
assert.equal(payload.samesite, nil)
assert.equal(payload.domain, nil)
assert.equal(payload.httponly, true)
assert.equal(payload.secure, false)
@ -405,13 +410,14 @@ describe("Sticky", function()
cookie.new = mocked_cookie_new
end)
local function test_set_cookie(sticky, samesite, conditional_samesite_none, expected_path)
local function test_set_cookie(sticky, samesite, conditional_samesite_none, expected_path, expected_samesite)
local s = {}
cookie.new = function(self)
local cookie_instance = {
set = function(self, payload)
assert.equal(payload.key, test_backend.sessionAffinityConfig.cookieSessionAffinity.name)
assert.equal(payload.path, expected_path)
assert.equal(payload.samesite, expected_samesite)
assert.equal(payload.domain, nil)
assert.equal(payload.httponly, true)
assert.equal(payload.secure, false)
@ -433,27 +439,27 @@ describe("Sticky", function()
end
it("returns a cookie with SameSite=Strict when user specifies samesite strict", function()
test_set_cookie(sticky_balanced, "Strict", false, "/; SameSite=Strict")
test_set_cookie(sticky_balanced, "Strict", false, "/", "Strict")
end)
it("returns a cookie with SameSite=Strict when user specifies samesite strict and conditional samesite none", function()
test_set_cookie(sticky_balanced, "Strict", true, "/; SameSite=Strict")
test_set_cookie(sticky_balanced, "Strict", true, "/", "Strict")
end)
it("returns a cookie with SameSite=Lax when user specifies samesite lax", function()
test_set_cookie(sticky_balanced, "Lax", false, "/; SameSite=Lax")
test_set_cookie(sticky_balanced, "Lax", false, "/", "Lax")
end)
it("returns a cookie with SameSite=Lax when user specifies samesite lax and conditional samesite none", function()
test_set_cookie(sticky_balanced, "Lax", true, "/; SameSite=Lax")
test_set_cookie(sticky_balanced, "Lax", true, "/", "Lax")
end)
it("returns a cookie with SameSite=None when user specifies samesite None", function()
test_set_cookie(sticky_balanced, "None", false, "/; SameSite=None")
test_set_cookie(sticky_balanced, "None", false, "/", "None")
end)
it("returns a cookie with SameSite=None when user specifies samesite None and conditional samesite none with supported user agent", function()
mock_ngx({ var = { location_path = "/", host = "test.com" , http_user_agent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.2704.103 Safari/537.36"} })
test_set_cookie(sticky_balanced, "None", true, "/; SameSite=None")
test_set_cookie(sticky_balanced, "None", true, "/", "None")
end)
it("returns a cookie without SameSite=None when user specifies samesite None and conditional samesite none with unsupported user agent", function()
mock_ngx({ var = { location_path = "/", host = "test.com" , http_user_agent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"} })
test_set_cookie(sticky_balanced, "None", true, "/")
test_set_cookie(sticky_balanced, "None", true, "/", nil)
end)
end)
end)

View file

@ -69,7 +69,7 @@ var _ = framework.IngressNginxDescribe("Annotations - Mirror", func() {
It("should disable mirror-request-body", func() {
annotations := map[string]string{
"nginx.ingress.kubernetes.io/mirror-uri": "http://localhost/mirror",
"nginx.ingress.kubernetes.io/mirror-target": "http://localhost/mirror",
"nginx.ingress.kubernetes.io/mirror-request-body": "off",
}

View file

@ -47,6 +47,11 @@ if ! command -v parallel &> /dev/null; then
exit 1
fi
if ! command -v kind --version &> /dev/null; then
echo "kind is not installed. Use the package manager or visit the official site https://kind.sigs.k8s.io/"
exit 1
fi
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
export TAG=dev
@ -59,8 +64,6 @@ export DOCKER_CLI_EXPERIMENTAL=enabled
KIND_CLUSTER_NAME="ingress-nginx-dev"
kind --version || $(echo "Please install kind before running e2e tests";exit 1)
echo "[dev-env] creating Kubernetes cluster with kind"
export KUBECONFIG="${HOME}/.kube/kind-config-${KIND_CLUSTER_NAME}"

View file

@ -69,6 +69,39 @@ var _ = framework.IngressNginxDescribe("Proxy Protocol", func() {
body := string(data)
Expect(body).Should(ContainSubstring(fmt.Sprintf("host=%v", "proxy-protocol")))
Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-port=1234")))
Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-proto=http")))
Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-for=192.168.0.1")))
})
It("should respect proto passed by the PROXY Protocol server port", func() {
host := "proxy-protocol"
f.UpdateNginxConfigMapData(setting, "true")
f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil))
f.WaitForNginxServer(host,
func(server string) bool {
return strings.Contains(server, "server_name proxy-protocol") &&
strings.Contains(server, "listen 80 proxy_protocol")
})
ip := f.GetNginxIP()
conn, err := net.Dial("tcp", net.JoinHostPort(ip, "80"))
Expect(err).NotTo(HaveOccurred(), "unexpected error creating connection to %s:80", ip)
defer conn.Close()
header := "PROXY TCP4 192.168.0.1 192.168.0.11 56324 443\r\n"
conn.Write([]byte(header))
conn.Write([]byte("GET / HTTP/1.1\r\nHost: proxy-protocol\r\n\r\n"))
data, err := ioutil.ReadAll(conn)
Expect(err).NotTo(HaveOccurred(), "unexpected error reading connection data")
body := string(data)
Expect(body).Should(ContainSubstring(fmt.Sprintf("host=%v", "proxy-protocol")))
Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-port=443")))
Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-proto=https")))
Expect(body).Should(ContainSubstring(fmt.Sprintf("x-forwarded-for=192.168.0.1")))
})
})