diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 612bd4b38..924c74deb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -57,19 +57,17 @@ jobs: name: Build runs-on: ubuntu-latest needs: changes - if: | - (needs.changes.outputs.go == 'true') steps: - name: Checkout uses: actions/checkout@v2 - - name: Set up Go 1.15 + - name: Set up Go 1.16 id: go uses: actions/setup-go@v2 with: - go-version: 1.15 + go-version: 1.16 - name: Set up Docker Buildx id: buildx @@ -116,6 +114,7 @@ jobs: runs-on: ubuntu-latest needs: - changes + - build if: | (needs.changes.outputs.charts == 'true') @@ -123,6 +122,11 @@ jobs: - name: Checkout uses: actions/checkout@v2 + + - name: cache + uses: actions/download-artifact@v2 + with: + name: docker.tar.gz - name: Lint run: | @@ -137,13 +141,24 @@ jobs: id: kind uses: engineerd/setup-kind@v0.5.0 with: - version: v0.10.0 - image: kindest/node:v1.20.2 + version: v0.11.1 + image: kindest/node:v1.21.1 + + - uses: geekyeggo/delete-artifact@v1 + with: + name: docker.tar.gz + failOnError: false + + - name: Load images from cache + run: | + echo "loading docker images..." + pigz -dc docker.tar.gz | docker load - name: Test env: KIND_CLUSTER_NAME: kind SKIP_CLUSTER_CREATION: true + SKIP_IMAGE_CREATION: true run: | kind get kubeconfig > $HOME/.kube/kind-config-kind make kind-e2e-chart-tests @@ -159,7 +174,7 @@ jobs: strategy: matrix: - k8s: [v1.16.15, v1.17.17, v1.18.15, v1.19.7, v1.20.2] + k8s: [v1.19.11, v1.20.7, v1.21.1] steps: @@ -175,7 +190,7 @@ jobs: id: kind uses: engineerd/setup-kind@v0.5.0 with: - version: v0.10.0 + version: v0.11.1 config: test/e2e/kind.yaml image: kindest/node:${{ matrix.k8s }} diff --git a/Changelog.md b/Changelog.md index b9a0de82b..09c206dc5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,66 @@ # Changelog +### 1.0.0-beta.1 +**THIS IS A BREAKING CHANGE** + +This release only supports Kubernetes versions >= v1.19. The support for Ingress Object in `networking.k8s.io/v1beta` is being dropped and manifests should now use `networking.k8s.io/v1`. + +**Image:** + +- `k8s.gcr.io/ingress-nginx/controller:v1.0.0-beta.1@sha256:f058f3fdc940095957695829745956c6acddcaef839907360965e27fd3348e2e` + +_ New Features:_ + +_Changes:_ + +- [X] [#7341](https://github.com/kubernetes/ingress-nginx/pull/7341) Fix IngressClass logic for newer releases (#7341) +- [X] [#7355](https://github.com/kubernetes/ingress-nginx/pull/7355) Downgrade Lua modules for s390x (#7355) +- [X] [#7319](https://github.com/kubernetes/ingress-nginx/pull/7319) Lower webhook timeout for digital ocean (#7319) +- [X] [#7161](https://github.com/kubernetes/ingress-nginx/pull/7161) fix: allow scope/tcp/udp configmap namespace to altered (#7161) +- [X] [#7331](https://github.com/kubernetes/ingress-nginx/pull/7331) Fix forwarding of auth-response-headers to gRPC backends (#7331) +- [X] [#7332](https://github.com/kubernetes/ingress-nginx/pull/7332) controller: ignore non-service backends (#7332) + +### 1.0.0-alpha.2 +**THIS IS A BREAKING CHANGE** + +This release only supports Kubernetes versions >= v1.19. The support for Ingress Object in `networking.k8s.io/v1beta` is being dropped and manifests should now use `networking.k8s.io/v1`. + +**Image:** + +- `k8s.gcr.io/ingress-nginx/controller:v1.0.0-alpha.2@sha256:04a0ad3a1279c2a58898e789eed767eafa138ee1e5b9b23a988c6e8485cf958d` + +_ New Features:_ + +- [X] [#7314](https://github.com/kubernetes/ingress-nginx/pull/7314) Add configuration to disable external name service feature +- [X] [#7313](https://github.com/kubernetes/ingress-nginx/pull/7313) Add file containing stable release +- [X] [#7311](https://github.com/kubernetes/ingress-nginx/pull/7311) Handle named (non-numeric) ports correctly +- [X] [#7308](https://github.com/kubernetes/ingress-nginx/pull/7308) Updated v1beta1 to v1 as its deprecated +- [X] [#7298](https://github.com/kubernetes/ingress-nginx/pull/7298) Speed up admission hook by eliminating deep copy of Ingresses in CheckIngress +- [X] [#7242](https://github.com/kubernetes/ingress-nginx/pull/7242) Retry to download maxmind DB if it fails +- [X] [#7228](https://github.com/kubernetes/ingress-nginx/pull/7228) Discover mounted geoip db files +- [X] [#7208](https://github.com/kubernetes/ingress-nginx/pull/7208) ingress/tcp: add additional error logging on failed +- [X] [#7190](https://github.com/kubernetes/ingress-nginx/pull/7190) chart: using Helm builtin capabilities check +- [X] [#7146](https://github.com/kubernetes/ingress-nginx/pull/7146) Use ENV expansion for namespace in args +- [X] [#7107](https://github.com/kubernetes/ingress-nginx/pull/7107) Fix MaxWorkerOpenFiles calculation on high cores nodes +- [X] [#7076](https://github.com/kubernetes/ingress-nginx/pull/7076) Rewrite clean-nginx-conf.sh in Go to speed up admission webhook +- [X] [#7031](https://github.com/kubernetes/ingress-nginx/pull/7031) Remove mercurial from build +- [X] [#6990](https://github.com/kubernetes/ingress-nginx/pull/6990) Use listen to ensure the port is free +- [X] [#6944](https://github.com/kubernetes/ingress-nginx/pull/6944) Update proper default value for HTTP2MaxConcurrentStreams in Docs +- [X] [#6940](https://github.com/kubernetes/ingress-nginx/pull/6940) Fix definition order of modsecurity directives + +### 1.0.0-alpha.1 +**THIS IS A BREAKING CHANGE** + +This release only supports Kubernetes versions >= v1.19. The support for Ingress Object in `networking.k8s.io/v1beta` is being dropped and manifests should now use `networking.k8s.io/v1`. + +**Image:** + +- `k8s.gcr.io/ingress-nginx/controller:v1.0.0-alpha.1@sha256:32f3f02a038c0d7cf33b71a14028c3a4ddee6f4c3fe5fadfa14b915e5e0d9faf` + +_ New Features:_ + +- [X] [#7156] Drops support for Ingress Object v1beta1 + ### 0.47.0 **Image:** diff --git a/OWNERS b/OWNERS index 250bce4e8..1d90c4cd5 100644 --- a/OWNERS +++ b/OWNERS @@ -1,15 +1,12 @@ # See the OWNERS docs: https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md approvers: - - ingress-nginx-admins - - ingress-nginx-maintainers - - ElvinEfendi - - rikatz +- ingress-nginx-admins +- ingress-nginx-maintainers +- sig-network-leads reviewers: - - ElvinEfendi - - cmluciano - - rikatz +- ingress-nginx-reviewers emeritus_approvers: - - aledbf # 2020-04-02 +- aledbf # 2020-04-02 diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 30f781cfc..b313f36b8 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -2,9 +2,31 @@ aliases: sig-network-leads: - - caseydavenport - - dcbw - - thockin + - caseydavenport + - dcbw + - thockin + ingress-nginx-admins: - - bowei + - bowei + - rikatz + ingress-nginx-maintainers: + - ElvinEfendi + - justinsb + - rikatz + - strongjz + + ingress-nginx-reviewers: + - ElvinEfendi + - cmluciano + - rikatz + - strongjz + - tao12345666333 + + ingress-nginx-helm-maintainers: + - ChiefAlexander + - cpanato + + ingress-nginx-helm-reviewers: + - ChiefAlexander + - cpanato diff --git a/README.md b/README.md index 9add5beba..e5056866d 100644 --- a/README.md +++ b/README.md @@ -37,11 +37,11 @@ For detailed changes on the `ingress-nginx` helm chart, please check the followi ### Support Versions table -| Ingress-nginx version | k8s supported version | Alpine Version | Nginx Version | -|-----------------------|------------- |----------------|---------------| -| v0.47.0 | 1.21, 1.20, 1.19 | 3.13.5 | 1.20.1 | -| v0.46.0 | 1.21, 1.20, 1.19 | 3.13.2 | 1.19.6 | -| v0.45.0 | 1.21, 1.20, 1.19 | 3.13.2 | 1.19.6 | +| Ingress-nginx version | k8s supported version | Alpine Version | Nginx Version | +|-----------------------|------------- |----------------|---------------| +| v1.0.0-beta.1 | 1.22, 1.21, 1.20, 1.19 | 3.13.5 | 1.20.1 | +| v1.0.0-alpha.2 | 1.22, 1.21, 1.20, 1.19 | 3.13.5 | 1.20.1 | +| v1.0.0-alpha.1 | 1.21, 1.20, 1.19 | 3.13.5 | 1.20.1 | # Get Involved diff --git a/RELEASE.md b/RELEASE.md index 50324bf71..c752b2a34 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -32,7 +32,7 @@ The sha is available in output from [cloud build](https://console.cloud.google.c 2a. Promote images: -* Open pull request to promote [staging image](https://github.com/kubernetes/k8s.io/blob/master/k8s.gcr.io/images/k8s-staging-ingress-nginx/images.yaml) +* Open pull request to promote [staging image](https://github.com/kubernetes/k8s.io/blob/main/k8s.gcr.io/images/k8s-staging-ingress-nginx/images.yaml) * e2e-test-runner * e2e-test-cfssl * e2e-test-echo @@ -53,7 +53,7 @@ The sha is available in output from [cloud build](https://console.cloud.google.c 4a. Promote images: -* Open pull request to promote [staging image](https://github.com/kubernetes/k8s.io/blob/master/k8s.gcr.io/images/k8s-staging-ingress-nginx/images.yaml) +* Open pull request to promote [staging image](https://github.com/kubernetes/k8s.io/blob/main/k8s.gcr.io/images/k8s-staging-ingress-nginx/images.yaml) * controller 5. Release helm chart: @@ -74,5 +74,7 @@ The sha is available in output from [cloud build](https://console.cloud.google.c * Update the version in [docs/deploy/index.md](docs/deploy/index.md) * Update Supported versions in the Support Versions table in the README.md * Merge + +* Update the stable.txt file to reflect the release to be created -7. Github release \ No newline at end of file +7. Github release diff --git a/TAG b/TAG index 0131a133c..ada98c6fd 100644 --- a/TAG +++ b/TAG @@ -1 +1 @@ -v0.47.0 +v1.0.0-beta.1 \ No newline at end of file diff --git a/charts/ingress-nginx/OWNERS b/charts/ingress-nginx/OWNERS index 7aadb8dc2..a31654fff 100644 --- a/charts/ingress-nginx/OWNERS +++ b/charts/ingress-nginx/OWNERS @@ -1,5 +1,7 @@ +# See the OWNERS docs: https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md + approvers: - - ChiefAlexander +- ingress-nginx-helm-maintainers reviewers: - - ChiefAlexander +- ingress-nginx-helm-reviewers diff --git a/charts/ingress-nginx/ci/daemonset-customconfig-values.yaml b/charts/ingress-nginx/ci/daemonset-customconfig-values.yaml index e12b53421..43dd2b2ac 100644 --- a/charts/ingress-nginx/ci/daemonset-customconfig-values.yaml +++ b/charts/ingress-nginx/ci/daemonset-customconfig-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null kind: DaemonSet admissionWebhooks: enabled: false diff --git a/charts/ingress-nginx/ci/daemonset-customnodeport-values.yaml b/charts/ingress-nginx/ci/daemonset-customnodeport-values.yaml index cfc545f69..1d94be219 100644 --- a/charts/ingress-nginx/ci/daemonset-customnodeport-values.yaml +++ b/charts/ingress-nginx/ci/daemonset-customnodeport-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false diff --git a/charts/ingress-nginx/ci/daemonset-headers-values.yaml b/charts/ingress-nginx/ci/daemonset-headers-values.yaml index ff82cd9c7..ab7d47bd4 100644 --- a/charts/ingress-nginx/ci/daemonset-headers-values.yaml +++ b/charts/ingress-nginx/ci/daemonset-headers-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false addHeaders: diff --git a/charts/ingress-nginx/ci/daemonset-internal-lb-values.yaml b/charts/ingress-nginx/ci/daemonset-internal-lb-values.yaml index 443e39d8b..abae84f6d 100644 --- a/charts/ingress-nginx/ci/daemonset-internal-lb-values.yaml +++ b/charts/ingress-nginx/ci/daemonset-internal-lb-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/daemonset-nodeport-values.yaml b/charts/ingress-nginx/ci/daemonset-nodeport-values.yaml index 6d6605f0e..3b7aa2fcd 100644 --- a/charts/ingress-nginx/ci/daemonset-nodeport-values.yaml +++ b/charts/ingress-nginx/ci/daemonset-nodeport-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/daemonset-podannotations-values.yaml b/charts/ingress-nginx/ci/daemonset-podannotations-values.yaml index 04ac58dbd..0b55306a1 100644 --- a/charts/ingress-nginx/ci/daemonset-podannotations-values.yaml +++ b/charts/ingress-nginx/ci/daemonset-podannotations-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false metrics: diff --git a/charts/ingress-nginx/ci/daemonset-tcp-udp-configMapNamespace-values.yaml b/charts/ingress-nginx/ci/daemonset-tcp-udp-configMapNamespace-values.yaml index afb5487c5..acd86a77a 100644 --- a/charts/ingress-nginx/ci/daemonset-tcp-udp-configMapNamespace-values.yaml +++ b/charts/ingress-nginx/ci/daemonset-tcp-udp-configMapNamespace-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/daemonset-tcp-udp-values.yaml b/charts/ingress-nginx/ci/daemonset-tcp-udp-values.yaml index 7b4d7cbe7..25ee64d85 100644 --- a/charts/ingress-nginx/ci/daemonset-tcp-udp-values.yaml +++ b/charts/ingress-nginx/ci/daemonset-tcp-udp-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/daemonset-tcp-values.yaml b/charts/ingress-nginx/ci/daemonset-tcp-values.yaml index a359a6a40..380c8b4b1 100644 --- a/charts/ingress-nginx/ci/daemonset-tcp-values.yaml +++ b/charts/ingress-nginx/ci/daemonset-tcp-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/deamonset-default-values.yaml b/charts/ingress-nginx/ci/deamonset-default-values.yaml index e63a7f5db..82fa23e85 100644 --- a/charts/ingress-nginx/ci/deamonset-default-values.yaml +++ b/charts/ingress-nginx/ci/deamonset-default-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/deamonset-metrics-values.yaml b/charts/ingress-nginx/ci/deamonset-metrics-values.yaml index 1e5190afc..cb3cb54be 100644 --- a/charts/ingress-nginx/ci/deamonset-metrics-values.yaml +++ b/charts/ingress-nginx/ci/deamonset-metrics-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false metrics: diff --git a/charts/ingress-nginx/ci/deamonset-psp-values.yaml b/charts/ingress-nginx/ci/deamonset-psp-values.yaml index 017b60a9c..8026a6356 100644 --- a/charts/ingress-nginx/ci/deamonset-psp-values.yaml +++ b/charts/ingress-nginx/ci/deamonset-psp-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/deamonset-webhook-and-psp-values.yaml b/charts/ingress-nginx/ci/deamonset-webhook-and-psp-values.yaml index 88aafc66f..fccdb134c 100644 --- a/charts/ingress-nginx/ci/deamonset-webhook-and-psp-values.yaml +++ b/charts/ingress-nginx/ci/deamonset-webhook-and-psp-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: true service: diff --git a/charts/ingress-nginx/ci/deamonset-webhook-values.yaml b/charts/ingress-nginx/ci/deamonset-webhook-values.yaml index 6e3b371da..54d364df1 100644 --- a/charts/ingress-nginx/ci/deamonset-webhook-values.yaml +++ b/charts/ingress-nginx/ci/deamonset-webhook-values.yaml @@ -1,5 +1,9 @@ controller: kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: true service: diff --git a/charts/ingress-nginx/ci/deployment-autoscaling-values.yaml b/charts/ingress-nginx/ci/deployment-autoscaling-values.yaml index 5314cecb3..b8b3ac686 100644 --- a/charts/ingress-nginx/ci/deployment-autoscaling-values.yaml +++ b/charts/ingress-nginx/ci/deployment-autoscaling-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null autoscaling: enabled: true admissionWebhooks: diff --git a/charts/ingress-nginx/ci/deployment-customconfig-values.yaml b/charts/ingress-nginx/ci/deployment-customconfig-values.yaml index f232531ac..85715ddb7 100644 --- a/charts/ingress-nginx/ci/deployment-customconfig-values.yaml +++ b/charts/ingress-nginx/ci/deployment-customconfig-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null config: use-proxy-protocol: "true" admissionWebhooks: diff --git a/charts/ingress-nginx/ci/deployment-customnodeport-values.yaml b/charts/ingress-nginx/ci/deployment-customnodeport-values.yaml index 9eda282b1..a564eaf93 100644 --- a/charts/ingress-nginx/ci/deployment-customnodeport-values.yaml +++ b/charts/ingress-nginx/ci/deployment-customnodeport-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/deployment-default-values.yaml b/charts/ingress-nginx/ci/deployment-default-values.yaml index 93a393c97..9f46b4e7e 100644 --- a/charts/ingress-nginx/ci/deployment-default-values.yaml +++ b/charts/ingress-nginx/ci/deployment-default-values.yaml @@ -1,4 +1,8 @@ # Left blank to test default values controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null service: type: ClusterIP diff --git a/charts/ingress-nginx/ci/deployment-headers-values.yaml b/charts/ingress-nginx/ci/deployment-headers-values.yaml index 665fd48d3..17a11ac37 100644 --- a/charts/ingress-nginx/ci/deployment-headers-values.yaml +++ b/charts/ingress-nginx/ci/deployment-headers-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false addHeaders: diff --git a/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml b/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml index 892f6de3f..8b2eb78bf 100644 --- a/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml +++ b/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/deployment-metrics-values.yaml b/charts/ingress-nginx/ci/deployment-metrics-values.yaml index 887ed0f62..9209ad5a6 100644 --- a/charts/ingress-nginx/ci/deployment-metrics-values.yaml +++ b/charts/ingress-nginx/ci/deployment-metrics-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false metrics: diff --git a/charts/ingress-nginx/ci/deployment-nodeport-values.yaml b/charts/ingress-nginx/ci/deployment-nodeport-values.yaml index 84f1f7582..cd9b32352 100644 --- a/charts/ingress-nginx/ci/deployment-nodeport-values.yaml +++ b/charts/ingress-nginx/ci/deployment-nodeport-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/deployment-podannotations-values.yaml b/charts/ingress-nginx/ci/deployment-podannotations-values.yaml index b65a0910b..b48d93c46 100644 --- a/charts/ingress-nginx/ci/deployment-podannotations-values.yaml +++ b/charts/ingress-nginx/ci/deployment-podannotations-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false metrics: diff --git a/charts/ingress-nginx/ci/deployment-psp-values.yaml b/charts/ingress-nginx/ci/deployment-psp-values.yaml index e339c69c3..2f332a7b2 100644 --- a/charts/ingress-nginx/ci/deployment-psp-values.yaml +++ b/charts/ingress-nginx/ci/deployment-psp-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null service: type: ClusterIP diff --git a/charts/ingress-nginx/ci/deployment-tcp-udp-configMapNamespace-values.yaml b/charts/ingress-nginx/ci/deployment-tcp-udp-configMapNamespace-values.yaml index 141e06b68..c51a4e91f 100644 --- a/charts/ingress-nginx/ci/deployment-tcp-udp-configMapNamespace-values.yaml +++ b/charts/ingress-nginx/ci/deployment-tcp-udp-configMapNamespace-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/deployment-tcp-udp-values.yaml b/charts/ingress-nginx/ci/deployment-tcp-udp-values.yaml index bc29abeba..5b45b69dc 100644 --- a/charts/ingress-nginx/ci/deployment-tcp-udp-values.yaml +++ b/charts/ingress-nginx/ci/deployment-tcp-udp-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: false service: diff --git a/charts/ingress-nginx/ci/deployment-tcp-values.yaml b/charts/ingress-nginx/ci/deployment-tcp-values.yaml index b7f54c09f..ac0b6e60e 100644 --- a/charts/ingress-nginx/ci/deployment-tcp-values.yaml +++ b/charts/ingress-nginx/ci/deployment-tcp-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null service: type: ClusterIP diff --git a/charts/ingress-nginx/ci/deployment-webhook-and-psp-values.yaml b/charts/ingress-nginx/ci/deployment-webhook-and-psp-values.yaml index a829c3614..6195bb339 100644 --- a/charts/ingress-nginx/ci/deployment-webhook-and-psp-values.yaml +++ b/charts/ingress-nginx/ci/deployment-webhook-and-psp-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: true service: diff --git a/charts/ingress-nginx/ci/deployment-webhook-values.yaml b/charts/ingress-nginx/ci/deployment-webhook-values.yaml index 4f18a70b9..76669a530 100644 --- a/charts/ingress-nginx/ci/deployment-webhook-values.yaml +++ b/charts/ingress-nginx/ci/deployment-webhook-values.yaml @@ -1,4 +1,8 @@ controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null admissionWebhooks: enabled: true service: diff --git a/charts/ingress-nginx/templates/NOTES.txt b/charts/ingress-nginx/templates/NOTES.txt index 60fb2c1f6..2eebba368 100644 --- a/charts/ingress-nginx/templates/NOTES.txt +++ b/charts/ingress-nginx/templates/NOTES.txt @@ -29,7 +29,7 @@ Get the application URL by running these commands: An example Ingress that makes use of the controller: - apiVersion: networking.k8s.io/v1beta1 + apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: diff --git a/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml b/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml index 2f3dd7784..712f74fdd 100644 --- a/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml +++ b/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml @@ -18,7 +18,7 @@ webhooks: - apiGroups: - networking.k8s.io apiVersions: - - v1beta1 + - v1 operations: - CREATE - UPDATE @@ -28,12 +28,11 @@ webhooks: sideEffects: None admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: namespace: {{ .Release.Namespace | quote }} name: {{ include "ingress-nginx.controller.fullname" . }}-admission - path: /networking/v1beta1/ingresses + path: /networking/v1/ingresses {{- if .Values.controller.admissionWebhooks.timeoutSeconds }} timeoutSeconds: {{ .Values.controller.admissionWebhooks.timeoutSeconds }} {{- end }} diff --git a/charts/ingress-nginx/templates/clusterrole.yaml b/charts/ingress-nginx/templates/clusterrole.yaml index 8ec5f49fa..95b7fec08 100644 --- a/charts/ingress-nginx/templates/clusterrole.yaml +++ b/charts/ingress-nginx/templates/clusterrole.yaml @@ -42,8 +42,7 @@ rules: - list - watch - apiGroups: - - extensions - - "networking.k8s.io" # k8s 1.14+ + - networking.k8s.io resources: - ingresses verbs: @@ -58,14 +57,13 @@ rules: - create - patch - apiGroups: - - extensions - - "networking.k8s.io" # k8s 1.14+ + - networking.k8s.io resources: - ingresses/status verbs: - update - apiGroups: - - "networking.k8s.io" # k8s 1.14+ + - networking.k8s.io resources: - ingressclasses verbs: diff --git a/charts/ingress-nginx/templates/controller-daemonset.yaml b/charts/ingress-nginx/templates/controller-daemonset.yaml index 2f6def589..d32ed72e7 100644 --- a/charts/ingress-nginx/templates/controller-daemonset.yaml +++ b/charts/ingress-nginx/templates/controller-daemonset.yaml @@ -74,22 +74,22 @@ spec: args: - /nginx-ingress-controller {{- if .Values.defaultBackend.enabled }} - - --default-backend-service={{ .Release.Namespace }}/{{ include "ingress-nginx.defaultBackend.fullname" . }} + - --default-backend-service=$(POD_NAMESPACE)/{{ include "ingress-nginx.defaultBackend.fullname" . }} {{- end }} {{- if .Values.controller.publishService.enabled }} - --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }} {{- end }} - --election-id={{ .Values.controller.electionID }} - - --ingress-class={{ .Values.controller.ingressClass }} - - --configmap={{ .Release.Namespace }}/{{ include "ingress-nginx.controller.fullname" . }} + - --controller-class={{ .Values.controller.ingressClassResource.controllerValue }} + - --configmap={{ default "$(POD_NAMESPACE)" .Values.controller.configMapNamespace }}/{{ include "ingress-nginx.controller.fullname" . }} {{- if .Values.tcp }} - - --tcp-services-configmap={{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-tcp + - --tcp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.tcp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-tcp {{- end }} {{- if .Values.udp }} - - --udp-services-configmap={{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-udp + - --udp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.udp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-udp {{- end }} {{- if .Values.controller.scope.enabled }} - - --watch-namespace={{ default .Release.Namespace .Values.controller.scope.namespace }} + - --watch-namespace={{ default "$(POD_NAMESPACE)" .Values.controller.scope.namespace }} {{- end }} {{- if and .Values.controller.reportNodeInternalIp .Values.controller.hostNetwork }} - --report-node-internal-ip-address={{ .Values.controller.reportNodeInternalIp }} diff --git a/charts/ingress-nginx/templates/controller-deployment.yaml b/charts/ingress-nginx/templates/controller-deployment.yaml index 7e2d223a9..c0c6f4933 100644 --- a/charts/ingress-nginx/templates/controller-deployment.yaml +++ b/charts/ingress-nginx/templates/controller-deployment.yaml @@ -84,13 +84,13 @@ spec: - --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }} {{- end }} - --election-id={{ .Values.controller.electionID }} - - --ingress-class={{ .Values.controller.ingressClass }} - - --configmap=$(POD_NAMESPACE)/{{ include "ingress-nginx.controller.fullname" . }} + - --controller-class={{ .Values.controller.ingressClassResource.controllerValue }} + - --configmap={{ default "$(POD_NAMESPACE)" .Values.controller.configMapNamespace }}/{{ include "ingress-nginx.controller.fullname" . }} {{- if .Values.tcp }} - - --tcp-services-configmap=$(POD_NAMESPACE)/{{ include "ingress-nginx.fullname" . }}-tcp + - --tcp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.tcp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-tcp {{- end }} {{- if .Values.udp }} - - --udp-services-configmap=$(POD_NAMESPACE)/{{ include "ingress-nginx.fullname" . }}-udp + - --udp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.udp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-udp {{- end }} {{- if .Values.controller.scope.enabled }} - --watch-namespace={{ default "$(POD_NAMESPACE)" .Values.controller.scope.namespace }} diff --git a/charts/ingress-nginx/templates/controller-ingressclass.yaml b/charts/ingress-nginx/templates/controller-ingressclass.yaml index f94b9590d..9492784a2 100644 --- a/charts/ingress-nginx/templates/controller-ingressclass.yaml +++ b/charts/ingress-nginx/templates/controller-ingressclass.yaml @@ -1,9 +1,7 @@ -{{- if and (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) (.Values.controller.ingressClassResource.enabled) -}} -{{- if and (semverCompare "=1.18-0" .Capabilities.KubeVersion.GitVersion) }} -apiVersion: networking.k8s.io/v1beta1 -{{- else }} +{{- if .Values.controller.ingressClassResource.enabled -}} +# We don't support namespaced ingressClass yet +# So a ClusterRole and a ClusterRoleBinding is required apiVersion: networking.k8s.io/v1 -{{- end }} kind: IngressClass metadata: labels: @@ -12,12 +10,12 @@ metadata: {{- with .Values.controller.labels }} {{- toYaml . | nindent 4 }} {{- end }} - name: {{ .Values.controller.ingressClass }} + name: {{ .Values.controller.ingressClassResource.name }} {{- if .Values.controller.ingressClassResource.default }} annotations: ingressclass.kubernetes.io/is-default-class: "true" {{- end }} spec: - controller: k8s.io/ingress-nginx + controller: {{ .Values.controller.ingressClassResource.controllerValue }} {{ template "ingressClass.parameters" . }} {{- end }} diff --git a/charts/ingress-nginx/templates/controller-role.yaml b/charts/ingress-nginx/templates/controller-role.yaml index 1a5ccd29b..97c627dac 100644 --- a/charts/ingress-nginx/templates/controller-role.yaml +++ b/charts/ingress-nginx/templates/controller-role.yaml @@ -34,8 +34,7 @@ rules: - list - watch - apiGroups: - - extensions - - "networking.k8s.io" # k8s 1.14+ + - networking.k8s.io resources: - ingresses verbs: @@ -43,14 +42,13 @@ rules: - list - watch - apiGroups: - - extensions - - "networking.k8s.io" # k8s 1.14+ + - networking.k8s.io resources: - ingresses/status verbs: - update - apiGroups: - - "networking.k8s.io" # k8s 1.14+ + - networking.k8s.io resources: - ingressclasses verbs: @@ -62,7 +60,7 @@ rules: resources: - configmaps resourceNames: - - {{ .Values.controller.electionID }}-{{ .Values.controller.ingressClass }} + - {{ .Values.controller.electionID }} verbs: - get - update diff --git a/charts/ingress-nginx/templates/controller-servicemonitor.yaml b/charts/ingress-nginx/templates/controller-servicemonitor.yaml index 066488a04..17894c8be 100644 --- a/charts/ingress-nginx/templates/controller-servicemonitor.yaml +++ b/charts/ingress-nginx/templates/controller-servicemonitor.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled -}} +{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled -}} apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: diff --git a/charts/ingress-nginx/values.yaml b/charts/ingress-nginx/values.yaml index 460b19884..4c0484227 100644 --- a/charts/ingress-nginx/values.yaml +++ b/charts/ingress-nginx/values.yaml @@ -76,15 +76,13 @@ controller: ## electionID: ingress-controller-leader - ## Name of the ingress class to route through this controller - ## - ingressClass: nginx - # This section refers to the creation of the IngressClass resource - # IngressClass resources are supported since k8s >= 1.18 + # IngressClass resources are supported since k8s >= 1.18 and required since k8s >= 1.19 ingressClassResource: - enabled: false + name: nginx + enabled: true default: false + controllerValue: "k8s.io/ingress-nginx" # Parameters is a link to a custom resource containing additional # configuration for the controller. This is optional if the controller @@ -121,23 +119,23 @@ controller: ## scope: enabled: false - namespace: "" # defaults to .Release.Namespace + namespace: "" # defaults to $(POD_NAMESPACE) ## Allows customization of the configmap / nginx-configmap namespace ## - configMapNamespace: "" # defaults to .Release.Namespace + configMapNamespace: "" # defaults to $(POD_NAMESPACE) ## Allows customization of the tcp-services-configmap ## tcp: - configMapNamespace: "" # defaults to .Release.Namespace + configMapNamespace: "" # defaults to $(POD_NAMESPACE) ## Annotations to be added to the tcp config configmap annotations: {} ## Allows customization of the udp-services-configmap ## udp: - configMapNamespace: "" # defaults to .Release.Namespace + configMapNamespace: "" # defaults to $(POD_NAMESPACE) ## Annotations to be added to the udp config configmap annotations: {} diff --git a/cmd/nginx/flags.go b/cmd/nginx/flags.go index 5fb63b430..aabade07e 100644 --- a/cmd/nginx/flags.go +++ b/cmd/nginx/flags.go @@ -23,17 +23,15 @@ import ( "time" "github.com/spf13/pflag" - apiv1 "k8s.io/api/core/v1" - "k8s.io/klog/v2" - - "k8s.io/ingress-nginx/internal/ingress/annotations/class" "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/controller/ingressclass" "k8s.io/ingress-nginx/internal/ingress/status" ing_net "k8s.io/ingress-nginx/internal/net" "k8s.io/ingress-nginx/internal/nginx" + klog "k8s.io/klog/v2" ) func parseFlags() (bool, *controller.Configuration, error) { @@ -57,10 +55,18 @@ only when the flag --apiserver-host is specified.`) Takes the form "namespace/name". The controller configures NGINX to forward requests to the first port of this Service.`) - ingressClass = flags.String("ingress-class", "", - `Name of the ingress class this controller satisfies. -The class of an Ingress object is set using the field IngressClassName in Kubernetes clusters version v1.18.0 or higher or the annotation "kubernetes.io/ingress.class" (deprecated). -If this parameter is not set, or set to the default value of "nginx", it will handle ingresses with either an empty or "nginx" class name.`) + ingressClassAnnotation = flags.String("ingress-class", ingressclass.DefaultAnnotationValue, + `[IN DEPRECATION] Name of the ingress class this controller satisfies. +The class of an Ingress object is set using the annotation "kubernetes.io/ingress.class" (deprecated). +The parameter --controller-class has precedence over this.`) + + ingressClassController = flags.String("controller-class", ingressclass.DefaultControllerName, + `Ingress Class Controller value this Ingress satisfies. +The class of an Ingress object is set using the field IngressClassName in Kubernetes clusters version v1.19.0 or higher. The .spec.controller value of the IngressClass +referenced in an Ingress Object should be the same value specified here to make this object be watched.`) + + watchWithoutClass = flags.Bool("watch-ingress-without-class", false, + `Define if Ingress Controller should also watch for Ingresses without an IngressClass or the annotation specified`) configMap = flags.String("configmap", "", `Name of the ConfigMap containing custom global configurations for the controller.`) @@ -126,6 +132,9 @@ Requires the update-status parameter.`) enableSSLPassthrough = flags.Bool("enable-ssl-passthrough", false, `Enable SSL Passthrough.`) + disableServiceExternalName = flags.Bool("disable-svc-external-name", false, + `Disable support for Services of type ExternalName`) + annotationsPrefix = flags.String("annotations-prefix", parser.DefaultAnnotationsPrefix, `Prefix of the Ingress annotations specific to the NGINX controller.`) @@ -179,6 +188,8 @@ Takes the form ":port". If not provided, no admission controller is starte flags.StringVar(&nginx.MaxmindLicenseKey, "maxmind-license-key", "", `Maxmind license key to download GeoLite2 Databases. https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases`) flags.StringVar(&nginx.MaxmindEditionIDs, "maxmind-edition-ids", "GeoLite2-City,GeoLite2-ASN", `Maxmind edition ids to download GeoLite2 Databases.`) + flags.IntVar(&nginx.MaxmindRetriesCount, "maxmind-retries-count", 1, "Number of attempts to download the GeoIP DB.") + flags.DurationVar(&nginx.MaxmindRetriesTimeout, "maxmind-retries-timeout", time.Second*0, "Maxmind downloading delay between 1st and 2nd attempt, 0s - do not retry to download if something went wrong.") flag.Set("logtostderr", "true") @@ -204,18 +215,6 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g status.UpdateInterval = *statusUpdateInterval } - if *ingressClass != "" { - klog.InfoS("Watching for Ingress", "class", *ingressClass) - - if *ingressClass != class.DefaultClass { - klog.Warningf("Only Ingresses with class %q will be processed by this Ingress controller", *ingressClass) - } else { - klog.Warning("Ingresses with an empty class will also be processed by this Ingress controller") - } - - class.IngressClass = *ingressClass - } - parser.AnnotationsPrefix = *annotationsPrefix // check port collisions @@ -264,28 +263,29 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g ngx_config.EnableSSLChainCompletion = *enableSSLChainCompletion config := &controller.Configuration{ - APIServerHost: *apiserverHost, - KubeConfigFile: *kubeConfigFile, - UpdateStatus: *updateStatus, - ElectionID: *electionID, - EnableProfiling: *profiling, - EnableMetrics: *enableMetrics, - MetricsPerHost: *metricsPerHost, - MonitorMaxBatchSize: *monitorMaxBatchSize, - EnableSSLPassthrough: *enableSSLPassthrough, - ResyncPeriod: *resyncPeriod, - DefaultService: *defaultSvc, - Namespace: *watchNamespace, - ConfigMapName: *configMap, - TCPConfigMapName: *tcpConfigMapName, - UDPConfigMapName: *udpConfigMapName, - DefaultSSLCertificate: *defSSLCertificate, - PublishService: *publishSvc, - PublishStatusAddress: *publishStatusAddress, - UpdateStatusOnShutdown: *updateStatusOnShutdown, - ShutdownGracePeriod: *shutdownGracePeriod, - UseNodeInternalIP: *useNodeInternalIP, - SyncRateLimit: *syncRateLimit, + APIServerHost: *apiserverHost, + KubeConfigFile: *kubeConfigFile, + UpdateStatus: *updateStatus, + ElectionID: *electionID, + EnableProfiling: *profiling, + EnableMetrics: *enableMetrics, + MetricsPerHost: *metricsPerHost, + MonitorMaxBatchSize: *monitorMaxBatchSize, + DisableServiceExternalName: *disableServiceExternalName, + EnableSSLPassthrough: *enableSSLPassthrough, + ResyncPeriod: *resyncPeriod, + DefaultService: *defaultSvc, + Namespace: *watchNamespace, + ConfigMapName: *configMap, + TCPConfigMapName: *tcpConfigMapName, + UDPConfigMapName: *udpConfigMapName, + DefaultSSLCertificate: *defSSLCertificate, + PublishService: *publishSvc, + PublishStatusAddress: *publishStatusAddress, + UpdateStatusOnShutdown: *updateStatusOnShutdown, + ShutdownGracePeriod: *shutdownGracePeriod, + UseNodeInternalIP: *useNodeInternalIP, + SyncRateLimit: *syncRateLimit, ListenPorts: &ngx_config.ListenPorts{ Default: *defServerPort, Health: *healthzPort, @@ -293,6 +293,11 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g HTTPS: *httpsPort, SSLProxy: *sslProxyPort, }, + IngressClassConfiguration: &ingressclass.IngressClassConfiguration{ + Controller: *ingressClassController, + AnnotationValue: *ingressClassAnnotation, + WatchWithoutClass: *watchWithoutClass, + }, DisableCatchAll: *disableCatchAll, ValidationWebhook: *validationWebhook, ValidationWebhookCertPath: *validationWebhookCert, @@ -303,16 +308,19 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g config.RootCAFile = *rootCAFile } - if (nginx.MaxmindLicenseKey != "" || nginx.MaxmindMirror != "") && nginx.MaxmindEditionIDs != "" { - if err := nginx.ValidateGeoLite2DBEditions(); err != nil { + var err error + if nginx.MaxmindEditionIDs != "" { + if err = nginx.ValidateGeoLite2DBEditions(); err != nil { return false, nil, err } - klog.InfoS("downloading maxmind GeoIP2 databases") - if err := nginx.DownloadGeoLite2DB(); err != nil { - klog.ErrorS(err, "unexpected error downloading GeoIP2 database") + if nginx.MaxmindLicenseKey != "" || nginx.MaxmindMirror != "" { + klog.InfoS("downloading maxmind GeoIP2 databases") + if err = nginx.DownloadGeoLite2DB(nginx.MaxmindRetriesCount, nginx.MaxmindRetriesTimeout); err != nil { + klog.ErrorS(err, "unexpected error downloading GeoIP2 database") + } } - config.MaxmindEditionFiles = nginx.MaxmindEditionFiles + config.MaxmindEditionFiles = &nginx.MaxmindEditionFiles } - return false, config, nil + return false, config, err } diff --git a/cmd/nginx/flags_test.go b/cmd/nginx/flags_test.go index 4286d4a20..b25fa7557 100644 --- a/cmd/nginx/flags_test.go +++ b/cmd/nginx/flags_test.go @@ -105,3 +105,16 @@ func TestMaxmindMirror(t *testing.T) { t.Fatalf("Expected an error parsing flags but none returned") } } + +func TestMaxmindRetryDownload(t *testing.T) { + resetForTesting(func() { t.Fatal("Parsing failed") }) + + oldArgs := os.Args + defer func() { os.Args = oldArgs }() + os.Args = []string{"cmd", "--publish-service", "namespace/test", "--http-port", "0", "--https-port", "0", "--maxmind-mirror", "http://127.0.0.1", "--maxmind-license-key", "0000000", "--maxmind-edition-ids", "GeoLite2-City", "--maxmind-retries-timeout", "1s", "--maxmind-retries-count", "3"} + + _, _, err := parseFlags() + if err == nil { + t.Fatalf("Expected an error parsing flags but none returned") + } +} diff --git a/cmd/nginx/main.go b/cmd/nginx/main.go index 9c245baa1..b21e1012e 100644 --- a/cmd/nginx/main.go +++ b/cmd/nginx/main.go @@ -43,7 +43,6 @@ import ( "k8s.io/klog/v2" "k8s.io/ingress-nginx/internal/file" - "k8s.io/ingress-nginx/internal/ingress/annotations/class" "k8s.io/ingress-nginx/internal/ingress/controller" "k8s.io/ingress-nginx/internal/ingress/metric" "k8s.io/ingress-nginx/internal/k8s" @@ -104,35 +103,16 @@ func main() { conf.FakeCertificate = ssl.GetFakeSSLCert() klog.InfoS("SSL fake certificate created", "file", conf.FakeCertificate.PemFileName) - var isNetworkingIngressAvailable bool - - isNetworkingIngressAvailable, k8s.IsIngressV1Beta1Ready, _ = k8s.NetworkingIngressAvailable(kubeClient) - if !isNetworkingIngressAvailable { - klog.Fatalf("ingress-nginx requires Kubernetes v1.14.0 or higher") + if !k8s.NetworkingIngressAvailable(kubeClient) { + klog.Fatalf("ingress-nginx requires Kubernetes v1.19.0 or higher") } - if k8s.IsIngressV1Beta1Ready { - klog.InfoS("Enabling new Ingress features available since Kubernetes v1.18") - k8s.IngressClass, err = kubeClient.NetworkingV1beta1().IngressClasses(). - Get(context.TODO(), class.IngressClass, metav1.GetOptions{}) - if err != nil { - if !errors.IsNotFound(err) { - if !errors.IsUnauthorized(err) && !errors.IsForbidden(err) { - klog.Fatalf("Error searching IngressClass: %v", err) - } - - klog.ErrorS(err, "Searching IngressClass", "class", class.IngressClass) + _, err = kubeClient.NetworkingV1().IngressClasses().List(context.TODO(), metav1.ListOptions{}) + if err != nil { + if !errors.IsNotFound(err) { + if errors.IsUnauthorized(err) || !errors.IsForbidden(err) { + klog.Fatalf("Error searching IngressClass: Please verify your RBAC and allow Ingress Controller to list and get Ingress Classes: %v", err) } - - klog.Warningf("No IngressClass resource with name %v found. Only annotation will be used.", class.IngressClass) - - // TODO: remove once this is fixed in client-go - k8s.IngressClass = nil - } - - if k8s.IngressClass != nil && k8s.IngressClass.Spec.Controller != k8s.IngressNGINXController { - klog.Errorf(`Invalid IngressClass (Spec.Controller) value "%v". Should be "%v"`, k8s.IngressClass.Spec.Controller, k8s.IngressNGINXController) - klog.Fatalf("IngressClass with name %v is not valid for ingress-nginx (invalid Spec.Controller)", class.IngressClass) } } @@ -153,7 +133,7 @@ func main() { mc := metric.NewDummyCollector() if conf.EnableMetrics { - mc, err = metric.NewCollector(conf.MetricsPerHost, reg) + mc, err = metric.NewCollector(conf.MetricsPerHost, reg, conf.IngressClassConfiguration.Controller) if err != nil { klog.Fatalf("Error creating prometheus collector: %v", err) } diff --git a/cmd/plugin/commands/ingresses/ingresses.go b/cmd/plugin/commands/ingresses/ingresses.go index 38da62930..dff967103 100644 --- a/cmd/plugin/commands/ingresses/ingresses.go +++ b/cmd/plugin/commands/ingresses/ingresses.go @@ -22,7 +22,8 @@ import ( "text/tabwriter" "github.com/spf13/cobra" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/ingress-nginx/cmd/plugin/request" @@ -157,9 +158,10 @@ func getIngressRows(ingresses *[]networking.Ingress) []ingressRow { defaultBackendService := "" defaultBackendPort := "" - if ing.Spec.Backend != nil { - defaultBackendService = ing.Spec.Backend.ServiceName - defaultBackendPort = ing.Spec.Backend.ServicePort.String() + if ing.Spec.DefaultBackend != nil { + name, port := serviceToNameAndPort(ing.Spec.DefaultBackend.Service) + defaultBackendService = name + defaultBackendPort = port.String() } // Handle catch-all ingress @@ -197,14 +199,15 @@ func getIngressRows(ingresses *[]networking.Ingress) []ingressRow { } for _, path := range rule.HTTP.Paths { + svcName, svcPort := serviceToNameAndPort(path.Backend.Service) row := ingressRow{ Namespace: ing.Namespace, IngressName: ing.Name, Host: rule.Host, Path: path.Path, TLS: hasTLS, - ServiceName: path.Backend.ServiceName, - ServicePort: path.Backend.ServicePort.String(), + ServiceName: svcName, + ServicePort: svcPort.String(), Address: address, } @@ -215,3 +218,17 @@ func getIngressRows(ingresses *[]networking.Ingress) []ingressRow { return rows } + +func serviceToNameAndPort(svc *networking.IngressServiceBackend) (string, intstr.IntOrString) { + var svcName string + if svc != nil { + svcName = svc.Name + if svc.Port.Number > 0 { + return svcName, intstr.FromInt(int(svc.Port.Number)) + } + if svc.Port.Name != "" { + return svcName, intstr.FromString(svc.Port.Name) + } + } + return "", intstr.IntOrString{} +} diff --git a/cmd/plugin/commands/ingresses/ingresses_test.go b/cmd/plugin/commands/ingresses/ingresses_test.go new file mode 100644 index 000000000..6a8d8837f --- /dev/null +++ b/cmd/plugin/commands/ingresses/ingresses_test.go @@ -0,0 +1,75 @@ +/* +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. +*/ + +package ingresses + +import ( + "testing" + + networking "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +func TestGetIngressInformation(t *testing.T) { + + testcases := map[string]struct { + ServiceBackend *networking.IngressServiceBackend + wantName string + wantPort intstr.IntOrString + }{ + "empty ingressServiceBackend": { + ServiceBackend: &networking.IngressServiceBackend{}, + wantName: "", + wantPort: intstr.IntOrString{}, + }, + "ingressServiceBackend with port 8080": { + ServiceBackend: &networking.IngressServiceBackend{ + Name: "test", + Port: networking.ServiceBackendPort{ + Number: 8080, + }, + }, + wantName: "test", + wantPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 8080, + }, + }, + "ingressServiceBackend with port name a-svc": { + ServiceBackend: &networking.IngressServiceBackend{ + Name: "test", + Port: networking.ServiceBackendPort{ + Name: "a-svc", + }, + }, + wantName: "test", + wantPort: intstr.IntOrString{ + Type: intstr.String, + StrVal: "a-svc", + }, + }, + } + + for title, testCase := range testcases { + gotName, gotPort := serviceToNameAndPort(testCase.ServiceBackend) + if gotName != testCase.wantName { + t.Fatalf("%s: expected '%v' but returned %v", title, testCase.wantName, gotName) + } + if gotPort != testCase.wantPort { + t.Fatalf("%s: expected '%v' but returned %v", title, testCase.wantPort, gotPort) + } + } +} diff --git a/cmd/plugin/commands/lint/main.go b/cmd/plugin/commands/lint/main.go index d120e9311..2daf8eb87 100644 --- a/cmd/plugin/commands/lint/main.go +++ b/cmd/plugin/commands/lint/main.go @@ -22,7 +22,7 @@ import ( "github.com/spf13/cobra" appsv1 "k8s.io/api/apps/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" kmeta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/cli-runtime/pkg/genericclioptions" diff --git a/cmd/plugin/lints/ingress.go b/cmd/plugin/lints/ingress.go index 0de4661f4..ea08bfd8b 100644 --- a/cmd/plugin/lints/ingress.go +++ b/cmd/plugin/lints/ingress.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" kmeta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/cmd/plugin/util" ) diff --git a/cmd/plugin/request/request.go b/cmd/plugin/request/request.go index b8bc4eaae..cae90e9d2 100644 --- a/cmd/plugin/request/request.go +++ b/cmd/plugin/request/request.go @@ -22,12 +22,12 @@ import ( appsv1 "k8s.io/api/apps/v1" apiv1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/cli-runtime/pkg/genericclioptions" appsv1client "k8s.io/client-go/kubernetes/typed/apps/v1" corev1 "k8s.io/client-go/kubernetes/typed/core/v1" - typednetworking "k8s.io/client-go/kubernetes/typed/networking/v1beta1" + typednetworking "k8s.io/client-go/kubernetes/typed/networking/v1" "k8s.io/ingress-nginx/cmd/plugin/util" ) diff --git a/deploy/static/provider/aws/deploy-tls-termination.yaml b/deploy/static/provider/aws/deploy-tls-termination.yaml index e70e88853..5d4331839 100644 --- a/deploy/static/provider/aws/deploy-tls-termination.yaml +++ b/deploy/static/provider/aws/deploy-tls-termination.yaml @@ -440,7 +440,7 @@ webhooks: - apiGroups: - networking.k8s.io apiVersions: - - v1beta1 + - v1 operations: - CREATE - UPDATE @@ -450,12 +450,11 @@ webhooks: sideEffects: None admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: namespace: ingress-nginx name: ingress-nginx-controller-admission - path: /networking/v1beta1/ingresses + path: /networking/v1/ingresses --- # Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml apiVersion: v1 diff --git a/deploy/static/provider/aws/deploy.yaml b/deploy/static/provider/aws/deploy.yaml index 15831416d..c5d58b112 100644 --- a/deploy/static/provider/aws/deploy.yaml +++ b/deploy/static/provider/aws/deploy.yaml @@ -427,7 +427,7 @@ webhooks: - apiGroups: - networking.k8s.io apiVersions: - - v1beta1 + - v1 operations: - CREATE - UPDATE @@ -437,12 +437,11 @@ webhooks: sideEffects: None admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: namespace: ingress-nginx name: ingress-nginx-controller-admission - path: /networking/v1beta1/ingresses + path: /networking/v1/ingresses --- # Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml apiVersion: v1 diff --git a/deploy/static/provider/baremetal/deploy.yaml b/deploy/static/provider/baremetal/deploy.yaml index 63ad2a46e..956d8fc8d 100644 --- a/deploy/static/provider/baremetal/deploy.yaml +++ b/deploy/static/provider/baremetal/deploy.yaml @@ -422,7 +422,7 @@ webhooks: - apiGroups: - networking.k8s.io apiVersions: - - v1beta1 + - v1 operations: - CREATE - UPDATE @@ -432,12 +432,11 @@ webhooks: sideEffects: None admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: namespace: ingress-nginx name: ingress-nginx-controller-admission - path: /networking/v1beta1/ingresses + path: /networking/v1/ingresses --- # Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml apiVersion: v1 diff --git a/deploy/static/provider/cloud/deploy.yaml b/deploy/static/provider/cloud/deploy.yaml index bfce22c62..4681a5d5d 100644 --- a/deploy/static/provider/cloud/deploy.yaml +++ b/deploy/static/provider/cloud/deploy.yaml @@ -424,7 +424,7 @@ webhooks: - apiGroups: - networking.k8s.io apiVersions: - - v1beta1 + - v1 operations: - CREATE - UPDATE @@ -434,12 +434,11 @@ webhooks: sideEffects: None admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: namespace: ingress-nginx name: ingress-nginx-controller-admission - path: /networking/v1beta1/ingresses + path: /networking/v1/ingresses --- # Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml apiVersion: v1 diff --git a/deploy/static/provider/do/deploy.yaml b/deploy/static/provider/do/deploy.yaml index b262c1edd..e8a9ff146 100644 --- a/deploy/static/provider/do/deploy.yaml +++ b/deploy/static/provider/do/deploy.yaml @@ -426,7 +426,7 @@ webhooks: - apiGroups: - networking.k8s.io apiVersions: - - v1beta1 + - v1 operations: - CREATE - UPDATE @@ -436,12 +436,12 @@ webhooks: sideEffects: None admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: namespace: ingress-nginx name: ingress-nginx-controller-admission - path: /networking/v1beta1/ingresses + path: /networking/v1/ingresses + timeoutSeconds: 29 --- # Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml apiVersion: v1 diff --git a/deploy/static/provider/exoscale/deploy.yaml b/deploy/static/provider/exoscale/deploy.yaml index 411e5c752..523188c3a 100644 --- a/deploy/static/provider/exoscale/deploy.yaml +++ b/deploy/static/provider/exoscale/deploy.yaml @@ -432,7 +432,7 @@ webhooks: - apiGroups: - networking.k8s.io apiVersions: - - v1beta1 + - v1 operations: - CREATE - UPDATE @@ -442,12 +442,11 @@ webhooks: sideEffects: None admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: namespace: ingress-nginx name: ingress-nginx-controller-admission - path: /networking/v1beta1/ingresses + path: /networking/v1/ingresses --- # Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml apiVersion: v1 diff --git a/deploy/static/provider/kind/deploy.yaml b/deploy/static/provider/kind/deploy.yaml index 7198b1d03..7d381814d 100644 --- a/deploy/static/provider/kind/deploy.yaml +++ b/deploy/static/provider/kind/deploy.yaml @@ -434,7 +434,7 @@ webhooks: - apiGroups: - networking.k8s.io apiVersions: - - v1beta1 + - v1 operations: - CREATE - UPDATE @@ -444,12 +444,11 @@ webhooks: sideEffects: None admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: namespace: ingress-nginx name: ingress-nginx-controller-admission - path: /networking/v1beta1/ingresses + path: /networking/v1/ingresses --- # Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml apiVersion: v1 diff --git a/deploy/static/provider/scw/deploy.yaml b/deploy/static/provider/scw/deploy.yaml index 76104696f..efc268fd0 100644 --- a/deploy/static/provider/scw/deploy.yaml +++ b/deploy/static/provider/scw/deploy.yaml @@ -426,7 +426,7 @@ webhooks: - apiGroups: - networking.k8s.io apiVersions: - - v1beta1 + - v1 operations: - CREATE - UPDATE @@ -436,12 +436,11 @@ webhooks: sideEffects: None admissionReviewVersions: - v1 - - v1beta1 clientConfig: service: namespace: ingress-nginx name: ingress-nginx-controller-admission - path: /networking/v1beta1/ingresses + path: /networking/v1/ingresses --- # Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml apiVersion: v1 diff --git a/docs/developer-guide/getting-started.md b/docs/developer-guide/getting-started.md index eb5e7cae5..1f648533e 100644 --- a/docs/developer-guide/getting-started.md +++ b/docs/developer-guide/getting-started.md @@ -67,7 +67,7 @@ FOCUS="no-auth-locations" make kind-e2e-test Valid values are defined in the describe definition of the e2e tests like [Default Backend](https://github.com/kubernetes/ingress-nginx/blob/master/test/e2e/defaultbackend/default_backend.go#L29) -The complete list of tests can be found [here](e2e-tests.md) +The complete list of tests can be found [here](../e2e-tests.md) ### Custom docker image diff --git a/docs/examples/affinity/cookie/ingress-samesite.yaml b/docs/examples/affinity/cookie/ingress-samesite.yaml index 42d1c2e2d..b3f8f4b20 100644 --- a/docs/examples/affinity/cookie/ingress-samesite.yaml +++ b/docs/examples/affinity/cookie/ingress-samesite.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cookie-samesite-none @@ -19,7 +19,7 @@ spec: servicePort: 80 path: / --- -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cookie-samesite-strict diff --git a/docs/examples/affinity/cookie/ingress.yaml b/docs/examples/affinity/cookie/ingress.yaml index 57edbdbd3..eac973fde 100644 --- a/docs/examples/affinity/cookie/ingress.yaml +++ b/docs/examples/affinity/cookie/ingress.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-test diff --git a/docs/examples/auth/basic/README.md b/docs/examples/auth/basic/README.md index 194bacb3b..a5fa579e0 100644 --- a/docs/examples/auth/basic/README.md +++ b/docs/examples/auth/basic/README.md @@ -30,7 +30,7 @@ type: Opaque ```console echo " -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-with-auth diff --git a/docs/examples/auth/client-certs/ingress.yaml b/docs/examples/auth/client-certs/ingress.yaml index cf5f701b2..7172081b4 100644 --- a/docs/examples/auth/client-certs/ingress.yaml +++ b/docs/examples/auth/client-certs/ingress.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: diff --git a/docs/examples/auth/external-auth/README.md b/docs/examples/auth/external-auth/README.md index a08138373..235cca9cb 100644 --- a/docs/examples/auth/external-auth/README.md +++ b/docs/examples/auth/external-auth/README.md @@ -13,7 +13,7 @@ NAME HOSTS ADDRESS PORTS AGE external-auth external-auth-01.sample.com 172.17.4.99 80 13s $ kubectl get ing external-auth -o yaml -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: @@ -23,7 +23,7 @@ metadata: name: external-auth namespace: default resourceVersion: "2068378" - selfLink: /apis/networking/v1beta1/namespaces/default/ingresses/external-auth + selfLink: /apis/networking/v1/namespaces/default/ingresses/external-auth uid: 5c388f1d-8970-11e6-9004-080027d2dc94 spec: rules: diff --git a/docs/examples/auth/external-auth/ingress.yaml b/docs/examples/auth/external-auth/ingress.yaml index c7a87a240..2a58ca2e3 100644 --- a/docs/examples/auth/external-auth/ingress.yaml +++ b/docs/examples/auth/external-auth/ingress.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: diff --git a/docs/examples/auth/oauth-external-auth/dashboard-ingress.yaml b/docs/examples/auth/oauth-external-auth/dashboard-ingress.yaml index ade56a9e6..725bf1dc5 100644 --- a/docs/examples/auth/oauth-external-auth/dashboard-ingress.yaml +++ b/docs/examples/auth/oauth-external-auth/dashboard-ingress.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: @@ -18,7 +18,7 @@ spec: --- -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: oauth2-proxy diff --git a/docs/examples/chashsubset/deployment.yaml b/docs/examples/chashsubset/deployment.yaml index 9b1bafcb1..82fdc7ac0 100644 --- a/docs/examples/chashsubset/deployment.yaml +++ b/docs/examples/chashsubset/deployment.yaml @@ -54,7 +54,7 @@ spec: targetPort: 8080 --- -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: diff --git a/docs/examples/customization/configuration-snippets/ingress.yaml b/docs/examples/customization/configuration-snippets/ingress.yaml index 07af3552f..70d9042c7 100644 --- a/docs/examples/customization/configuration-snippets/ingress.yaml +++ b/docs/examples/customization/configuration-snippets/ingress.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-configuration-snippet diff --git a/docs/examples/customization/external-auth-headers/deploy/echo-service.yaml b/docs/examples/customization/external-auth-headers/deploy/echo-service.yaml index 1c3667c7c..075421807 100644 --- a/docs/examples/customization/external-auth-headers/deploy/echo-service.yaml +++ b/docs/examples/customization/external-auth-headers/deploy/echo-service.yaml @@ -43,7 +43,7 @@ spec: selector: k8s-app: demo-echo-service --- -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: public-demo-echo-service @@ -61,7 +61,7 @@ spec: servicePort: 80 path: / --- -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: secure-demo-echo-service diff --git a/docs/examples/docker-registry/ingress-with-tls.yaml b/docs/examples/docker-registry/ingress-with-tls.yaml index fc277b20f..11ccf6627 100644 --- a/docs/examples/docker-registry/ingress-with-tls.yaml +++ b/docs/examples/docker-registry/ingress-with-tls.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: diff --git a/docs/examples/docker-registry/ingress-without-tls.yaml b/docs/examples/docker-registry/ingress-without-tls.yaml index 1ce1b98fb..2d713cb8c 100644 --- a/docs/examples/docker-registry/ingress-without-tls.yaml +++ b/docs/examples/docker-registry/ingress-without-tls.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: diff --git a/docs/examples/grpc/ingress.yaml b/docs/examples/grpc/ingress.yaml index 1d76476d1..1d45665ed 100644 --- a/docs/examples/grpc/ingress.yaml +++ b/docs/examples/grpc/ingress.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: diff --git a/docs/examples/multi-tls/multi-tls.yaml b/docs/examples/multi-tls/multi-tls.yaml index c616501be..29395a285 100644 --- a/docs/examples/multi-tls/multi-tls.yaml +++ b/docs/examples/multi-tls/multi-tls.yaml @@ -92,7 +92,7 @@ spec: fieldPath: status.podIP --- -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: foo-tls diff --git a/docs/examples/rewrite/README.md b/docs/examples/rewrite/README.md index 3ad5e4fcd..824b0966f 100644 --- a/docs/examples/rewrite/README.md +++ b/docs/examples/rewrite/README.md @@ -34,7 +34,7 @@ Create an Ingress rule with a rewrite annotation: ```console $ echo ' -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: @@ -66,7 +66,7 @@ For example, the ingress definition above will result in the following rewrites: Create an Ingress rule with an app-root annotation: ``` $ echo " -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: diff --git a/docs/examples/static-ip/nginx-ingress.yaml b/docs/examples/static-ip/nginx-ingress.yaml index aa4877e56..358942f5c 100644 --- a/docs/examples/static-ip/nginx-ingress.yaml +++ b/docs/examples/static-ip/nginx-ingress.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-nginx diff --git a/docs/examples/tls-termination/README.md b/docs/examples/tls-termination/README.md index 1a17d6d21..f3096db2e 100644 --- a/docs/examples/tls-termination/README.md +++ b/docs/examples/tls-termination/README.md @@ -11,7 +11,7 @@ You need a [TLS cert](../PREREQUISITES.md#tls-certificates) and a [test HTTP ser Create a `ingress.yaml` file. ```yaml -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-test diff --git a/docs/examples/tls-termination/ingress.yaml b/docs/examples/tls-termination/ingress.yaml index fc97b3707..2e989d1b0 100644 --- a/docs/examples/tls-termination/ingress.yaml +++ b/docs/examples/tls-termination/ingress.yaml @@ -1,4 +1,4 @@ -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-test diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 1707aa0e2..7ecd71c65 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -32,7 +32,7 @@ Rules: /tea tea-svc:80 () /coffee coffee-svc:80 () Annotations: - kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{},"name":"cafe-ingress","namespace":"default","selfLink":"/apis/networking/v1beta1/namespaces/default/ingresses/cafe-ingress"},"spec":{"rules":[{"host":"cafe.com","http":{"paths":[{"backend":{"serviceName":"tea-svc","servicePort":80},"path":"/tea"},{"backend":{"serviceName":"coffee-svc","servicePort":80},"path":"/coffee"}]}}]},"status":{"loadBalancer":{"ingress":[{"ip":"169.48.142.110"}]}}} + kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{},"name":"cafe-ingress","namespace":"default","selfLink":"/apis/networking/v1/namespaces/default/ingresses/cafe-ingress"},"spec":{"rules":[{"host":"cafe.com","http":{"paths":[{"backend":{"serviceName":"tea-svc","servicePort":80},"path":"/tea"},{"backend":{"serviceName":"coffee-svc","servicePort":80},"path":"/coffee"}]}}]},"status":{"loadBalancer":{"ingress":[{"ip":"169.48.142.110"}]}}} Events: Type Reason Age From Message @@ -208,9 +208,9 @@ $ kubectl exec test-701078429-s5kca -- curl --cacert /var/run/secrets/kubernetes "/apis/apps", "/apis/apps/v1alpha1", "/apis/authentication.k8s.io", - "/apis/authentication.k8s.io/v1beta1", + "/apis/authentication.k8s.io/v1", "/apis/authorization.k8s.io", - "/apis/authorization.k8s.io/v1beta1", + "/apis/authorization.k8s.io/v1", "/apis/autoscaling", "/apis/autoscaling/v1", "/apis/batch", @@ -219,13 +219,13 @@ $ kubectl exec test-701078429-s5kca -- curl --cacert /var/run/secrets/kubernetes "/apis/certificates.k8s.io", "/apis/certificates.k8s.io/v1alpha1", "/apis/networking", - "/apis/networking/v1beta1", + "/apis/networking/v1", "/apis/policy", "/apis/policy/v1alpha1", "/apis/rbac.authorization.k8s.io", "/apis/rbac.authorization.k8s.io/v1alpha1", "/apis/storage.k8s.io", - "/apis/storage.k8s.io/v1beta1", + "/apis/storage.k8s.io/v1", "/healthz", "/healthz/ping", "/logs", diff --git a/docs/user-guide/basic-usage.md b/docs/user-guide/basic-usage.md index 82019d978..808b5ce8d 100644 --- a/docs/user-guide/basic-usage.md +++ b/docs/user-guide/basic-usage.md @@ -5,7 +5,7 @@ ingress-nginx can be used for many use cases, inside various cloud provider and First of all follow the instructions to install ingress-nginx. Then imagine that you need to expose 2 HTTP services already installed: `myServiceA`, `myServiceB`. Let's say that you want to expose the first at `myServiceA.foo.org` and the second at `myServiceB.foo.org`. One possible solution is to create two **ingress** resources: ``` -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-myservicea @@ -22,7 +22,7 @@ spec: serviceName: myservicea servicePort: 80 --- -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-myserviceb diff --git a/docs/user-guide/cli-arguments.md b/docs/user-guide/cli-arguments.md index 799ce7324..d51c75994 100644 --- a/docs/user-guide/cli-arguments.md +++ b/docs/user-guide/cli-arguments.md @@ -33,6 +33,8 @@ They are set in the container spec of the `nginx-ingress-controller` Deployment | `--log_file_max_size` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) | | `--logtostderr` | log to standard error instead of files (default true) | | `--maxmind-edition-ids` | Maxmind edition ids to download GeoLite2 Databases. (default "GeoLite2-City,GeoLite2-ASN") | +| `--maxmind-retries-timeout` | Maxmind downloading delay between 1st and 2nd attempt, 0s - do not retry to download if something went wrong. (default 0s) | +| `--maxmind-retries-count` | Number of attempts to download the GeoIP DB. (default 1) | | `--maxmind-license-key` | Maxmind license key to download GeoLite2 Databases. https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases | | `--metrics-per-host` | Export metrics per-host (default true) | | `--profiler-port` | Port to use for expose the ingress controller Go profiler when it is enabled. (default 10245) | diff --git a/docs/user-guide/fcgi-services.md b/docs/user-guide/fcgi-services.md index 7c9dd6138..62271c2ce 100644 --- a/docs/user-guide/fcgi-services.md +++ b/docs/user-guide/fcgi-services.md @@ -60,7 +60,7 @@ data: --- -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: diff --git a/docs/user-guide/ingress-path-matching.md b/docs/user-guide/ingress-path-matching.md index 092cf9264..6812e2cb5 100644 --- a/docs/user-guide/ingress-path-matching.md +++ b/docs/user-guide/ingress-path-matching.md @@ -15,7 +15,7 @@ This can be enabled by setting the `nginx.ingress.kubernetes.io/use-regex` annot See the [description](./nginx-configuration/annotations.md#use-regex) of the `use-regex` annotation for more details. ```yaml -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress @@ -51,7 +51,7 @@ In NGINX, regular expressions follow a **first match** policy. In order to enabl Let the following two ingress definitions be created: ```yaml -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress-1 @@ -71,7 +71,7 @@ spec: ``` ```yaml -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress-2 @@ -125,7 +125,7 @@ This case is expected and a result of NGINX's a first match policy for paths tha Let the following ingress be defined: ```yaml -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress-3 diff --git a/docs/user-guide/nginx-configuration/annotations.md b/docs/user-guide/nginx-configuration/annotations.md index add5c5595..465b4a60b 100755 --- a/docs/user-guide/nginx-configuration/annotations.md +++ b/docs/user-guide/nginx-configuration/annotations.md @@ -391,7 +391,7 @@ For more information please see [the `server_name` documentation](http://nginx.o Using the annotation `nginx.ingress.kubernetes.io/server-snippet` it is possible to add custom configuration in the server configuration block. ```yaml -apiVersion: networking.k8s.io/v1beta1 +apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: diff --git a/docs/user-guide/nginx-configuration/configmap.md b/docs/user-guide/nginx-configuration/configmap.md index df357d5e9..c947c7a86 100755 --- a/docs/user-guide/nginx-configuration/configmap.md +++ b/docs/user-guide/nginx-configuration/configmap.md @@ -54,7 +54,7 @@ The following table shows a configuration option's name, type, and the default v |[http2-max-field-size](#http2-max-field-size)|string|"4k"| |[http2-max-header-size](#http2-max-header-size)|string|"16k"| |[http2-max-requests](#http2-max-requests)|int|1000| -|[http2-max-concurrent-streams](#http2-max-concurrent-streams)|int|1000| +|[http2-max-concurrent-streams](#http2-max-concurrent-streams)|int|128| |[hsts](#hsts)|bool|"true"| |[hsts-include-subdomains](#hsts-include-subdomains)|bool|"true"| |[hsts-max-age](#hsts-max-age)|string|"15724800"| @@ -178,6 +178,9 @@ The following table shows a configuration option's name, type, and the default v |[proxy-buffering](#proxy-buffering)|string|"off"| |[limit-req-status-code](#limit-req-status-code)|int|503| |[limit-conn-status-code](#limit-conn-status-code)|int|503| +|[enable-syslog](#enable-syslog)|bool|false| +|[syslog-host](#syslog-host)|string|""| +|[syslog-port](#syslog-port)|int|514| |[no-tls-redirect-locations](#no-tls-redirect-locations)|string|"/.well-known/acme-challenge"| |[global-auth-url](#global-auth-url)|string|""| |[global-auth-method](#global-auth-method)|string|""| @@ -451,7 +454,7 @@ _**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. -The default of 0 means "max open files (system's limit) / [worker-processes](#worker-processes) - 1024". +The default of 0 means "max open files (system's limit) - 1024". _**default:**_ 0 ## map-hash-bucket-size @@ -1071,6 +1074,18 @@ Sets the [status code to return in response to rejected requests](http://nginx.o 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 +## enable-syslog + +Enable [syslog](http://nginx.org/en/docs/syslog.html) feature for access log and error log. _**default:**_ false + +## syslog-host + +Sets the address of syslog server. The address can be specified as a domain name or IP address. + +## syslog-port + +Sets the port of syslog server. _**default:**_ 514 + ## no-tls-redirect-locations A comma-separated list of locations on which http requests will never get redirected to their https counterpart. diff --git a/docs/user-guide/third-party-addons/opentracing.md b/docs/user-guide/third-party-addons/opentracing.md index 3bef8332c..916b29637 100644 --- a/docs/user-guide/third-party-addons/opentracing.md +++ b/docs/user-guide/third-party-addons/opentracing.md @@ -168,7 +168,7 @@ In the Zipkin interface we can see the details: # Apply the Ingress Resource $ echo ' - apiVersion: networking.k8s.io/v1beta1 + apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echo-ingress diff --git a/go.mod b/go.mod index efbf04769..e07dfcfff 100644 --- a/go.mod +++ b/go.mod @@ -17,9 +17,10 @@ require ( github.com/mitchellh/mapstructure v1.3.2 github.com/moul/pb v0.0.0-20180404114147-54bdd96e6a52 github.com/ncabatoff/process-exporter v0.7.2 - github.com/onsi/ginkgo v1.14.1 + github.com/onsi/ginkgo v1.16.4 github.com/opencontainers/runc v1.0.0-rc92 github.com/pkg/errors v0.9.1 + github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_golang v1.7.1 github.com/prometheus/client_model v0.2.0 github.com/prometheus/common v0.14.0 @@ -28,21 +29,22 @@ require ( github.com/stretchr/testify v1.6.1 github.com/tallclair/mdtoc v1.0.0 github.com/zakjan/cert-chain-resolver v0.0.0-20200729110141-6b99e360f97a - golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 - golang.org/x/net v0.0.0-20201110031124-69a78807bb2b + golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 + golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 google.golang.org/grpc v1.27.1 gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/go-playground/pool.v3 v3.1.1 - k8s.io/api v0.20.2 - k8s.io/apiextensions-apiserver v0.20.2 - k8s.io/apimachinery v0.20.2 - k8s.io/apiserver v0.20.2 - k8s.io/cli-runtime v0.20.2 - k8s.io/client-go v0.20.2 - k8s.io/code-generator v0.20.2 - k8s.io/component-base v0.20.2 - k8s.io/klog/v2 v2.4.0 + k8s.io/api v0.21.1 + k8s.io/apiextensions-apiserver v0.21.1 + k8s.io/apimachinery v0.21.1 + k8s.io/apiserver v0.21.1 + k8s.io/cli-runtime v0.21.1 + k8s.io/client-go v0.21.1 + k8s.io/code-generator v0.21.1 + k8s.io/component-base v0.21.1 + k8s.io/klog/v2 v2.8.0 k8s.io/utils v0.0.0-20201110183641-67b214c5f920 pault.ag/go/sniff v0.0.0-20200207005214-cf7e4d167732 sigs.k8s.io/controller-runtime v0.8.0 + sigs.k8s.io/kind v0.11.1 // indirect ) diff --git a/go.sum b/go.sum index 4439cb737..b6d88cecf 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,5 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= @@ -27,8 +26,9 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.1 h1:eVvIXUKiTgv++6YnWb42DUA1YL7qDugnKP0HljexdnQ= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.12 h1:gI8ytXbxMfI+IVbI9mP2JGCTXIuhHLgRlvQ9X4PsnHE= +github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5 h1:Y3bBUV4rTuxenJJs41HU3qmqsb+auo+a3Lz+PlJPpL0= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= @@ -46,7 +46,9 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= 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= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= @@ -55,6 +57,7 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -62,20 +65,23 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= 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-proxyproto v0.0.0-20200108142055-f0b8253b1507 h1:dmVRVC/MmuwC2edm/P6oWIP+9n+p9IgVgK0lq9mBQjU= github.com/armon/go-proxyproto v0.0.0-20200108142055-f0b8253b1507/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -97,15 +103,14 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= 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 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= @@ -113,26 +118,25 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/go-systemd/v22 v22.1.0 h1:kq/SbG2BCKLkDKkjQf5OWwKWUKj1lgs3lFI4PxnR5lg= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/channels v1.1.0 h1:F1taHcn7/F0i8DYqKXJnyhJcVpp2kgFcNePxXtnyu4k= github.com/eapache/channels v1.1.0/go.mod h1:jMm2qB5Ubtg9zLd+inMZd2/NUvXgzmWXsDaLyQIGfH0= @@ -142,7 +146,6 @@ github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/ekalinin/github-markdown-toc v0.0.0-20190514155158-83fadb60a7f1/go.mod h1:XfZS1iyC28CnllR54Ou2Ero6qs4Rmn7GpVumNSj1DZo= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= @@ -150,11 +153,10 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/fasthttp/websocket v1.4.2 h1:AU/zSiIIAuJjBMf5o+vO0syGOnEfvZRu40xIhW/3RuM= +github.com/evanphx/json-patch/v5 v5.2.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fasthttp/websocket v1.4.2/go.mod h1:smsv/h4PBEBaU0XDTY5UwJTpZv69fQ0FfcLJr21mA6Y= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.0.0 h1:BrX964Rv5uQ3wwS+KRUAJCBBw5PQmgJfJ6v4yly5QwU= @@ -171,8 +173,11 @@ github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXt github.com/gavv/httpexpect/v2 v2.1.0 h1:Q7xnFuKqBY2si4DsqxdbWBt9rfrbVTT2/9YSomc9tEw= github.com/gavv/httpexpect/v2 v2.1.0/go.mod h1:lnd0TqJLrP+wkJk3SFwtrpSlOAZQ7HaaIFuOYbgqgUM= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -182,48 +187,80 @@ github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgO 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-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.3.0 h1:q4c+kbcR0d5rSurhBR8dIgieOaYpXtsdTYfx22Cu6rs= github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/zapr v0.2.0 h1:v6Ji8yBW77pva6NkJKQdHLAJKrIJKRHz0RXwPqCHSR4= +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.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw= +github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +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/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= 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 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= @@ -240,7 +277,6 @@ 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.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= 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= @@ -253,7 +289,6 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ 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= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= @@ -270,14 +305,14 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 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= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/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/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1 h1:A8Yhf6EtqTv9RMsU6MQTyrtV1TjWlR6xU9BsZIwuTCM= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= @@ -287,17 +322,15 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.0.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +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= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= @@ -316,7 +349,6 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -336,8 +368,8 @@ github.com/imkira/go-interpol v1.0.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/C github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 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= @@ -350,28 +382,24 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= 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= @@ -379,20 +407,22 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9 github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +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/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= 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-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= 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= @@ -410,7 +440,6 @@ github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9 github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= 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 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -418,14 +447,18 @@ github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/I github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 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= github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/moul/pb v0.0.0-20180404114147-54bdd96e6a52 h1:8zDEa5yAIWYBHSDpPbSgGIBL/SvPSE9/FlB3aQ54d/A= github.com/moul/pb v0.0.0-20180404114147-54bdd96e6a52/go.mod h1:jE2HT8eoucYyUPBFJMreiVlC3KPHkDMtN8wn+ef7Y64= github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= @@ -446,8 +479,10 @@ github.com/ncabatoff/go-seq v0.0.0-20180805175032-b08ef85ed833 h1:t4WWQ9I797y7QU github.com/ncabatoff/go-seq v0.0.0-20180805175032-b08ef85ed833/go.mod h1:0CznHmXSjMEqs5Tezj/w2emQoM41wzYM9KpDKUHPYag= github.com/ncabatoff/process-exporter v0.7.2 h1:2UxJJ5fm9fiiUHqHgbusrfceCFQpEET/+wADEOfDSqI= github.com/ncabatoff/process-exporter v0.7.2/go.mod h1:d7Yf/brhprE2fjCdtZ2Edt0so30RY5PmtRu6qD0gUOc= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= @@ -458,13 +493,13 @@ github.com/onsi/ginkgo v1.7.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.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= github.com/onsi/ginkgo v1.14.1/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/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 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 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -486,6 +521,7 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= 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= @@ -504,7 +540,6 @@ github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA= @@ -520,20 +555,16 @@ github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7q github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4= github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/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 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= 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 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -544,29 +575,28 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f h1:PgA+Olipyj258EIEYnpFFONrrCcAIWNUNoFhUfMqAGY= github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f/go.mod h1:lHhJedqxCoHN+zMtwGNTXWmF0u9Jt363FYRhV6g0CdY= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= 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= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= 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 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -575,6 +605,7 @@ github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 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/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -582,11 +613,9 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= 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= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= @@ -595,9 +624,10 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tallclair/mdtoc v1.0.0 h1:+FqBzRdFsgwrkzewUYC8GG6/hckREy9t4cDw4bWjx+M= github.com/tallclair/mdtoc v1.0.0/go.mod h1:BjDk9nfX4091pXLHhvf6Ejr4/r//9NslWmweWb2Hkbs= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -605,6 +635,7 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasthttp v1.9.0 h1:hNpmUdy/+ZXYpGy0OBfm7K0UQTzb73W0T0U4iJIVrMw= github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= @@ -614,68 +645,67 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg= github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI= +github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zakjan/cert-chain-resolver v0.0.0-20200729110141-6b99e360f97a h1:Tj7Mkjj6sjeNwFBiRHM7ieg1CiPHCDNSMSmS0ooGcZo= github.com/zakjan/cert-chain-resolver v0.0.0-20200729110141-6b99e360f97a/go.mod h1:KNkcm66cr4ilOiEcjydK+tc2ShPUhqmuoXCljXUBPu8= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= 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= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 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-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -695,10 +725,8 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -707,11 +735,13 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -720,9 +750,11 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -736,16 +768,15 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 h1:OgUuv8lsRpBibGNbSizVwKWlysjaNzmC9gYMhPVfqFM= +golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 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 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6 h1:pE8b58s1HRDMi8RDc79m0HISf9D4TzseP40cEA6IGfs= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -755,6 +786,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -766,6 +798,7 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -778,7 +811,9 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/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-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= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -786,6 +821,7 @@ golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/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= @@ -793,39 +829,44 @@ golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642 h1:B6caxRw+hozq68X2MY7jEpZh/cr4/aHLv9xU8Kkadrw= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPjc0178IU44m4EjOO5IY= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +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-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +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/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= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -836,6 +877,7 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 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= @@ -863,15 +905,17 @@ golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200616133436-c1934b75d054 h1:HHeAlu5H9b71C+Fx0K+1dGgVFN1DM1/wz4aoGOA5qS8= golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 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.1.0 h1:Phva6wqu+xR//Njw6iorylFFgn/z547tw5Ne3HZPQ+k= gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -887,10 +931,8 @@ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= @@ -901,7 +943,6 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= @@ -914,7 +955,6 @@ google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4 google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a h1:pOwg4OoaRYScjmR4LlLgdtnyoHYTSAVhhqe5uPdpII8= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -927,9 +967,7 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -939,24 +977,20 @@ 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.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 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= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/pool.v3 v3.1.1 h1:4Qcj91IsYTpIeRhe/eo6Fz+w6uKWPEghx8vHFTYMfhw= gopkg.in/go-playground/pool.v3 v3.1.1/go.mod h1:pUAGBximS/hccTTSzEop6wvvQhVa3QPDFFW+8REdutg= @@ -965,7 +999,6 @@ 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/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 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -975,57 +1008,61 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +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 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= 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= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= 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-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= -k8s.io/api v0.20.2 h1:y/HR22XDZY3pniu9hIFDLpUCPq2w5eQ6aV/VFQ7uJMw= -k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8= +k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c= +k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk= -k8s.io/apiextensions-apiserver v0.20.2 h1:rfrMWQ87lhd8EzQWRnbQ4gXrniL/yTRBgYH1x1+BLlo= -k8s.io/apiextensions-apiserver v0.20.2/go.mod h1:F6TXp389Xntt+LUq3vw6HFOLttPa0V8821ogLGwb6Zs= +k8s.io/apiextensions-apiserver v0.21.1 h1:AA+cnsb6w7SZ1vD32Z+zdgfXdXY8X9uGX5bN6EoPEIo= +k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.2 h1:hFx6Sbt1oG0n6DZ+g4bFt5f6BoMkOjKWsQFu077M3Vg= k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs= +k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= -k8s.io/apiserver v0.20.2 h1:lGno2t3gcZnLtzsKH4oG0xA9/4GTiBzMO1DGp+K+Bak= -k8s.io/apiserver v0.20.2/go.mod h1:2nKd93WyMhZx4Hp3RfgH2K5PhwyTrprrkWYnI7id7jA= -k8s.io/cli-runtime v0.20.2 h1:W0/FHdbApnl9oB7xdG643c/Zaf7TZT+43I+zKxwqvhU= -k8s.io/cli-runtime v0.20.2/go.mod h1:FjH6uIZZZP3XmwrXWeeYCbgxcrD6YXxoAykBaWH0VdM= +k8s.io/apiserver v0.21.1 h1:wTRcid53IhxhbFt4KTrFSw8tAncfr01EP91lzfcygVg= +k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY= +k8s.io/cli-runtime v0.21.1 h1:Oj/iZxa7LLXrhzShaLNF4rFJEIEBTDHj0dJw4ra2vX4= +k8s.io/cli-runtime v0.21.1/go.mod h1:TI9Bvl8lQWZB2KqE91QLCp9AZE4l29zNFnj/x4IX4Fw= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= -k8s.io/client-go v0.20.2 h1:uuf+iIAbfnCSw8IGAv/Rg0giM+2bOzHLOsbbrwrdhNQ= -k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE= +k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4= +k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= -k8s.io/code-generator v0.20.2 h1:SQaysped4EtUDk3u1zphnUJiOAwFdhHx9xS3WKAE0x8= -k8s.io/code-generator v0.20.2/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= +k8s.io/code-generator v0.21.1 h1:jvcxHpVu5dm/LMXr3GOj/jroiP8+v2YnJE9i2OVRenk= +k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= -k8s.io/component-base v0.20.2 h1:LMmu5I0pLtwjpp5009KLuMGFqSc2S2isGw8t1hpYKLE= -k8s.io/component-base v0.20.2/go.mod h1:pzFtCiwe/ASD0iV7ySMu8SYVJjCapNM9bjvk7ptpKh0= +k8s.io/component-base v0.21.1 h1:iLpj2btXbR326s/xNQWmPNGu0gaYSjzn7IN/5i28nQw= +k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20201113003025-83324d819ded h1:JApXBKYyB7l9xx+DK7/+mFjC7A9Bt5A93FPvFD0HIFE= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +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/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd h1:sOHNzJIkytDF6qadMNKhhDRpc6ODik8lVC6nOur7B2c= +k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= +k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= @@ -1036,12 +1073,17 @@ 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.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/controller-runtime v0.8.0 h1:s0dYdo7lQgJiAf+alP82PRwbz+oAqL3oSyMQ18XRDOc= sigs.k8s.io/controller-runtime v0.8.0/go.mod h1:v9Lbj5oX443uR7GXYY46E0EE2o7k2YxQ58GxVNeXSW4= -sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= -sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8= +sigs.k8s.io/kind v0.11.1/go.mod h1:fRpgVhtqAWrtLB9ED7zQahUimpUXuG/iHT88xYqEGIA= +sigs.k8s.io/kustomize/api v0.8.8 h1:G2z6JPSSjtWWgMeWSoHdXqyftJNmMmyxXpwENGoOtGE= +sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY= +sigs.k8s.io/kustomize/kyaml v0.10.17 h1:4zrV0ym5AYa0e512q7K3Wp1u7mzoWW0xR3UHJcGWGIg= +sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= +sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/hack/generate-deploy-scripts.sh b/hack/generate-deploy-scripts.sh index e20596c1d..a4872c6d8 100755 --- a/hack/generate-deploy-scripts.sh +++ b/hack/generate-deploy-scripts.sh @@ -163,6 +163,8 @@ controller: service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: "true" config: use-proxy-protocol: "true" + admissionWebhooks: + timeoutSeconds: 29 EOF diff --git a/images/OWNERS b/images/OWNERS index b135a937c..00f162ebd 100644 --- a/images/OWNERS +++ b/images/OWNERS @@ -1,7 +1,9 @@ +# See the OWNERS docs: https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md + approvers: -- aledbf -- ElvinEfendi +- ingress-nginx-admins +- ingress-nginx-maintainers reviewers: -- ElvinEfendi -- aledbf +- ingress-nginx-admins +- ingress-nginx-maintainers diff --git a/images/nginx/rootfs/build.sh b/images/nginx/rootfs/build.sh index ebea37cf6..2ac3a9ca3 100755 --- a/images/nginx/rootfs/build.sh +++ b/images/nginx/rootfs/build.sh @@ -62,6 +62,13 @@ export BUILD_PATH=/tmp/build ARCH=$(uname -m) +if [[ ${ARCH} == "s390x" ]]; then + export LUAJIT_VERSION=9d5750d28478abfdcaefdfdc408f87752a21e431 + export LUA_RESTY_CORE=0.1.17 + export LUA_NGX_VERSION=0.10.15 + export LUA_STREAM_NGX_VERSION=0.0.7 +fi + get_src() { hash="$1" @@ -93,7 +100,6 @@ apk add \ geoip-dev \ perl-dev \ libedit-dev \ - mercurial \ alpine-sdk \ findutils \ curl ca-certificates \ @@ -160,17 +166,28 @@ get_src 3a3a03060bf5e3fef52c9a2de02e6035cb557f389453d8f3b0c1d3d570636994 \ get_src 464f46744a6be778626d11452c4db3c2d09461080c6db42e358e21af19d542f6 \ "https://github.com/msgpack/msgpack-c/archive/cpp-$MSGPACK_VERSION.tar.gz" +if [[ ${ARCH} == "s390x" ]]; then +get_src 7d5f3439c8df56046d0564b5857fd8a30296ab1bd6df0f048aed7afb56a0a4c2 \ + "https://github.com/openresty/lua-nginx-module/archive/v$LUA_NGX_VERSION.tar.gz" +get_src 99c47c75c159795c9faf76bbb9fa58e5a50b75286c86565ffcec8514b1c74bf9 \ + "https://github.com/openresty/stream-lua-nginx-module/archive/v$LUA_STREAM_NGX_VERSION.tar.gz" +else get_src 7dc05df3d1824b02c6958ff37f9e682b73c1737dcfee93212ca3f6c5bfae08f3 \ "https://github.com/openresty/lua-nginx-module/archive/$LUA_NGX_VERSION.tar.gz" - get_src 6fcf7054f412a19c23c1ac3c0663f42f40bccc907d98c5d1657ae5cab9973ee9 \ "https://github.com/openresty/stream-lua-nginx-module/archive/v$LUA_STREAM_NGX_VERSION.tar.gz" +fi get_src 2a69815e4ae01aa8b170941a8e1a10b6f6a9aab699dee485d58f021dd933829a \ "https://github.com/openresty/lua-upstream-nginx-module/archive/v$LUA_UPSTREAM_VERSION.tar.gz" +if [[ ${ARCH} == "s390x" ]]; then +get_src 266ed1abb70a9806d97cb958537a44b67db6afb33d3b32292a2d68a2acedea75 \ + "https://github.com/openresty/luajit2/archive/$LUAJIT_VERSION.tar.gz" +else get_src f74a0821b079ea1fd63dd8659064356fc3f421ff4b35c17877140d2b2841cc3b \ "https://github.com/openresty/luajit2/archive/v$LUAJIT_VERSION.tar.gz" +fi get_src 40cc298f22bc29621024b68503335dcce464e42bcf02246f5864d7f8f2f5c379 \ "https://github.com/DataDog/dd-opentracing-cpp/archive/$DATADOG_CPP_VERSION.tar.gz" @@ -193,8 +210,13 @@ get_src bfd8c4b6c90aa9dcbe047ac798593a41a3f21edcb71904d50d8ac0e8c77d1132 \ get_src a21ec0d78a5dc5856df2374890a8a58e51de866b3d5978aceb0109a094367630 \ "https://github.com/openresty/lua-resty-balancer/archive/$LUA_RESTY_BALANCER.tar.gz" +if [[ ${ARCH} == "s390x" ]]; then +get_src 8f5f76d2689a3f6b0782f0a009c56a65e4c7a4382be86422c9b3549fe95b0dc4 \ + "https://github.com/openresty/lua-resty-core/archive/v$LUA_RESTY_CORE.tar.gz" +else get_src a377fbce78ba10f3ed3a8b5173ea318f8cf8da9d2ab127bb1e1f263078bf7da0 \ "https://github.com/openresty/lua-resty-core/archive/v$LUA_RESTY_CORE.tar.gz" +fi get_src bd6bee4ccc6cf3307ab6ca0eea693a921fab9b067ba40ae12a652636da588ff7 \ "https://github.com/openresty/lua-cjson/archive/$LUA_CJSON_VERSION.tar.gz" diff --git a/internal/admission/controller/convert.go b/internal/admission/controller/convert.go deleted file mode 100644 index 004e5d057..000000000 --- a/internal/admission/controller/convert.go +++ /dev/null @@ -1,90 +0,0 @@ -/* -Copyright 2020 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 controller - -import ( - "unsafe" - - admissionv1 "k8s.io/api/admission/v1" - admissionv1beta1 "k8s.io/api/admission/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" -) - -// these conversions are copied from https://github.com/kubernetes/kubernetes/blob/4db3a096ce8ac730b2280494422e1c4cf5fe875e/pkg/apis/admission/v1beta1/zz_generated.conversion.go -// to avoid copying in kubernetes/kubernetes -// they are sightly modified to remove complexity - -func convertV1beta1AdmissionReviewToAdmissionAdmissionReview(in *admissionv1beta1.AdmissionReview, out *admissionv1.AdmissionReview) { - if in.Request != nil { - if out.Request == nil { - out.Request = &admissionv1.AdmissionRequest{} - } - in, out := &in.Request, &out.Request - *out = new(admissionv1.AdmissionRequest) - convertV1beta1AdmissionRequestToAdmissionAdmissionRequest(*in, *out) - } else { - out.Request = nil - } - out.Response = (*admissionv1.AdmissionResponse)(unsafe.Pointer(in.Response)) // #nosec -} - -func convertV1beta1AdmissionRequestToAdmissionAdmissionRequest(in *admissionv1beta1.AdmissionRequest, out *admissionv1.AdmissionRequest) { - out.UID = types.UID(in.UID) - out.Kind = in.Kind - out.Resource = in.Resource - out.SubResource = in.SubResource - out.RequestKind = (*metav1.GroupVersionKind)(unsafe.Pointer(in.RequestKind)) // #nosec - out.RequestResource = (*metav1.GroupVersionResource)(unsafe.Pointer(in.RequestResource)) // #nosec - out.RequestSubResource = in.RequestSubResource - out.Name = in.Name - out.Namespace = in.Namespace - out.Operation = admissionv1.Operation(in.Operation) - out.Object = in.Object - out.OldObject = in.OldObject - out.Options = in.Options -} - -func convertAdmissionAdmissionReviewToV1beta1AdmissionReview(in *admissionv1.AdmissionReview, out *admissionv1beta1.AdmissionReview) { - if in.Request != nil { - if out.Request == nil { - out.Request = &admissionv1beta1.AdmissionRequest{} - } - in, out := &in.Request, &out.Request - *out = new(admissionv1beta1.AdmissionRequest) - convertAdmissionAdmissionRequestToV1beta1AdmissionRequest(*in, *out) - } else { - out.Request = nil - } - out.Response = (*admissionv1beta1.AdmissionResponse)(unsafe.Pointer(in.Response)) // #nosec -} - -func convertAdmissionAdmissionRequestToV1beta1AdmissionRequest(in *admissionv1.AdmissionRequest, out *admissionv1beta1.AdmissionRequest) { - out.UID = types.UID(in.UID) - out.Kind = in.Kind - out.Resource = in.Resource - out.SubResource = in.SubResource - out.RequestKind = (*metav1.GroupVersionKind)(unsafe.Pointer(in.RequestKind)) // #nosec - out.RequestResource = (*metav1.GroupVersionResource)(unsafe.Pointer(in.RequestResource)) // #nosec - out.RequestSubResource = in.RequestSubResource - out.Name = in.Name - out.Namespace = in.Namespace - out.Operation = admissionv1beta1.Operation(in.Operation) - out.Object = in.Object - out.OldObject = in.OldObject - out.Options = in.Options -} diff --git a/internal/admission/controller/main.go b/internal/admission/controller/main.go index 7c59cdd9e..066747301 100644 --- a/internal/admission/controller/main.go +++ b/internal/admission/controller/main.go @@ -21,12 +21,10 @@ import ( "net/http" admissionv1 "k8s.io/api/admission/v1" - admissionv1beta1 "k8s.io/api/admission/v1beta1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer/json" "k8s.io/klog/v2" ) @@ -46,7 +44,7 @@ type IngressAdmission struct { var ( ingressResource = metav1.GroupVersionKind{ Group: networking.GroupName, - Version: "v1beta1", + Version: "v1", Kind: "Ingress", } ) @@ -55,19 +53,10 @@ var ( // with Allowed=false if the Object is an ingress that would prevent nginx to reload the configuration // with Allowed=true otherwise func (ia *IngressAdmission) HandleAdmission(obj runtime.Object) (runtime.Object, error) { - outputVersion := admissionv1.SchemeGroupVersion review, isV1 := obj.(*admissionv1.AdmissionReview) - if !isV1 { - outputVersion = admissionv1beta1.SchemeGroupVersion - reviewv1beta1, isv1beta1 := obj.(*admissionv1beta1.AdmissionReview) - if !isv1beta1 { - return nil, fmt.Errorf("request is not of type AdmissionReview v1 or v1beta1") - } - - review = &admissionv1.AdmissionReview{} - convertV1beta1AdmissionReviewToAdmissionAdmissionReview(reviewv1beta1, review) + return nil, fmt.Errorf("request is not of type AdmissionReview v1 or v1beta1") } if !apiequality.Semantic.DeepEqual(review.Request.Kind, ingressResource) { @@ -94,7 +83,7 @@ func (ia *IngressAdmission) HandleAdmission(obj runtime.Object) (runtime.Object, } review.Response = status - return convertResponse(review, outputVersion), nil + return review, nil } if err := ia.Checker.CheckIngress(&ingress); err != nil { @@ -106,24 +95,12 @@ func (ia *IngressAdmission) HandleAdmission(obj runtime.Object) (runtime.Object, } review.Response = status - return convertResponse(review, outputVersion), nil + return review, nil } klog.InfoS("successfully validated configuration, accepting", "ingress", fmt.Sprintf("%v/%v", review.Request.Name, review.Request.Namespace)) status.Allowed = true review.Response = status - return convertResponse(review, outputVersion), nil -} - -func convertResponse(review *admissionv1.AdmissionReview, outputVersion schema.GroupVersion) runtime.Object { - // reply v1 - if outputVersion.Version == admissionv1.SchemeGroupVersion.Version { - return review - } - - // reply v1beta1 - reviewv1beta1 := &admissionv1beta1.AdmissionReview{} - convertAdmissionAdmissionReviewToV1beta1AdmissionReview(review, reviewv1beta1) - return review + return review, nil } diff --git a/internal/admission/controller/main_test.go b/internal/admission/controller/main_test.go index b745c14a2..7cc3cd7b4 100644 --- a/internal/admission/controller/main_test.go +++ b/internal/admission/controller/main_test.go @@ -21,7 +21,7 @@ import ( "testing" admissionv1 "k8s.io/api/admission/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/json" @@ -71,7 +71,7 @@ func TestHandleAdmission(t *testing.T) { result, err = adm.HandleAdmission(&admissionv1.AdmissionReview{ Request: &admissionv1.AdmissionRequest{ - Kind: v1.GroupVersionKind{Group: networking.GroupName, Version: "v1beta1", Kind: "Ingress"}, + Kind: v1.GroupVersionKind{Group: networking.GroupName, Version: "v1", Kind: "Ingress"}, Object: runtime.RawExtension{ Raw: []byte{0xff}, }, diff --git a/internal/admission/controller/server.go b/internal/admission/controller/server.go index 8c9235bdc..913e3b8de 100644 --- a/internal/admission/controller/server.go +++ b/internal/admission/controller/server.go @@ -21,7 +21,6 @@ import ( "net/http" admissionv1 "k8s.io/api/admission/v1" - admissionv1beta1 "k8s.io/api/admission/v1beta1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer/json" "k8s.io/klog/v2" @@ -32,7 +31,6 @@ var ( ) func init() { - admissionv1beta1.AddToScheme(scheme) admissionv1.AddToScheme(scheme) } diff --git a/internal/ingress/annotations/alias/main.go b/internal/ingress/annotations/alias/main.go index 6cbe4c6dc..bd2067c9f 100644 --- a/internal/ingress/annotations/alias/main.go +++ b/internal/ingress/annotations/alias/main.go @@ -20,7 +20,7 @@ import ( "sort" "strings" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" diff --git a/internal/ingress/annotations/alias/main_test.go b/internal/ingress/annotations/alias/main_test.go index a482fc7c1..8e6fca447 100644 --- a/internal/ingress/annotations/alias/main_test.go +++ b/internal/ingress/annotations/alias/main_test.go @@ -21,7 +21,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/annotations.go b/internal/ingress/annotations/annotations.go index 2c3b3c1cf..9fb53dd1e 100644 --- a/internal/ingress/annotations/annotations.go +++ b/internal/ingress/annotations/annotations.go @@ -25,7 +25,7 @@ import ( "k8s.io/klog/v2" apiv1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/alias" diff --git a/internal/ingress/annotations/annotations_test.go b/internal/ingress/annotations/annotations_test.go index 1a428e729..012e4fc6e 100644 --- a/internal/ingress/annotations/annotations_test.go +++ b/internal/ingress/annotations/annotations_test.go @@ -20,9 +20,8 @@ import ( "testing" apiv1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/defaults" @@ -76,8 +75,12 @@ func (m mockCfg) GetAuthCertificate(name string) (*resolver.AuthSSLCert, error) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -86,9 +89,13 @@ func buildIngress() *networking.Ingress { Namespace: apiv1.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/auth/main.go b/internal/ingress/annotations/auth/main.go index 9edfc1751..9fe54c1f9 100644 --- a/internal/ingress/annotations/auth/main.go +++ b/internal/ingress/annotations/auth/main.go @@ -24,7 +24,7 @@ import ( "github.com/pkg/errors" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/client-go/tools/cache" "k8s.io/ingress-nginx/internal/file" diff --git a/internal/ingress/annotations/auth/main_test.go b/internal/ingress/annotations/auth/main_test.go index b02741d01..fea465b5f 100644 --- a/internal/ingress/annotations/auth/main_test.go +++ b/internal/ingress/annotations/auth/main_test.go @@ -26,9 +26,8 @@ import ( "github.com/pkg/errors" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" ing_errors "k8s.io/ingress-nginx/internal/ingress/errors" "k8s.io/ingress-nginx/internal/ingress/resolver" @@ -36,8 +35,12 @@ import ( func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -46,9 +49,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/authreq/main.go b/internal/ingress/annotations/authreq/main.go index afcd84a65..6cfcc383d 100644 --- a/internal/ingress/annotations/authreq/main.go +++ b/internal/ingress/annotations/authreq/main.go @@ -23,7 +23,7 @@ import ( "k8s.io/klog/v2" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" ing_errors "k8s.io/ingress-nginx/internal/ingress/errors" diff --git a/internal/ingress/annotations/authreq/main_test.go b/internal/ingress/annotations/authreq/main_test.go index 276779c1c..da903fe30 100644 --- a/internal/ingress/annotations/authreq/main_test.go +++ b/internal/ingress/annotations/authreq/main_test.go @@ -22,18 +22,20 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" - - "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -42,9 +44,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/authreqglobal/main.go b/internal/ingress/annotations/authreqglobal/main.go index 170f6957d..78dd7d6a5 100644 --- a/internal/ingress/annotations/authreqglobal/main.go +++ b/internal/ingress/annotations/authreqglobal/main.go @@ -17,7 +17,7 @@ limitations under the License. package authreqglobal import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/authreqglobal/main_test.go b/internal/ingress/annotations/authreqglobal/main_test.go index a4096f7da..0313edcf5 100644 --- a/internal/ingress/annotations/authreqglobal/main_test.go +++ b/internal/ingress/annotations/authreqglobal/main_test.go @@ -20,18 +20,20 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" - - "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -40,9 +42,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/authtls/main.go b/internal/ingress/annotations/authtls/main.go index 16e218d33..dd89df4f3 100644 --- a/internal/ingress/annotations/authtls/main.go +++ b/internal/ingress/annotations/authtls/main.go @@ -18,7 +18,7 @@ package authtls import ( "github.com/pkg/errors" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "regexp" diff --git a/internal/ingress/annotations/authtls/main_test.go b/internal/ingress/annotations/authtls/main_test.go index d1a54ad70..b2c915d18 100644 --- a/internal/ingress/annotations/authtls/main_test.go +++ b/internal/ingress/annotations/authtls/main_test.go @@ -20,9 +20,8 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/errors" "k8s.io/ingress-nginx/internal/ingress/resolver" @@ -30,8 +29,12 @@ import ( func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -40,9 +43,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/backendprotocol/main.go b/internal/ingress/annotations/backendprotocol/main.go index d6e7beb4c..85a5fde5d 100644 --- a/internal/ingress/annotations/backendprotocol/main.go +++ b/internal/ingress/annotations/backendprotocol/main.go @@ -20,7 +20,7 @@ import ( "regexp" "strings" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/klog/v2" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" diff --git a/internal/ingress/annotations/backendprotocol/main_test.go b/internal/ingress/annotations/backendprotocol/main_test.go index 4a1c1bf31..e8c018998 100644 --- a/internal/ingress/annotations/backendprotocol/main_test.go +++ b/internal/ingress/annotations/backendprotocol/main_test.go @@ -20,12 +20,10 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" - - "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *networking.Ingress { @@ -35,9 +33,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, }, } diff --git a/internal/ingress/annotations/canary/main.go b/internal/ingress/annotations/canary/main.go index 2cc88021b..3930b84d7 100644 --- a/internal/ingress/annotations/canary/main.go +++ b/internal/ingress/annotations/canary/main.go @@ -17,7 +17,7 @@ limitations under the License. package canary import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/errors" diff --git a/internal/ingress/annotations/canary/main_test.go b/internal/ingress/annotations/canary/main_test.go index f755fe865..ddfc0a9c4 100644 --- a/internal/ingress/annotations/canary/main_test.go +++ b/internal/ingress/annotations/canary/main_test.go @@ -20,9 +20,8 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "strconv" @@ -32,8 +31,12 @@ import ( func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -42,9 +45,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/class/main.go b/internal/ingress/annotations/class/main.go deleted file mode 100644 index b2fe32d63..000000000 --- a/internal/ingress/annotations/class/main.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2015 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 class - -import ( - networking "k8s.io/api/networking/v1beta1" - "k8s.io/ingress-nginx/internal/k8s" -) - -const ( - // IngressKey picks a specific "class" for the Ingress. - // The controller only processes Ingresses with this annotation either - // unset, or set to either the configured value or the empty string. - IngressKey = "kubernetes.io/ingress.class" -) - -var ( - // DefaultClass defines the default class used in the nginx ingress controller - DefaultClass = "nginx" - - // IngressClass sets the runtime ingress class to use - // An empty string means accept all ingresses without - // annotation and the ones configured with class nginx - IngressClass = "nginx" -) - -// IsValid returns true if the given Ingress specify the ingress.class -// annotation or IngressClassName resource for Kubernetes >= v1.18 -func IsValid(ing *networking.Ingress) bool { - // 1. with annotation or IngressClass - ingress, ok := ing.GetAnnotations()[IngressKey] - if !ok && ing.Spec.IngressClassName != nil { - ingress = *ing.Spec.IngressClassName - } - - // empty ingress and IngressClass equal default - if len(ingress) == 0 && IngressClass == DefaultClass { - return true - } - - // k8s > v1.18. - // Processing may be redundant because k8s.IngressClass is obtained by IngressClass - // 3. without annotation and IngressClass. Check IngressClass - if k8s.IngressClass != nil { - return ingress == k8s.IngressClass.Name - } - - // 4. with IngressClass - return ingress == IngressClass -} diff --git a/internal/ingress/annotations/class/main_test.go b/internal/ingress/annotations/class/main_test.go deleted file mode 100644 index 2d863f072..000000000 --- a/internal/ingress/annotations/class/main_test.go +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package class - -import ( - "testing" - - api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" - meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/ingress-nginx/internal/k8s" -) - -func TestIsValidClass(t *testing.T) { - dc := DefaultClass - ic := IngressClass - k8sic := k8s.IngressClass - v1Ready := k8s.IsIngressV1Ready - // restore original values after the tests - defer func() { - DefaultClass = dc - IngressClass = ic - k8s.IngressClass = k8sic - k8s.IsIngressV1Ready = v1Ready - }() - - tests := []struct { - ingress string - controller string - defClass string - annotation bool - ingressClassName bool - k8sClass *networking.IngressClass - v1Ready bool - isValid bool - }{ - {"", "", "nginx", true, false, nil, false, true}, - {"", "nginx", "nginx", true, false, nil, false, true}, - {"nginx", "nginx", "nginx", true, false, nil, false, true}, - {"custom", "custom", "nginx", true, false, nil, false, true}, - {"", "killer", "nginx", true, false, nil, false, false}, - {"custom", "nginx", "nginx", true, false, nil, false, false}, - {"nginx", "nginx", "nginx", false, true, nil, false, true}, - {"custom", "nginx", "nginx", false, true, nil, true, false}, - {"nginx", "nginx", "nginx", false, true, nil, true, true}, - {"", "custom", "nginx", false, false, - &networking.IngressClass{ - ObjectMeta: meta_v1.ObjectMeta{ - Name: "custom", - }, - }, - false, false}, - {"", "custom", "nginx", false, false, - &networking.IngressClass{ - ObjectMeta: meta_v1.ObjectMeta{ - Name: "custom", - }, - }, - true, false}, - } - - for _, test := range tests { - ing := &networking.Ingress{ - ObjectMeta: meta_v1.ObjectMeta{ - Name: "foo", - Namespace: api.NamespaceDefault, - }, - } - - data := map[string]string{} - ing.SetAnnotations(data) - if test.annotation { - ing.Annotations[IngressKey] = test.ingress - } - if test.ingressClassName { - ing.Spec.IngressClassName = &[]string{test.ingress}[0] - } - - IngressClass = test.controller - DefaultClass = test.defClass - k8s.IngressClass = test.k8sClass - k8s.IsIngressV1Ready = test.v1Ready - - b := IsValid(ing) - if b != test.isValid { - t.Errorf("test %v - expected %v but %v was returned", test, test.isValid, b) - } - } -} diff --git a/internal/ingress/annotations/clientbodybuffersize/main.go b/internal/ingress/annotations/clientbodybuffersize/main.go index 924ceecd1..9020ee594 100644 --- a/internal/ingress/annotations/clientbodybuffersize/main.go +++ b/internal/ingress/annotations/clientbodybuffersize/main.go @@ -17,7 +17,7 @@ limitations under the License. package clientbodybuffersize import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/clientbodybuffersize/main_test.go b/internal/ingress/annotations/clientbodybuffersize/main_test.go index 56f64083c..9932f8314 100644 --- a/internal/ingress/annotations/clientbodybuffersize/main_test.go +++ b/internal/ingress/annotations/clientbodybuffersize/main_test.go @@ -20,7 +20,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/connection/main.go b/internal/ingress/annotations/connection/main.go index 7d45fdc36..e9b0c1865 100644 --- a/internal/ingress/annotations/connection/main.go +++ b/internal/ingress/annotations/connection/main.go @@ -17,7 +17,7 @@ limitations under the License. package connection import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/connection/main_test.go b/internal/ingress/annotations/connection/main_test.go index d86aeb16a..011a2948c 100644 --- a/internal/ingress/annotations/connection/main_test.go +++ b/internal/ingress/annotations/connection/main_test.go @@ -20,7 +20,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/cors/main.go b/internal/ingress/annotations/cors/main.go index 2f1a0a37b..44947a014 100644 --- a/internal/ingress/annotations/cors/main.go +++ b/internal/ingress/annotations/cors/main.go @@ -19,7 +19,7 @@ package cors import ( "regexp" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/cors/main_test.go b/internal/ingress/annotations/cors/main_test.go index 6f75ce6a7..a65bf12cd 100644 --- a/internal/ingress/annotations/cors/main_test.go +++ b/internal/ingress/annotations/cors/main_test.go @@ -20,17 +20,20 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -39,9 +42,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/customhttperrors/main.go b/internal/ingress/annotations/customhttperrors/main.go index 3c5fbf077..a05fb16c8 100644 --- a/internal/ingress/annotations/customhttperrors/main.go +++ b/internal/ingress/annotations/customhttperrors/main.go @@ -20,7 +20,7 @@ import ( "strconv" "strings" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/customhttperrors/main_test.go b/internal/ingress/annotations/customhttperrors/main_test.go index 3827d197f..1f87247ed 100644 --- a/internal/ingress/annotations/customhttperrors/main_test.go +++ b/internal/ingress/annotations/customhttperrors/main_test.go @@ -22,12 +22,10 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" - - "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *networking.Ingress { @@ -37,9 +35,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, }, } diff --git a/internal/ingress/annotations/defaultbackend/main.go b/internal/ingress/annotations/defaultbackend/main.go index ff4f41ce3..7b239497d 100644 --- a/internal/ingress/annotations/defaultbackend/main.go +++ b/internal/ingress/annotations/defaultbackend/main.go @@ -20,7 +20,7 @@ import ( "fmt" "github.com/pkg/errors" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/defaultbackend/main_test.go b/internal/ingress/annotations/defaultbackend/main_test.go index 927860215..ec23d32c2 100644 --- a/internal/ingress/annotations/defaultbackend/main_test.go +++ b/internal/ingress/annotations/defaultbackend/main_test.go @@ -20,19 +20,21 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/errors" "k8s.io/ingress-nginx/internal/ingress/resolver" - - "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -41,9 +43,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/fastcgi/main.go b/internal/ingress/annotations/fastcgi/main.go index 174a2716c..a7e96a014 100644 --- a/internal/ingress/annotations/fastcgi/main.go +++ b/internal/ingress/annotations/fastcgi/main.go @@ -21,7 +21,7 @@ import ( "reflect" "github.com/pkg/errors" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/client-go/tools/cache" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" diff --git a/internal/ingress/annotations/fastcgi/main_test.go b/internal/ingress/annotations/fastcgi/main_test.go index 6802a41c2..26d85e7ce 100644 --- a/internal/ingress/annotations/fastcgi/main_test.go +++ b/internal/ingress/annotations/fastcgi/main_test.go @@ -20,13 +20,11 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/errors" "k8s.io/ingress-nginx/internal/ingress/resolver" - - "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *networking.Ingress { @@ -36,9 +34,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "fastcgi", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, }, } diff --git a/internal/ingress/annotations/globalratelimit/main.go b/internal/ingress/annotations/globalratelimit/main.go index e4b18bd66..02a732847 100644 --- a/internal/ingress/annotations/globalratelimit/main.go +++ b/internal/ingress/annotations/globalratelimit/main.go @@ -21,7 +21,7 @@ import ( "time" "github.com/pkg/errors" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" ing_errors "k8s.io/ingress-nginx/internal/ingress/errors" diff --git a/internal/ingress/annotations/globalratelimit/main_test.go b/internal/ingress/annotations/globalratelimit/main_test.go index 38da8f4a9..341a9883c 100644 --- a/internal/ingress/annotations/globalratelimit/main_test.go +++ b/internal/ingress/annotations/globalratelimit/main_test.go @@ -23,10 +23,9 @@ import ( "github.com/pkg/errors" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" ing_errors "k8s.io/ingress-nginx/internal/ingress/errors" "k8s.io/ingress-nginx/internal/ingress/resolver" @@ -37,8 +36,12 @@ const expectedUID = "31285d47b1504dcfbd6f12c46d769f6e" func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -48,9 +51,13 @@ func buildIngress() *networking.Ingress { UID: UID, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/http2pushpreload/main.go b/internal/ingress/annotations/http2pushpreload/main.go index c542f03cf..27d3368f4 100644 --- a/internal/ingress/annotations/http2pushpreload/main.go +++ b/internal/ingress/annotations/http2pushpreload/main.go @@ -17,7 +17,7 @@ limitations under the License. package http2pushpreload import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/http2pushpreload/main_test.go b/internal/ingress/annotations/http2pushpreload/main_test.go index 6b24ecfae..bb98af93f 100644 --- a/internal/ingress/annotations/http2pushpreload/main_test.go +++ b/internal/ingress/annotations/http2pushpreload/main_test.go @@ -20,7 +20,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/influxdb/main.go b/internal/ingress/annotations/influxdb/main.go index cec014b89..1aee91f33 100644 --- a/internal/ingress/annotations/influxdb/main.go +++ b/internal/ingress/annotations/influxdb/main.go @@ -17,7 +17,7 @@ limitations under the License. package influxdb import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/influxdb/main_test.go b/internal/ingress/annotations/influxdb/main_test.go index 97ba14963..13d681509 100644 --- a/internal/ingress/annotations/influxdb/main_test.go +++ b/internal/ingress/annotations/influxdb/main_test.go @@ -20,17 +20,20 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -39,9 +42,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/ipwhitelist/main.go b/internal/ingress/annotations/ipwhitelist/main.go index 42d424873..4fd40ee2b 100644 --- a/internal/ingress/annotations/ipwhitelist/main.go +++ b/internal/ingress/annotations/ipwhitelist/main.go @@ -22,7 +22,7 @@ import ( "github.com/pkg/errors" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/net" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" diff --git a/internal/ingress/annotations/ipwhitelist/main_test.go b/internal/ingress/annotations/ipwhitelist/main_test.go index 43aef7573..5042bb200 100644 --- a/internal/ingress/annotations/ipwhitelist/main_test.go +++ b/internal/ingress/annotations/ipwhitelist/main_test.go @@ -20,9 +20,8 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/defaults" "k8s.io/ingress-nginx/internal/ingress/resolver" @@ -30,8 +29,12 @@ import ( func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -40,9 +43,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/loadbalancing/main.go b/internal/ingress/annotations/loadbalancing/main.go index ddae0ccbe..a8b4335e6 100644 --- a/internal/ingress/annotations/loadbalancing/main.go +++ b/internal/ingress/annotations/loadbalancing/main.go @@ -17,7 +17,7 @@ limitations under the License. package loadbalancing import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/loadbalancing/main_test.go b/internal/ingress/annotations/loadbalancing/main_test.go index bbda79715..e2be5c0ae 100644 --- a/internal/ingress/annotations/loadbalancing/main_test.go +++ b/internal/ingress/annotations/loadbalancing/main_test.go @@ -20,7 +20,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/log/main.go b/internal/ingress/annotations/log/main.go index 6cf99d9c8..4bc76dcf7 100644 --- a/internal/ingress/annotations/log/main.go +++ b/internal/ingress/annotations/log/main.go @@ -17,7 +17,7 @@ limitations under the License. package log import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/log/main_test.go b/internal/ingress/annotations/log/main_test.go index 068b1be16..c4632b010 100644 --- a/internal/ingress/annotations/log/main_test.go +++ b/internal/ingress/annotations/log/main_test.go @@ -20,17 +20,20 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -39,9 +42,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/mirror/main.go b/internal/ingress/annotations/mirror/main.go index b2591347e..e11d4b4fb 100644 --- a/internal/ingress/annotations/mirror/main.go +++ b/internal/ingress/annotations/mirror/main.go @@ -19,7 +19,7 @@ package mirror import ( "fmt" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/mirror/main_test.go b/internal/ingress/annotations/mirror/main_test.go index 1ecaef3b9..af7ed1b1f 100644 --- a/internal/ingress/annotations/mirror/main_test.go +++ b/internal/ingress/annotations/mirror/main_test.go @@ -21,7 +21,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/modsecurity/main.go b/internal/ingress/annotations/modsecurity/main.go index 91a0a5a94..c53739441 100644 --- a/internal/ingress/annotations/modsecurity/main.go +++ b/internal/ingress/annotations/modsecurity/main.go @@ -17,7 +17,7 @@ limitations under the License. package modsecurity import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) diff --git a/internal/ingress/annotations/modsecurity/main_test.go b/internal/ingress/annotations/modsecurity/main_test.go index 34d92533d..2ddbdf7e3 100644 --- a/internal/ingress/annotations/modsecurity/main_test.go +++ b/internal/ingress/annotations/modsecurity/main_test.go @@ -20,7 +20,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/opentracing/main.go b/internal/ingress/annotations/opentracing/main.go index 875d695f7..2ed4a2182 100644 --- a/internal/ingress/annotations/opentracing/main.go +++ b/internal/ingress/annotations/opentracing/main.go @@ -17,7 +17,7 @@ limitations under the License. package opentracing import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/opentracing/main_test.go b/internal/ingress/annotations/opentracing/main_test.go index f1e06b087..77e29cb5d 100644 --- a/internal/ingress/annotations/opentracing/main_test.go +++ b/internal/ingress/annotations/opentracing/main_test.go @@ -20,17 +20,20 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -39,9 +42,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/parser/main.go b/internal/ingress/annotations/parser/main.go index 3fae804da..b39e409b9 100644 --- a/internal/ingress/annotations/parser/main.go +++ b/internal/ingress/annotations/parser/main.go @@ -22,7 +22,7 @@ import ( "strconv" "strings" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/ingress-nginx/internal/ingress/errors" diff --git a/internal/ingress/annotations/parser/main_test.go b/internal/ingress/annotations/parser/main_test.go index 218565183..f63560ca3 100644 --- a/internal/ingress/annotations/parser/main_test.go +++ b/internal/ingress/annotations/parser/main_test.go @@ -21,7 +21,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/internal/ingress/annotations/portinredirect/main.go b/internal/ingress/annotations/portinredirect/main.go index bb5925c31..25d665558 100644 --- a/internal/ingress/annotations/portinredirect/main.go +++ b/internal/ingress/annotations/portinredirect/main.go @@ -17,7 +17,7 @@ limitations under the License. package portinredirect import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/portinredirect/main_test.go b/internal/ingress/annotations/portinredirect/main_test.go index 7087ddcd3..71afd4cdf 100644 --- a/internal/ingress/annotations/portinredirect/main_test.go +++ b/internal/ingress/annotations/portinredirect/main_test.go @@ -21,9 +21,8 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/defaults" @@ -32,8 +31,12 @@ import ( func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -42,9 +45,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/proxy/main.go b/internal/ingress/annotations/proxy/main.go index f5c225258..3a89b8855 100644 --- a/internal/ingress/annotations/proxy/main.go +++ b/internal/ingress/annotations/proxy/main.go @@ -17,7 +17,7 @@ limitations under the License. package proxy import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/proxy/main_test.go b/internal/ingress/annotations/proxy/main_test.go index 418db922e..e377ccb19 100644 --- a/internal/ingress/annotations/proxy/main_test.go +++ b/internal/ingress/annotations/proxy/main_test.go @@ -20,9 +20,8 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/defaults" @@ -31,8 +30,12 @@ import ( func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -41,9 +44,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/proxyssl/main.go b/internal/ingress/annotations/proxyssl/main.go index da3bbecc0..2452d90da 100644 --- a/internal/ingress/annotations/proxyssl/main.go +++ b/internal/ingress/annotations/proxyssl/main.go @@ -22,7 +22,7 @@ import ( "strings" "github.com/pkg/errors" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" ing_errors "k8s.io/ingress-nginx/internal/ingress/errors" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/proxyssl/main_test.go b/internal/ingress/annotations/proxyssl/main_test.go index a52fcb98a..29949796c 100644 --- a/internal/ingress/annotations/proxyssl/main_test.go +++ b/internal/ingress/annotations/proxyssl/main_test.go @@ -20,9 +20,8 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/errors" "k8s.io/ingress-nginx/internal/ingress/resolver" @@ -30,8 +29,12 @@ import ( func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -40,9 +43,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/ratelimit/main.go b/internal/ingress/annotations/ratelimit/main.go index 7b7d6f4db..4011c2542 100644 --- a/internal/ingress/annotations/ratelimit/main.go +++ b/internal/ingress/annotations/ratelimit/main.go @@ -21,7 +21,7 @@ import ( "fmt" "strings" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/ratelimit/main_test.go b/internal/ingress/annotations/ratelimit/main_test.go index 7ffbac3ff..9f101cc3b 100644 --- a/internal/ingress/annotations/ratelimit/main_test.go +++ b/internal/ingress/annotations/ratelimit/main_test.go @@ -20,10 +20,9 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/defaults" "k8s.io/ingress-nginx/internal/ingress/resolver" @@ -31,8 +30,12 @@ import ( func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -41,9 +44,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/redirect/redirect.go b/internal/ingress/annotations/redirect/redirect.go index 02ee1d522..11b08a4a2 100644 --- a/internal/ingress/annotations/redirect/redirect.go +++ b/internal/ingress/annotations/redirect/redirect.go @@ -21,7 +21,7 @@ import ( "net/url" "strings" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/errors" diff --git a/internal/ingress/annotations/redirect/redirect_test.go b/internal/ingress/annotations/redirect/redirect_test.go index b9bda6688..b5a87a5d3 100644 --- a/internal/ingress/annotations/redirect/redirect_test.go +++ b/internal/ingress/annotations/redirect/redirect_test.go @@ -23,7 +23,7 @@ import ( "strconv" "testing" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/errors" diff --git a/internal/ingress/annotations/rewrite/main.go b/internal/ingress/annotations/rewrite/main.go index 902f00f4c..f92d508dc 100644 --- a/internal/ingress/annotations/rewrite/main.go +++ b/internal/ingress/annotations/rewrite/main.go @@ -19,7 +19,7 @@ package rewrite import ( "net/url" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/klog/v2" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" diff --git a/internal/ingress/annotations/rewrite/main_test.go b/internal/ingress/annotations/rewrite/main_test.go index beece494a..c2cb42c78 100644 --- a/internal/ingress/annotations/rewrite/main_test.go +++ b/internal/ingress/annotations/rewrite/main_test.go @@ -20,9 +20,8 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/defaults" @@ -35,8 +34,12 @@ const ( func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -46,9 +49,13 @@ func buildIngress() *networking.Ingress { Annotations: map[string]string{}, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/satisfy/main.go b/internal/ingress/annotations/satisfy/main.go index a064bdf96..0d4fd4ff6 100644 --- a/internal/ingress/annotations/satisfy/main.go +++ b/internal/ingress/annotations/satisfy/main.go @@ -17,7 +17,7 @@ limitations under the License. package satisfy import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/satisfy/main_test.go b/internal/ingress/annotations/satisfy/main_test.go index a3475316a..b45205d9f 100644 --- a/internal/ingress/annotations/satisfy/main_test.go +++ b/internal/ingress/annotations/satisfy/main_test.go @@ -20,18 +20,21 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -40,9 +43,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/secureupstream/main.go b/internal/ingress/annotations/secureupstream/main.go index 631804464..ebaea2058 100644 --- a/internal/ingress/annotations/secureupstream/main.go +++ b/internal/ingress/annotations/secureupstream/main.go @@ -17,7 +17,7 @@ limitations under the License. package secureupstream import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/klog/v2" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" diff --git a/internal/ingress/annotations/secureupstream/main_test.go b/internal/ingress/annotations/secureupstream/main_test.go index 508d54a84..7546cb5cf 100644 --- a/internal/ingress/annotations/secureupstream/main_test.go +++ b/internal/ingress/annotations/secureupstream/main_test.go @@ -21,18 +21,21 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -41,9 +44,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/serversnippet/main.go b/internal/ingress/annotations/serversnippet/main.go index 33a672650..70f0af8e5 100644 --- a/internal/ingress/annotations/serversnippet/main.go +++ b/internal/ingress/annotations/serversnippet/main.go @@ -17,7 +17,7 @@ limitations under the License. package serversnippet import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/serversnippet/main_test.go b/internal/ingress/annotations/serversnippet/main_test.go index 066334f69..c9e0979ad 100644 --- a/internal/ingress/annotations/serversnippet/main_test.go +++ b/internal/ingress/annotations/serversnippet/main_test.go @@ -20,7 +20,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/serviceupstream/main.go b/internal/ingress/annotations/serviceupstream/main.go index ff90f8160..4c44356d6 100644 --- a/internal/ingress/annotations/serviceupstream/main.go +++ b/internal/ingress/annotations/serviceupstream/main.go @@ -17,7 +17,7 @@ limitations under the License. package serviceupstream import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/serviceupstream/main_test.go b/internal/ingress/annotations/serviceupstream/main_test.go index c7f44598e..3fbdb5785 100644 --- a/internal/ingress/annotations/serviceupstream/main_test.go +++ b/internal/ingress/annotations/serviceupstream/main_test.go @@ -20,17 +20,20 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -39,9 +42,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { diff --git a/internal/ingress/annotations/sessionaffinity/main.go b/internal/ingress/annotations/sessionaffinity/main.go index c5b340ec7..9449ceb93 100644 --- a/internal/ingress/annotations/sessionaffinity/main.go +++ b/internal/ingress/annotations/sessionaffinity/main.go @@ -19,7 +19,7 @@ package sessionaffinity import ( "regexp" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/klog/v2" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" diff --git a/internal/ingress/annotations/sessionaffinity/main_test.go b/internal/ingress/annotations/sessionaffinity/main_test.go index 51d92ffb0..98f0a1eb6 100644 --- a/internal/ingress/annotations/sessionaffinity/main_test.go +++ b/internal/ingress/annotations/sessionaffinity/main_test.go @@ -20,17 +20,20 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) func buildIngress() *networking.Ingress { defaultBackend := networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, } return &networking.Ingress{ @@ -39,9 +42,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, Rules: []networking.IngressRule{ { @@ -64,7 +71,6 @@ func buildIngress() *networking.Ingress { func TestIngressAffinityCookieConfig(t *testing.T) { ing := buildIngress() - data := map[string]string{} data[parser.GetAnnotationWithPrefix(annotationAffinityType)] = "cookie" data[parser.GetAnnotationWithPrefix(annotationAffinityMode)] = "balanced" diff --git a/internal/ingress/annotations/snippet/main.go b/internal/ingress/annotations/snippet/main.go index 9a3878603..93ec70cf9 100644 --- a/internal/ingress/annotations/snippet/main.go +++ b/internal/ingress/annotations/snippet/main.go @@ -17,7 +17,7 @@ limitations under the License. package snippet import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/snippet/main_test.go b/internal/ingress/annotations/snippet/main_test.go index 0abeaed8a..0defc3c1f 100644 --- a/internal/ingress/annotations/snippet/main_test.go +++ b/internal/ingress/annotations/snippet/main_test.go @@ -20,7 +20,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/sslcipher/main.go b/internal/ingress/annotations/sslcipher/main.go index d100a0da4..e4e5baad2 100644 --- a/internal/ingress/annotations/sslcipher/main.go +++ b/internal/ingress/annotations/sslcipher/main.go @@ -17,7 +17,7 @@ limitations under the License. package sslcipher import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/sslcipher/main_test.go b/internal/ingress/annotations/sslcipher/main_test.go index 8110697dc..6eb9ec0c2 100644 --- a/internal/ingress/annotations/sslcipher/main_test.go +++ b/internal/ingress/annotations/sslcipher/main_test.go @@ -21,7 +21,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/sslpassthrough/main.go b/internal/ingress/annotations/sslpassthrough/main.go index 20ff1a010..d1def7172 100644 --- a/internal/ingress/annotations/sslpassthrough/main.go +++ b/internal/ingress/annotations/sslpassthrough/main.go @@ -17,7 +17,7 @@ limitations under the License. package sslpassthrough import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" ing_errors "k8s.io/ingress-nginx/internal/ingress/errors" diff --git a/internal/ingress/annotations/sslpassthrough/main_test.go b/internal/ingress/annotations/sslpassthrough/main_test.go index d5e54b2e2..5cf2f979a 100644 --- a/internal/ingress/annotations/sslpassthrough/main_test.go +++ b/internal/ingress/annotations/sslpassthrough/main_test.go @@ -20,12 +20,10 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" - - "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *networking.Ingress { @@ -35,9 +33,13 @@ func buildIngress() *networking.Ingress { Namespace: api.NamespaceDefault, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "default-backend", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, }, } diff --git a/internal/ingress/annotations/upstreamhashby/main.go b/internal/ingress/annotations/upstreamhashby/main.go index bb202f1b0..e6bbca6c3 100644 --- a/internal/ingress/annotations/upstreamhashby/main.go +++ b/internal/ingress/annotations/upstreamhashby/main.go @@ -17,7 +17,7 @@ limitations under the License. package upstreamhashby import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/upstreamhashby/main_test.go b/internal/ingress/annotations/upstreamhashby/main_test.go index 5a71be56f..d2c2644ca 100644 --- a/internal/ingress/annotations/upstreamhashby/main_test.go +++ b/internal/ingress/annotations/upstreamhashby/main_test.go @@ -20,7 +20,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/upstreamvhost/main.go b/internal/ingress/annotations/upstreamvhost/main.go index bf761a70f..2eed5607e 100644 --- a/internal/ingress/annotations/upstreamvhost/main.go +++ b/internal/ingress/annotations/upstreamvhost/main.go @@ -17,7 +17,7 @@ limitations under the License. package upstreamvhost import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/upstreamvhost/main_test.go b/internal/ingress/annotations/upstreamvhost/main_test.go index 1506c4f7f..130d745ee 100644 --- a/internal/ingress/annotations/upstreamvhost/main_test.go +++ b/internal/ingress/annotations/upstreamvhost/main_test.go @@ -20,7 +20,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/xforwardedprefix/main.go b/internal/ingress/annotations/xforwardedprefix/main.go index 2071b6411..60eed8773 100644 --- a/internal/ingress/annotations/xforwardedprefix/main.go +++ b/internal/ingress/annotations/xforwardedprefix/main.go @@ -17,7 +17,7 @@ limitations under the License. package xforwardedprefix import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/annotations/xforwardedprefix/main_test.go b/internal/ingress/annotations/xforwardedprefix/main_test.go index c94df3ab2..a78c63d04 100644 --- a/internal/ingress/annotations/xforwardedprefix/main_test.go +++ b/internal/ingress/annotations/xforwardedprefix/main_test.go @@ -20,7 +20,7 @@ import ( "testing" api "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go index f8e79e66e..b96e26772 100644 --- a/internal/ingress/controller/config/config.go +++ b/internal/ingress/controller/config/config.go @@ -925,7 +925,7 @@ type TemplateConfig struct { ListenPorts *ListenPorts PublishService *apiv1.Service EnableMetrics bool - MaxmindEditionFiles []string + MaxmindEditionFiles *[]string MonitorMaxBatchSize int PID string diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index dd04b0f09..27cd2ffe4 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -25,7 +25,7 @@ import ( "github.com/mitchellh/hashstructure" apiv1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" @@ -33,11 +33,11 @@ import ( clientset "k8s.io/client-go/kubernetes" "k8s.io/ingress-nginx/internal/ingress" "k8s.io/ingress-nginx/internal/ingress/annotations" - "k8s.io/ingress-nginx/internal/ingress/annotations/class" "k8s.io/ingress-nginx/internal/ingress/annotations/log" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/annotations/proxy" ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config" + "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/k8s" @@ -85,6 +85,8 @@ type Configuration struct { ListenPorts *ngx_config.ListenPorts + DisableServiceExternalName bool + EnableSSLPassthrough bool EnableProfiling bool @@ -98,12 +100,14 @@ type Configuration struct { DisableCatchAll bool + IngressClassConfiguration *ingressclass.IngressClassConfiguration + ValidationWebhook string ValidationWebhookCertPath string ValidationWebhookKeyPath string GlobalExternalAuth *ngx_config.GlobalExternalAuth - MaxmindEditionFiles []string + MaxmindEditionFiles *[]string MonitorMaxBatchSize int @@ -219,17 +223,12 @@ func (n *NGINXController) CheckIngress(ing *networking.Ingress) error { return nil } - if !class.IsValid(ing) { - klog.Warningf("ignoring ingress %v in %v based on annotation %v", ing.Name, ing.ObjectMeta.Namespace, class.IngressKey) - return nil - } - if n.cfg.Namespace != "" && ing.ObjectMeta.Namespace != n.cfg.Namespace { klog.Warningf("ignoring ingress %v in namespace %v different from the namespace watched %s", ing.Name, ing.ObjectMeta.Namespace, n.cfg.Namespace) return nil } - if n.cfg.DisableCatchAll && ing.Spec.Backend != nil { + if n.cfg.DisableCatchAll && ing.Spec.DefaultBackend != nil { return fmt.Errorf("This deployment is trying to create a catch-all ingress while DisableCatchAll flag is set to true. Remove '.spec.backend' or set DisableCatchAll flag to false.") } @@ -571,7 +570,13 @@ func (n *NGINXController) getBackendServers(ingresses []*ingress.Ingress) ([]*in } for _, path := range rule.HTTP.Paths { - upsName := upstreamName(ing.Namespace, path.Backend.ServiceName, path.Backend.ServicePort) + if path.Backend.Service == nil { + // skip non-service backends + klog.V(3).Infof("Ingress %q and path %q does not contain a service backend, using default backend", ingKey, path.Path) + continue + } + + upsName := upstreamName(ing.Namespace, path.Backend.Service) ups := upstreams[upsName] @@ -786,11 +791,12 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B upstreams[defUpstreamName] = du for _, ing := range data { + ingKey := k8s.MetaNamespaceKey(ing) anns := ing.ParsedAnnotations var defBackend string - if ing.Spec.Backend != nil { - defBackend = upstreamName(ing.Namespace, ing.Spec.Backend.ServiceName, ing.Spec.Backend.ServicePort) + if ing.Spec.DefaultBackend != nil && ing.Spec.DefaultBackend.Service != nil { + defBackend = upstreamName(ing.Namespace, ing.Spec.DefaultBackend.Service) klog.V(3).Infof("Creating upstream %q", defBackend) upstreams[defBackend] = newUpstream(defBackend) @@ -804,11 +810,11 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B upstreams[defBackend].LoadBalancing = n.store.GetBackendConfiguration().LoadBalancing } - svcKey := fmt.Sprintf("%v/%v", ing.Namespace, ing.Spec.Backend.ServiceName) + svcKey := fmt.Sprintf("%v/%v", ing.Namespace, ing.Spec.DefaultBackend.Service.Name) // add the service ClusterIP as a single Endpoint instead of individual Endpoints if anns.ServiceUpstream { - endpoint, err := n.getServiceClusterEndpoint(svcKey, ing.Spec.Backend) + endpoint, err := n.getServiceClusterEndpoint(svcKey, ing.Spec.DefaultBackend) if err != nil { klog.Errorf("Failed to determine a suitable ClusterIP Endpoint for Service %q: %v", svcKey, err) } else { @@ -829,7 +835,8 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B } if len(upstreams[defBackend].Endpoints) == 0 { - endps, err := n.serviceEndpoints(svcKey, ing.Spec.Backend.ServicePort.String()) + _, port := upstreamServiceNameAndPort(ing.Spec.DefaultBackend.Service) + endps, err := n.serviceEndpoints(svcKey, port.String()) upstreams[defBackend].Endpoints = append(upstreams[defBackend].Endpoints, endps...) if err != nil { klog.Warningf("Error creating upstream %q: %v", defBackend, err) @@ -849,15 +856,21 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B } for _, path := range rule.HTTP.Paths { - name := upstreamName(ing.Namespace, path.Backend.ServiceName, path.Backend.ServicePort) + if path.Backend.Service == nil { + // skip non-service backends + klog.V(3).Infof("Ingress %q and path %q does not contain a service backend, using default backend", ingKey, path.Path) + continue + } + name := upstreamName(ing.Namespace, path.Backend.Service) + svcName, svcPort := upstreamServiceNameAndPort(path.Backend.Service) if _, ok := upstreams[name]; ok { continue } klog.V(3).Infof("Creating upstream %q", name) upstreams[name] = newUpstream(name) - upstreams[name].Port = path.Backend.ServicePort + upstreams[name].Port = svcPort upstreams[name].UpstreamHashBy.UpstreamHashBy = anns.UpstreamHashBy.UpstreamHashBy upstreams[name].UpstreamHashBy.UpstreamHashBySubset = anns.UpstreamHashBy.UpstreamHashBySubset @@ -868,7 +881,7 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B upstreams[name].LoadBalancing = n.store.GetBackendConfiguration().LoadBalancing } - svcKey := fmt.Sprintf("%v/%v", ing.Namespace, path.Backend.ServiceName) + svcKey := fmt.Sprintf("%v/%v", ing.Namespace, svcName) // add the service ClusterIP as a single Endpoint instead of individual Endpoints if anns.ServiceUpstream { @@ -893,7 +906,8 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B } if len(upstreams[name].Endpoints) == 0 { - endp, err := n.serviceEndpoints(svcKey, path.Backend.ServicePort.String()) + _, port := upstreamServiceNameAndPort(path.Backend.Service) + endp, err := n.serviceEndpoints(svcKey, port.String()) if err != nil { klog.Warningf("Error obtaining Endpoints for Service %q: %v", svcKey, err) continue @@ -931,20 +945,23 @@ func (n *NGINXController) getServiceClusterEndpoint(svcKey string, backend *netw // if the Service port is referenced by name in the Ingress, lookup the // actual port in the service spec - if backend.ServicePort.Type == intstr.String { - var port int32 = -1 - for _, svcPort := range svc.Spec.Ports { - if svcPort.Name == backend.ServicePort.String() { - port = svcPort.Port - break + if backend.Service != nil { + _, svcportintorstr := upstreamServiceNameAndPort(backend.Service) + if svcportintorstr.Type == intstr.String { + var port int32 = -1 + for _, svcPort := range svc.Spec.Ports { + if svcPort.Name == svcportintorstr.String() { + port = svcPort.Port + break + } } + if port == -1 { + return endpoint, fmt.Errorf("service %q does not have a port named %q", svc.Name, svcportintorstr.String()) + } + endpoint.Port = fmt.Sprintf("%d", port) + } else { + endpoint.Port = svcportintorstr.String() } - if port == -1 { - return endpoint, fmt.Errorf("service %q does not have a port named %q", svc.Name, backend.ServicePort) - } - endpoint.Port = fmt.Sprintf("%d", port) - } else { - endpoint.Port = backend.ServicePort.String() } return endpoint, err @@ -963,6 +980,10 @@ func (n *NGINXController) serviceEndpoints(svcKey, backendPort string) ([]ingres // Ingress with an ExternalName Service and no port defined for that Service if svc.Spec.Type == apiv1.ServiceTypeExternalName { + if n.cfg.DisableServiceExternalName { + klog.Warningf("Service %q of type ExternalName not allowed due to Ingress configuration.", svcKey) + return upstreams, nil + } servicePort := externalNamePorts(backendPort, svc) endps := getEndpoints(svc, servicePort, apiv1.ProtocolTCP, n.store.GetServiceEndpoints) if len(endps) == 0 { @@ -1071,8 +1092,8 @@ func (n *NGINXController) createServers(data []*ingress.Ingress, continue } - if ing.Spec.Backend != nil { - defUpstream := upstreamName(ing.Namespace, ing.Spec.Backend.ServiceName, ing.Spec.Backend.ServicePort) + if ing.Spec.DefaultBackend != nil && ing.Spec.DefaultBackend.Service != nil { + defUpstream := upstreamName(ing.Namespace, ing.Spec.DefaultBackend.Service) if backendUpstream, ok := upstreams[defUpstream]; ok { // use backend specified in Ingress as the default backend for all its rules @@ -1337,8 +1358,8 @@ func mergeAlternativeBackends(ing *ingress.Ingress, upstreams map[string]*ingres servers map[string]*ingress.Server) { // merge catch-all alternative backends - if ing.Spec.Backend != nil { - upsName := upstreamName(ing.Namespace, ing.Spec.Backend.ServiceName, ing.Spec.Backend.ServicePort) + if ing.Spec.DefaultBackend != nil { + upsName := upstreamName(ing.Namespace, ing.Spec.DefaultBackend.Service) altUps := upstreams[upsName] @@ -1380,7 +1401,13 @@ func mergeAlternativeBackends(ing *ingress.Ingress, upstreams map[string]*ingres } for _, path := range rule.HTTP.Paths { - upsName := upstreamName(ing.Namespace, path.Backend.ServiceName, path.Backend.ServicePort) + if path.Backend.Service == nil { + // skip non-service backends + klog.V(3).Infof("Ingress %q and path %q does not contain a service backend, using default backend", k8s.MetaNamespaceKey(ing), path.Path) + continue + } + + upsName := upstreamName(ing.Namespace, path.Backend.Service) altUps := upstreams[upsName] @@ -1596,6 +1623,12 @@ func checkOverlap(ing *networking.Ingress, ingresses []*ingress.Ingress, servers } for _, path := range rule.HTTP.Paths { + if path.Backend.Service == nil { + // skip non-service backends + klog.V(3).Infof("Ingress %q and path %q does not contain a service backend, using default backend", k8s.MetaNamespaceKey(ing), path.Path) + continue + } + if path.Path == "" { path.Path = rootLocation } diff --git a/internal/ingress/controller/controller_test.go b/internal/ingress/controller/controller_test.go index 22d108ca4..d33ac7d30 100644 --- a/internal/ingress/controller/controller_test.go +++ b/internal/ingress/controller/controller_test.go @@ -33,9 +33,8 @@ import ( "github.com/eapache/channels" corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/kubernetes/fake" "k8s.io/ingress-nginx/internal/file" @@ -46,6 +45,7 @@ import ( "k8s.io/ingress-nginx/internal/ingress/annotations/proxyssl" "k8s.io/ingress-nginx/internal/ingress/controller/config" ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config" + "k8s.io/ingress-nginx/internal/ingress/controller/ingressclass" "k8s.io/ingress-nginx/internal/ingress/controller/store" "k8s.io/ingress-nginx/internal/ingress/defaults" "k8s.io/ingress-nginx/internal/ingress/metric" @@ -189,18 +189,6 @@ func TestCheckIngress(t *testing.T) { }, }, } - - t.Run("When the ingress class differs from nginx", func(t *testing.T) { - ing.ObjectMeta.Annotations["kubernetes.io/ingress.class"] = "different" - nginx.command = testNginxTestCommand{ - t: t, - err: fmt.Errorf("test error"), - } - if nginx.CheckIngress(ing) != nil { - t.Errorf("with a different ingress class, no error should be returned") - } - }) - t.Run("when the class is the nginx one", func(t *testing.T) { ing.ObjectMeta.Annotations["kubernetes.io/ingress.class"] = "nginx" nginx.command = testNginxTestCommand{ @@ -257,7 +245,7 @@ func TestCheckIngress(t *testing.T) { }) t.Run("When a new catch-all ingress is being created despite catch-alls being disabled ", func(t *testing.T) { - backendBefore := ing.Spec.Backend + backendBefore := ing.Spec.DefaultBackend disableCatchAllBefore := nginx.cfg.DisableCatchAll nginx.command = testNginxTestCommand{ @@ -266,10 +254,12 @@ func TestCheckIngress(t *testing.T) { } nginx.cfg.DisableCatchAll = true - ing.Spec.Backend = &networking.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.IntOrString{ - IntVal: 80, + ing.Spec.DefaultBackend = &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "http-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, } @@ -278,7 +268,7 @@ func TestCheckIngress(t *testing.T) { } // reset backend and catch-all flag - ing.Spec.Backend = backendBefore + ing.Spec.DefaultBackend = backendBefore nginx.cfg.DisableCatchAll = disableCatchAllBefore }) @@ -331,10 +321,11 @@ func TestMergeAlternativeBackends(t *testing.T) { Path: "/", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-canary", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -415,10 +406,11 @@ func TestMergeAlternativeBackends(t *testing.T) { Path: "/", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "foo-http-svc-canary", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "foo-http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -435,10 +427,11 @@ func TestMergeAlternativeBackends(t *testing.T) { Path: "/", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-canary", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -553,10 +546,11 @@ func TestMergeAlternativeBackends(t *testing.T) { Path: "/", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-canary", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -588,10 +582,12 @@ func TestMergeAlternativeBackends(t *testing.T) { Namespace: "example", }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "http-svc-canary", - ServicePort: intstr.IntOrString{ - IntVal: 80, + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -656,10 +652,12 @@ func TestMergeAlternativeBackends(t *testing.T) { Namespace: "example", }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "http-svc-canary", - ServicePort: intstr.IntOrString{ - IntVal: 80, + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -720,9 +718,11 @@ func TestMergeAlternativeBackends(t *testing.T) { Path: "/", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-canary", - ServicePort: intstr.IntOrString{ - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1001,10 +1001,12 @@ func TestGetBackendServers(t *testing.T) { Namespace: "example", }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "http-svc-canary", - ServicePort: intstr.IntOrString{ - IntVal: 80, + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1044,10 +1046,12 @@ func TestGetBackendServers(t *testing.T) { Namespace: "example", }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "http-svc-canary", - ServicePort: intstr.IntOrString{ - IntVal: 80, + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1064,10 +1068,12 @@ func TestGetBackendServers(t *testing.T) { Namespace: "example", }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.IntOrString{ - IntVal: 80, + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "http-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1117,10 +1123,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-canary", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1177,10 +1184,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1214,10 +1222,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-canary", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-canary", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1283,10 +1292,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/a", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-1", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-1", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1320,10 +1330,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/a", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-2", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-2", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1357,10 +1368,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/b", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-2", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-2", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1394,10 +1406,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/b", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-1", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-1", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1431,10 +1444,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/c", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-1", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-1", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1468,10 +1482,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/c", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc-2", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "http-svc-2", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1553,10 +1568,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/path1", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "path1-svc", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "path1-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1593,10 +1609,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/path2", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "path2-svc", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "path2-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1658,10 +1675,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/path1", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "path1-svc", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "path1-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1698,10 +1716,11 @@ func TestGetBackendServers(t *testing.T) { Path: "/path2", PathType: &pathTypePrefix, Backend: networking.IngressBackend{ - ServiceName: "path2-svc", - ServicePort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, + Service: &networking.IngressServiceBackend{ + Name: "path2-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, }, }, }, @@ -1754,6 +1773,67 @@ func TestGetBackendServers(t *testing.T) { } }, }, + { + Ingresses: []*ingress.Ingress{ + { + Ingress: networking.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "proxy-ssl-1", + Namespace: "proxyssl", + }, + Spec: networking.IngressSpec{ + Rules: []networking.IngressRule{ + { + Host: "example.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/path1", + PathType: &pathTypePrefix, + Backend: networking.IngressBackend{}, + }, + }, + }, + }, + }, + }, + }, + }, + ParsedAnnotations: &annotations.Ingress{ + ProxySSL: proxyssl.Config{ + AuthSSLCert: resolver.AuthSSLCert{ + CAFileName: "cafile1.crt", + Secret: "secret1", + }, + }, + }, + }, + }, + Validate: func(ingresses []*ingress.Ingress, upstreams []*ingress.Backend, servers []*ingress.Server) { + if len(servers) != 2 { + t.Errorf("servers count should be 1, got %d", len(servers)) + return + } + + s := servers[1] + + if s.Locations[0].Backend != "upstream-default-backend" { + t.Errorf("backend should be upstream-default-backend, got '%s'", s.Locations[0].Backend) + } + }, + SetConfigMap: func(ns string) *v1.ConfigMap { + return &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config", + SelfLink: fmt.Sprintf("/api/v1/namespaces/%s/configmaps/config", ns), + }, + Data: map[string]string{ + "proxy-ssl-location-only": "true", + }, + } + }, + }, } for _, testCase := range testCases { @@ -1808,7 +1888,12 @@ func newNGINXController(t *testing.T) *NGINXController { 10*time.Minute, clientSet, channels.NewRingChannel(10), - false) + false, + &ingressclass.IngressClassConfiguration{ + Controller: "k8s.io/ingress-nginx", + AnnotationValue: "nginx", + }, + ) sslCert := ssl.GetFakeSSLCert() config := &Configuration{ @@ -1866,7 +1951,11 @@ func newDynamicNginxController(t *testing.T, setConfigMap func(string) *v1.Confi 10*time.Minute, clientSet, channels.NewRingChannel(10), - false) + false, + &ingressclass.IngressClassConfiguration{ + Controller: "k8s.io/ingress-nginx", + AnnotationValue: "nginx", + }) sslCert := ssl.GetFakeSSLCert() config := &Configuration{ diff --git a/internal/ingress/controller/ingressclass/ingressclass.go b/internal/ingress/controller/ingressclass/ingressclass.go new file mode 100644 index 000000000..025a4e2a5 --- /dev/null +++ b/internal/ingress/controller/ingressclass/ingressclass.go @@ -0,0 +1,45 @@ +/* +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. +*/ + +package ingressclass + +const ( + // IngressKey picks a specific "class" for the Ingress. + // The controller only processes Ingresses with this annotation either + // unset, or set to either the configured value or the empty string. + IngressKey = "kubernetes.io/ingress.class" + + // DefaultControllerName defines the default controller name for Ingress NGINX + DefaultControllerName = "k8s.io/ingress-nginx" + + // DefaultAnnotationValue defines the default annotation value for the ingress-nginx controller + DefaultAnnotationValue = "nginx" +) + +// IngressClassConfiguration defines the various aspects of IngressClass parsing +// and how the controller should behave in each case +type IngressClassConfiguration struct { + // Controller defines the controller value this daemon watch to. + // Defaults to "k8s.io/ingress-nginx" defined in flags + Controller string + // AnnotationValue defines the annotation value this Controller watch to, in case of the + // ingressSpecName is not found but the annotation is. + // The Annotation is deprecated and should not be used in future releases + AnnotationValue string + // WatchWithoutClass defines if Controller should watch to Ingress Objects that does + // not contain an IngressClass configuration + WatchWithoutClass bool +} diff --git a/internal/ingress/controller/location.go b/internal/ingress/controller/location.go index e6b6c44bd..d40e88960 100644 --- a/internal/ingress/controller/location.go +++ b/internal/ingress/controller/location.go @@ -20,10 +20,8 @@ import ( "fmt" "strings" - "github.com/mitchellh/copystructure" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/internal/ingress" - "k8s.io/klog/v2" ) var ( @@ -73,18 +71,14 @@ func updateServerLocations(locations []*ingress.Location) []*ingress.Location { continue } - // copy location before any change - el, err := copystructure.Copy(location) - if err != nil { - klog.ErrorS(err, "copying location") - } + var el ingress.Location = *location // normalize path. Must end in / location.Path = normalizePrefixPath(location.Path) newLocations = append(newLocations, location) // add exact location - exactLocation := el.(*ingress.Location) + exactLocation := &el exactLocation.PathType = &pathTypeExact newLocations = append(newLocations, exactLocation) diff --git a/internal/ingress/controller/nginx.go b/internal/ingress/controller/nginx.go index 664d36b75..20f518f8e 100644 --- a/internal/ingress/controller/nginx.go +++ b/internal/ingress/controller/nginx.go @@ -50,7 +50,6 @@ import ( adm_controller "k8s.io/ingress-nginx/internal/admission/controller" "k8s.io/ingress-nginx/internal/file" "k8s.io/ingress-nginx/internal/ingress" - "k8s.io/ingress-nginx/internal/ingress/annotations/class" ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config" "k8s.io/ingress-nginx/internal/ingress/controller/process" "k8s.io/ingress-nginx/internal/ingress/controller/store" @@ -131,7 +130,8 @@ func NewNGINXController(config *Configuration, mc metric.Collector) *NGINXContro config.ResyncPeriod, config.Client, n.updateCh, - config.DisableCatchAll) + config.DisableCatchAll, + config.IngressClassConfiguration) n.syncQueue = task.NewTaskQueue(n.syncIngress) @@ -257,10 +257,10 @@ func (n *NGINXController) Start() { // we need to use the defined ingress class to allow multiple leaders // in order to update information about ingress status - electionID := fmt.Sprintf("%v-%v", n.cfg.ElectionID, class.DefaultClass) - if class.IngressClass != "" { - electionID = fmt.Sprintf("%v-%v", n.cfg.ElectionID, class.IngressClass) - } + // TODO: For now, as the the IngressClass logics has changed, is up to the + // cluster admin to create different Leader Election IDs. + // Should revisit this in a future + electionID := n.cfg.ElectionID setupLeaderElection(&leaderElectionConfig{ Client: n.cfg.Client, @@ -512,12 +512,7 @@ func (n NGINXController) generateTemplate(cfg ngx_config.Configuration, ingressC if cfg.MaxWorkerOpenFiles == 0 { // the limit of open files is per worker process // and we leave some room to avoid consuming all the FDs available - wp, err := strconv.Atoi(cfg.WorkerProcesses) - klog.V(3).InfoS("Worker processes", "count", wp) - if err != nil { - wp = 1 - } - maxOpenFiles := (rlimitMaxNumFiles() / wp) - 1024 + maxOpenFiles := rlimitMaxNumFiles() - 1024 klog.V(3).InfoS("Maximum number of open file descriptors", "value", maxOpenFiles) if maxOpenFiles < 1024 { // this means the value of RLIMIT_NOFILE is too low. diff --git a/internal/ingress/controller/store/backend_ssl.go b/internal/ingress/controller/store/backend_ssl.go index fe9138c6f..377f62015 100644 --- a/internal/ingress/controller/store/backend_ssl.go +++ b/internal/ingress/controller/store/backend_ssl.go @@ -24,7 +24,7 @@ import ( "github.com/pkg/errors" apiv1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/file" diff --git a/internal/ingress/controller/store/ingress.go b/internal/ingress/controller/store/ingress.go index dafc48924..1d8ccb342 100644 --- a/internal/ingress/controller/store/ingress.go +++ b/internal/ingress/controller/store/ingress.go @@ -17,7 +17,7 @@ limitations under the License. package store import ( - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/client-go/tools/cache" "k8s.io/ingress-nginx/internal/ingress" ) diff --git a/internal/ingress/controller/store/ingressclass.go b/internal/ingress/controller/store/ingressclass.go new file mode 100644 index 000000000..da613d035 --- /dev/null +++ b/internal/ingress/controller/store/ingressclass.go @@ -0,0 +1,39 @@ +/* +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. +*/ + +package store + +import ( + networking "k8s.io/api/networking/v1" + "k8s.io/client-go/tools/cache" +) + +// IngressClassLister makes a Store that lists IngressClass. +type IngressClassLister struct { + cache.Store +} + +// ByKey returns the Ingress matching key in the local Ingress Store. +func (il IngressClassLister) ByKey(key string) (*networking.IngressClass, error) { + i, exists, err := il.GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, NotExistsError(key) + } + return i.(*networking.IngressClass), nil +} diff --git a/internal/ingress/controller/store/store.go b/internal/ingress/controller/store/store.go index 0088c3b01..39ba29abd 100644 --- a/internal/ingress/controller/store/store.go +++ b/internal/ingress/controller/store/store.go @@ -28,7 +28,7 @@ import ( "github.com/eapache/channels" corev1 "k8s.io/api/core/v1" - networkingv1beta1 "k8s.io/api/networking/v1beta1" + networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" k8sruntime "k8s.io/apimachinery/pkg/runtime" @@ -41,14 +41,13 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/record" "k8s.io/klog/v2" - "k8s.io/utils/pointer" "k8s.io/ingress-nginx/internal/file" "k8s.io/ingress-nginx/internal/ingress" "k8s.io/ingress-nginx/internal/ingress/annotations" - "k8s.io/ingress-nginx/internal/ingress/annotations/class" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" ngx_config "k8s.io/ingress-nginx/internal/ingress/controller/config" + "k8s.io/ingress-nginx/internal/ingress/controller/ingressclass" ngx_template "k8s.io/ingress-nginx/internal/ingress/controller/template" "k8s.io/ingress-nginx/internal/ingress/defaults" "k8s.io/ingress-nginx/internal/ingress/errors" @@ -121,16 +120,18 @@ type Event struct { // Informer defines the required SharedIndexInformers that interact with the API server. type Informer struct { - Ingress cache.SharedIndexInformer - Endpoint cache.SharedIndexInformer - Service cache.SharedIndexInformer - Secret cache.SharedIndexInformer - ConfigMap cache.SharedIndexInformer + Ingress cache.SharedIndexInformer + IngressClass cache.SharedIndexInformer + Endpoint cache.SharedIndexInformer + Service cache.SharedIndexInformer + Secret cache.SharedIndexInformer + ConfigMap cache.SharedIndexInformer } // Lister contains object listers (stores). type Lister struct { Ingress IngressLister + IngressClass IngressClassLister Service ServiceLister Endpoint EndpointLister Secret SecretLister @@ -150,6 +151,7 @@ func (e NotExistsError) Error() string { func (i *Informer) Run(stopCh chan struct{}) { go i.Secret.Run(stopCh) go i.Endpoint.Run(stopCh) + go i.IngressClass.Run(stopCh) go i.Service.Run(stopCh) go i.ConfigMap.Run(stopCh) @@ -157,6 +159,7 @@ func (i *Informer) Run(stopCh chan struct{}) { // from the queue if !cache.WaitForCacheSync(stopCh, i.Endpoint.HasSynced, + i.IngressClass.HasSynced, i.Service.HasSynced, i.Secret.HasSynced, i.ConfigMap.HasSynced, @@ -221,7 +224,8 @@ func New( resyncPeriod time.Duration, client clientset.Interface, updateCh *channels.RingChannel, - disableCatchAll bool) Storer { + disableCatchAll bool, + icConfig *ingressclass.IngressClassConfiguration) Storer { store := &k8sStore{ informers: &Informer{}, @@ -293,9 +297,12 @@ func New( informers.WithTweakListOptions(secretsTweakListOptionsFunc), ) - store.informers.Ingress = infFactory.Networking().V1beta1().Ingresses().Informer() + store.informers.Ingress = infFactory.Networking().V1().Ingresses().Informer() store.listers.Ingress.Store = store.informers.Ingress.GetStore() + store.informers.IngressClass = infFactory.Networking().V1().IngressClasses().Informer() + store.listers.IngressClass.Store = cache.NewStore(cache.MetaNamespaceKeyFunc) + store.informers.Endpoint = infFactory.Core().V1().Endpoints().Informer() store.listers.Endpoint.Store = store.informers.Endpoint.GetStore() @@ -317,14 +324,16 @@ func New( klog.ErrorS(nil, "Error obtaining object from tombstone", "key", obj) return } - ing, ok = tombstone.Obj.(*networkingv1beta1.Ingress) + ing, ok = tombstone.Obj.(*networkingv1.Ingress) if !ok { klog.Errorf("Tombstone contained object that is not an Ingress: %#v", obj) return } } - if !class.IsValid(ing) { + _, err := store.GetIngressClass(ing, icConfig) + if err != nil { + klog.InfoS("Ignoring ingress because of error while validating ingress class", "ingress", klog.KObj(ing), "error", err) return } @@ -347,12 +356,14 @@ func New( ingEventHandler := cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { ing, _ := toIngress(obj) - if !class.IsValid(ing) { - ingressClass, _ := parser.GetStringAnnotation(class.IngressKey, ing) - klog.InfoS("Ignoring ingress", "ingress", klog.KObj(ing), "kubernetes.io/ingress.class", ingressClass, "ingressClassName", pointer.StringPtrDerefOr(ing.Spec.IngressClassName, "")) + ic, err := store.GetIngressClass(ing, icConfig) + if err != nil { + klog.InfoS("Ignoring ingress because of error while validating ingress class", "ingress", klog.KObj(ing), "error", err) return } + klog.InfoS("Found valid IngressClass", "ingress", klog.KObj(ing), "ingressclass", ic) + if hasCatchAllIngressRule(ing.Spec) && disableCatchAll { klog.InfoS("Ignoring add for catch-all ingress because of --disable-catch-all", "ingress", klog.KObj(ing)) return @@ -374,21 +385,21 @@ func New( oldIng, _ := toIngress(old) curIng, _ := toIngress(cur) - validOld := class.IsValid(oldIng) - validCur := class.IsValid(curIng) - if !validOld && validCur { + _, errOld := store.GetIngressClass(oldIng, icConfig) + classCur, errCur := store.GetIngressClass(curIng, icConfig) + if errOld != nil && errCur == nil { if hasCatchAllIngressRule(curIng.Spec) && disableCatchAll { klog.InfoS("ignoring update for catch-all ingress because of --disable-catch-all", "ingress", klog.KObj(curIng)) return } - klog.InfoS("creating ingress", "ingress", klog.KObj(curIng), "class", class.IngressKey) + klog.InfoS("creating ingress", "ingress", klog.KObj(curIng), "ingressclass", classCur) recorder.Eventf(curIng, corev1.EventTypeNormal, "Sync", "Scheduled for sync") - } else if validOld && !validCur { - klog.InfoS("removing ingress", "ingress", klog.KObj(curIng), "class", class.IngressKey) + } else if errOld == nil && errCur != nil { + klog.InfoS("removing ingress because of unknown ingressclass", "ingress", klog.KObj(curIng)) ingDeleteHandler(old) return - } else if validCur && !reflect.DeepEqual(old, cur) { + } else if errCur == nil && !reflect.DeepEqual(old, cur) { if hasCatchAllIngressRule(curIng.Spec) && disableCatchAll { klog.InfoS("ignoring update for catch-all ingress and delete old one because of --disable-catch-all", "ingress", klog.KObj(curIng)) ingDeleteHandler(old) @@ -412,6 +423,63 @@ func New( }, } + ingressClassEventHandler := cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + ingressclass := obj.(*networkingv1.IngressClass) + if ingressclass.Spec.Controller != icConfig.Controller { + klog.InfoS("ignoring ingressclass as the spec.controller is not the same of this ingress", "ingressclass", klog.KObj(ingressclass)) + return + } + err := store.listers.IngressClass.Add(ingressclass) + if err != nil { + klog.InfoS("error adding ingressclass to store", "ingressclass", klog.KObj(ingressclass), "error", err) + return + } + + updateCh.In() <- Event{ + Type: CreateEvent, + Obj: obj, + } + }, + DeleteFunc: func(obj interface{}) { + ingressclass := obj.(*networkingv1.IngressClass) + if ingressclass.Spec.Controller != icConfig.Controller { + klog.InfoS("ignoring ingressclass as the spec.controller is not the same of this ingress", "ingressclass", klog.KObj(ingressclass)) + return + } + err := store.listers.IngressClass.Delete(ingressclass) + if err != nil { + klog.InfoS("error removing ingressclass from store", "ingressclass", klog.KObj(ingressclass), "error", err) + return + } + updateCh.In() <- Event{ + Type: DeleteEvent, + Obj: obj, + } + }, + UpdateFunc: func(old, cur interface{}) { + oic := old.(*networkingv1.IngressClass) + cic := cur.(*networkingv1.IngressClass) + if cic.Spec.Controller != icConfig.Controller { + klog.InfoS("ignoring ingressclass as the spec.controller is not the same of this ingress", "ingressclass", klog.KObj(cic)) + return + } + // TODO: In a future we might be interested in parse parameters and use as + // current IngressClass for this case, crossing with configmap + if !reflect.DeepEqual(cic.Spec.Parameters, oic.Spec.Parameters) { + err := store.listers.IngressClass.Update(cic) + if err != nil { + klog.InfoS("error updating ingressclass in store", "ingressclass", klog.KObj(cic), "error", err) + return + } + updateCh.In() <- Event{ + Type: UpdateEvent, + Obj: cur, + } + } + }, + } + secrEventHandler := cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { sec := obj.(*corev1.Secret) @@ -608,6 +676,7 @@ func New( } store.informers.Ingress.AddEventHandler(ingEventHandler) + store.informers.IngressClass.AddEventHandler(ingressClassEventHandler) store.informers.Endpoint.AddEventHandler(epEventHandler) store.informers.Secret.AddEventHandler(secrEventHandler) store.informers.ConfigMap.AddEventHandler(cmEventHandler) @@ -626,17 +695,17 @@ func New( // hasCatchAllIngressRule returns whether or not an ingress produces a // catch-all server, and so should be ignored when --disable-catch-all is set -func hasCatchAllIngressRule(spec networkingv1beta1.IngressSpec) bool { - return spec.Backend != nil +func hasCatchAllIngressRule(spec networkingv1.IngressSpec) bool { + return spec.DefaultBackend != nil } // syncIngress parses ingress annotations converting the value of the // annotation to a go struct -func (s *k8sStore) syncIngress(ing *networkingv1beta1.Ingress) { +func (s *k8sStore) syncIngress(ing *networkingv1.Ingress) { key := k8s.MetaNamespaceKey(ing) klog.V(3).Infof("updating annotations information for ingress %v", key) - copyIng := &networkingv1beta1.Ingress{} + copyIng := &networkingv1.Ingress{} ing.ObjectMeta.DeepCopyInto(©Ing.ObjectMeta) ing.Spec.DeepCopyInto(©Ing.Spec) ing.Status.DeepCopyInto(©Ing.Status) @@ -666,7 +735,7 @@ func (s *k8sStore) syncIngress(ing *networkingv1beta1.Ingress) { // updateSecretIngressMap takes an Ingress and updates all Secret objects it // references in secretIngressMap. -func (s *k8sStore) updateSecretIngressMap(ing *networkingv1beta1.Ingress) { +func (s *k8sStore) updateSecretIngressMap(ing *networkingv1.Ingress) { key := k8s.MetaNamespaceKey(ing) klog.V(3).Infof("updating references to secrets for ingress %v", key) @@ -710,7 +779,7 @@ func (s *k8sStore) updateSecretIngressMap(ing *networkingv1beta1.Ingress) { // objectRefAnnotationNsKey returns an object reference formatted as a // 'namespace/name' key from the given annotation name. -func objectRefAnnotationNsKey(ann string, ing *networkingv1beta1.Ingress) (string, error) { +func objectRefAnnotationNsKey(ann string, ing *networkingv1.Ingress) (string, error) { annValue, err := parser.GetStringAnnotation(ann, ing) if err != nil { return "", err @@ -729,7 +798,7 @@ func objectRefAnnotationNsKey(ann string, ing *networkingv1beta1.Ingress) (strin // syncSecrets synchronizes data from all Secrets referenced by the given // Ingress with the local store and file system. -func (s *k8sStore) syncSecrets(ing *networkingv1beta1.Ingress) { +func (s *k8sStore) syncSecrets(ing *networkingv1.Ingress) { key := k8s.MetaNamespaceKey(ing) for _, secrKey := range s.secretIngressMap.ReferencedBy(key) { s.syncSecret(secrKey) @@ -758,8 +827,34 @@ func (s *k8sStore) GetService(key string) (*corev1.Service, error) { return s.listers.Service.ByKey(key) } +func (s *k8sStore) GetIngressClass(ing *networkingv1.Ingress, icConfig *ingressclass.IngressClassConfiguration) (string, error) { + // First we try ingressClassName + if ing.Spec.IngressClassName != nil { + iclass, err := s.listers.IngressClass.ByKey(*ing.Spec.IngressClassName) + if err != nil { + return "", err + } + return iclass.Name, nil + } + + // Then we try annotation + if ingressclass, ok := ing.GetAnnotations()[ingressclass.IngressKey]; ok { + if ingressclass != icConfig.AnnotationValue { + return "", fmt.Errorf("ingress class annotation is not equal to the expected by Ingress Controller") + } + return ingressclass, nil + } + + // Then we accept if the WithoutClass is enabled + if icConfig.WatchWithoutClass { + // Reserving "_" as a "wildcard" name + return "_", nil + } + return "", fmt.Errorf("ingress does not contain a valid IngressClass") +} + // getIngress returns the Ingress matching key. -func (s *k8sStore) getIngress(key string) (*networkingv1beta1.Ingress, error) { +func (s *k8sStore) getIngress(key string) (*networkingv1.Ingress, error) { ing, err := s.listers.IngressWithAnnotation.ByKey(key) if err != nil { return nil, err @@ -900,11 +995,11 @@ func (s *k8sStore) Run(stopCh chan struct{}) { var runtimeScheme = k8sruntime.NewScheme() func init() { - utilruntime.Must(networkingv1beta1.AddToScheme(runtimeScheme)) + utilruntime.Must(networkingv1.AddToScheme(runtimeScheme)) } -func toIngress(obj interface{}) (*networkingv1beta1.Ingress, bool) { - if ing, ok := obj.(*networkingv1beta1.Ingress); ok { +func toIngress(obj interface{}) (*networkingv1.Ingress, bool) { + if ing, ok := obj.(*networkingv1.Ingress); ok { k8s.SetDefaultNGINXPathType(ing) return ing, true } diff --git a/internal/ingress/controller/store/store_test.go b/internal/ingress/controller/store/store_test.go index bcc8f67d6..c84775ee5 100644 --- a/internal/ingress/controller/store/store_test.go +++ b/internal/ingress/controller/store/store_test.go @@ -29,24 +29,61 @@ import ( "github.com/eapache/channels" v1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" k8sErrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" "sigs.k8s.io/controller-runtime/pkg/envtest" "k8s.io/ingress-nginx/internal/ingress" - "k8s.io/ingress-nginx/internal/ingress/annotations/class" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" + "k8s.io/ingress-nginx/internal/ingress/controller/ingressclass" "k8s.io/ingress-nginx/test/e2e/framework" ) +var pathPrefix networking.PathType = networking.PathTypePrefix + +var DefaultClassConfig = &ingressclass.IngressClassConfiguration{ + Controller: ingressclass.DefaultControllerName, + AnnotationValue: ingressclass.DefaultAnnotationValue, + WatchWithoutClass: false, +} + +var ( + commonIngressSpec = networking.IngressSpec{ + Rules: []networking.IngressRule{ + { + Host: "dummy", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/", + PathType: &pathPrefix, + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "http-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +) + func TestStore(t *testing.T) { //TODO: move env definition to docker image? os.Setenv("KUBEBUILDER_ASSETS", "/usr/local/bin") + pathPrefix = networking.PathTypePrefix + te := &envtest.Environment{} cfg, err := te.Start() if err != nil { @@ -83,7 +120,8 @@ func TestStore(t *testing.T) { 10*time.Minute, clientSet, updateCh, - false) + false, + DefaultClassConfig) storer.Run(stopCh) @@ -109,13 +147,14 @@ func TestStore(t *testing.T) { t.Errorf("expected an error but none returned") } if svc != nil { - t.Errorf("expected an Ingres but none returned") + t.Errorf("expected an Ingress but none returned") } }) - t.Run("should return one event for add, update and delete of ingress", func(t *testing.T) { + t.Run("should return no event for add, update and delete of ingress as the existing ingressclass is not the expected", func(t *testing.T) { ns := createNamespace(clientSet, t) defer deleteNamespace(ns, clientSet, t) + createConfigMap(clientSet, ns, t) stopCh := make(chan struct{}) @@ -160,35 +199,20 @@ func TestStore(t *testing.T) { 10*time.Minute, clientSet, updateCh, - false) + false, + DefaultClassConfig) storer.Run(stopCh) - + ic := createIngressClass(clientSet, t, "not-k8s.io/not-ingress-nginx") + defer deleteIngressClass(ic, clientSet, t) + validSpec := commonIngressSpec + validSpec.IngressClassName = &ic ing := ensureIngress(&networking.Ingress{ ObjectMeta: metav1.ObjectMeta{ - Name: "dummy", + Name: "dummy-no-class", Namespace: ns, }, - Spec: networking.IngressSpec{ - Rules: []networking.IngressRule{ - { - Host: "dummy", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{ - { - Path: "/", - Backend: networking.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.FromInt(80), - }, - }, - }, - }, - }, - }, - }, - }, + Spec: validSpec, }, clientSet, t) err := framework.WaitForIngressInNamespace(clientSet, ns, ing.Name) @@ -197,35 +221,113 @@ func TestStore(t *testing.T) { } time.Sleep(1 * time.Second) - // create an invalid ingress (different class) + ni := ing.DeepCopy() + ni.Spec.Rules[0].Host = "update-dummy" + _ = ensureIngress(ni, clientSet, t) + if err != nil { + t.Errorf("error creating ingress: %v", err) + } + // Secret takes a bit to update + time.Sleep(3 * time.Second) + + err = clientSet.NetworkingV1().Ingresses(ni.Namespace).Delete(context.TODO(), ni.Name, metav1.DeleteOptions{}) + if err != nil { + t.Errorf("error deleting ingress: %v", err) + } + + err = framework.WaitForNoIngressInNamespace(clientSet, ni.Namespace, ni.Name) + if err != nil { + t.Errorf("error waiting for secret: %v", err) + } + time.Sleep(1 * time.Second) + + if atomic.LoadUint64(&add) != 0 { + t.Errorf("expected 0 event of type Create but %v occurred", add) + } + if atomic.LoadUint64(&upd) != 0 { + t.Errorf("expected 0 event of type Update but %v occurred", upd) + } + if atomic.LoadUint64(&del) != 0 { + t.Errorf("expected 0 event of type Delete but %v occurred", del) + } + }) + + t.Run("should return one event for add, update and delete of ingress", func(t *testing.T) { + ns := createNamespace(clientSet, t) + defer deleteNamespace(ns, clientSet, t) + ic := createIngressClass(clientSet, t, ingressclass.DefaultControllerName) + defer deleteIngressClass(ic, clientSet, t) + createConfigMap(clientSet, ns, t) + + stopCh := make(chan struct{}) + updateCh := channels.NewRingChannel(1024) + + var add uint64 + var upd uint64 + var del uint64 + + go func(ch *channels.RingChannel) { + for { + evt, ok := <-ch.Out() + if !ok { + return + } + + e := evt.(Event) + if e.Obj == nil { + continue + } + if _, ok := e.Obj.(*networking.Ingress); !ok { + continue + } + + switch e.Type { + case CreateEvent: + atomic.AddUint64(&add, 1) + case UpdateEvent: + atomic.AddUint64(&upd, 1) + case DeleteEvent: + atomic.AddUint64(&del, 1) + } + } + }(updateCh) + + storer := New( + ns, + fmt.Sprintf("%v/config", ns), + fmt.Sprintf("%v/tcp", ns), + fmt.Sprintf("%v/udp", ns), + "", + 10*time.Minute, + clientSet, + updateCh, + false, + DefaultClassConfig) + + storer.Run(stopCh) + validSpec := commonIngressSpec + validSpec.IngressClassName = &ic + ing := ensureIngress(&networking.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dummy-class", + Namespace: ns, + }, + Spec: validSpec, + }, clientSet, t) + + err := framework.WaitForIngressInNamespace(clientSet, ns, ing.Name) + if err != nil { + t.Errorf("error waiting for secret: %v", err) + } + time.Sleep(1 * time.Second) + + // create an invalid ingress (no ingress class and no watchWithoutClass config) invalidIngress := ensureIngress(&networking.Ingress{ ObjectMeta: metav1.ObjectMeta{ - Name: "custom-class", + Name: "no-class", Namespace: ns, - Annotations: map[string]string{ - class.IngressKey: "something", - }, - }, - Spec: networking.IngressSpec{ - Rules: []networking.IngressRule{ - { - Host: "dummy", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{ - { - Path: "/", - Backend: networking.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.FromInt(80), - }, - }, - }, - }, - }, - }, - }, }, + Spec: commonIngressSpec, }, clientSet, t) defer deleteIngress(invalidIngress, clientSet, t) @@ -238,9 +340,9 @@ func TestStore(t *testing.T) { // Secret takes a bit to update time.Sleep(3 * time.Second) - err = clientSet.NetworkingV1beta1().Ingresses(ni.Namespace).Delete(context.TODO(), ni.Name, metav1.DeleteOptions{}) + err = clientSet.NetworkingV1().Ingresses(ni.Namespace).Delete(context.TODO(), ni.Name, metav1.DeleteOptions{}) if err != nil { - t.Errorf("error creating ingress: %v", err) + t.Errorf("error deleting ingress: %v", err) } err = framework.WaitForNoIngressInNamespace(clientSet, ni.Namespace, ni.Name) @@ -260,7 +362,7 @@ func TestStore(t *testing.T) { } }) - t.Run("should not receive updates for ingress with invalid class", func(t *testing.T) { + t.Run("should return two events for add and delete and one for update of ingress and watch-without-class", func(t *testing.T) { ns := createNamespace(clientSet, t) defer deleteNamespace(ns, clientSet, t) createConfigMap(clientSet, ns, t) @@ -298,6 +400,224 @@ func TestStore(t *testing.T) { } }(updateCh) + ingressClassconfig := &ingressclass.IngressClassConfiguration{ + Controller: ingressclass.DefaultControllerName, + AnnotationValue: ingressclass.DefaultAnnotationValue, + WatchWithoutClass: true, + } + + storer := New( + ns, + fmt.Sprintf("%v/config", ns), + fmt.Sprintf("%v/tcp", ns), + fmt.Sprintf("%v/udp", ns), + "", + 10*time.Minute, + clientSet, + updateCh, + false, + ingressClassconfig) + + storer.Run(stopCh) + + validIngress1 := ensureIngress(&networking.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ing1", + Namespace: ns, + }, + Spec: commonIngressSpec, + }, clientSet, t) + err := framework.WaitForIngressInNamespace(clientSet, ns, validIngress1.Name) + if err != nil { + t.Errorf("error waiting for ingress: %v", err) + } + + otherIngress := commonIngressSpec + otherIngress.Rules[0].Host = "other-ingress" + validIngress2 := ensureIngress(&networking.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ing2", + Namespace: ns, + }, + Spec: otherIngress, + }, clientSet, t) + err = framework.WaitForIngressInNamespace(clientSet, ns, validIngress2.Name) + if err != nil { + t.Errorf("error waiting for ingress: %v", err) + } + + time.Sleep(1 * time.Second) + + validIngressUpdated := validIngress1.DeepCopy() + validIngressUpdated.Spec.Rules[0].Host = "update-dummy" + _ = ensureIngress(validIngressUpdated, clientSet, t) + if err != nil { + t.Errorf("error updating ingress: %v", err) + } + // Secret takes a bit to update + time.Sleep(3 * time.Second) + + err = clientSet.NetworkingV1().Ingresses(validIngressUpdated.Namespace).Delete(context.TODO(), validIngressUpdated.Name, metav1.DeleteOptions{}) + if err != nil { + t.Errorf("error deleting ingress: %v", err) + } + err = clientSet.NetworkingV1().Ingresses(validIngress2.Namespace).Delete(context.TODO(), validIngress2.Name, metav1.DeleteOptions{}) + if err != nil { + t.Errorf("error deleting ingress: %v", err) + } + + err = framework.WaitForNoIngressInNamespace(clientSet, validIngressUpdated.Namespace, validIngressUpdated.Name) + if err != nil { + t.Errorf("error waiting for ingress deletion: %v", err) + } + err = framework.WaitForNoIngressInNamespace(clientSet, validIngress2.Namespace, validIngress2.Name) + if err != nil { + t.Errorf("error waiting for ingress deletion: %v", err) + } + time.Sleep(1 * time.Second) + + if atomic.LoadUint64(&add) != 2 { + t.Errorf("expected 0 event of type Create but %v occurred", add) + } + if atomic.LoadUint64(&upd) != 1 { + t.Errorf("expected 0 event of type Update but %v occurred", upd) + } + if atomic.LoadUint64(&del) != 2 { + t.Errorf("expected 0 event of type Delete but %v occurred", del) + } + }) + + t.Run("should not receive updates for ingress with invalid class annotation", func(t *testing.T) { + ns := createNamespace(clientSet, t) + defer deleteNamespace(ns, clientSet, t) + createConfigMap(clientSet, ns, t) + + stopCh := make(chan struct{}) + updateCh := channels.NewRingChannel(1024) + + var add uint64 + var upd uint64 + var del uint64 + + // TODO: This repeats a lot, transform in a local function + go func(ch *channels.RingChannel) { + for { + evt, ok := <-ch.Out() + if !ok { + return + } + + e := evt.(Event) + if e.Obj == nil { + continue + } + if _, ok := e.Obj.(*networking.Ingress); !ok { + continue + } + + switch e.Type { + case CreateEvent: + atomic.AddUint64(&add, 1) + case UpdateEvent: + atomic.AddUint64(&upd, 1) + case DeleteEvent: + atomic.AddUint64(&del, 1) + } + } + }(updateCh) + + storer := New( + ns, + fmt.Sprintf("%v/config", ns), + fmt.Sprintf("%v/tcp", ns), + fmt.Sprintf("%v/udp", ns), + "", + 10*time.Minute, + clientSet, + updateCh, + false, + DefaultClassConfig) + + storer.Run(stopCh) + + // create an invalid ingress (different class) + invalidIngress := ensureIngress(&networking.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "custom-class", + Namespace: ns, + Annotations: map[string]string{ + ingressclass.IngressKey: "something", + }, + }, + Spec: commonIngressSpec, + }, clientSet, t) + err := framework.WaitForIngressInNamespace(clientSet, ns, invalidIngress.Name) + if err != nil { + t.Errorf("error waiting for ingress: %v", err) + } + time.Sleep(1 * time.Second) + + invalidIngressUpdated := invalidIngress.DeepCopy() + invalidIngressUpdated.Spec.Rules[0].Host = "update-dummy" + _ = ensureIngress(invalidIngressUpdated, clientSet, t) + if err != nil { + t.Errorf("error creating ingress: %v", err) + } + // Secret takes a bit to update + time.Sleep(3 * time.Second) + + if atomic.LoadUint64(&add) != 0 { + t.Errorf("expected 0 event of type Create but %v occurred", add) + } + if atomic.LoadUint64(&upd) != 0 { + t.Errorf("expected 0 event of type Update but %v occurred", upd) + } + if atomic.LoadUint64(&del) != 0 { + t.Errorf("expected 0 event of type Delete but %v occurred", del) + } + }) + + t.Run("should not receive updates for ingress with invalid class specification", func(t *testing.T) { + ns := createNamespace(clientSet, t) + defer deleteNamespace(ns, clientSet, t) + ic := createIngressClass(clientSet, t, ingressclass.DefaultControllerName) + defer deleteIngressClass(ic, clientSet, t) + + createConfigMap(clientSet, ns, t) + + stopCh := make(chan struct{}) + updateCh := channels.NewRingChannel(1024) + + var add uint64 + var upd uint64 + var del uint64 + + go func(ch *channels.RingChannel) { + for { + evt, ok := <-ch.Out() + if !ok { + return + } + + e := evt.(Event) + if e.Obj == nil { + continue + } + if _, ok := e.Obj.(*networking.Ingress); !ok { + continue + } + + switch e.Type { + case CreateEvent: + atomic.AddUint64(&add, 1) + case UpdateEvent: + atomic.AddUint64(&upd, 1) + case DeleteEvent: + atomic.AddUint64(&del, 1) + } + } + }(updateCh) + storer := New( ns, fmt.Sprintf("%v/config", ns), @@ -307,39 +627,20 @@ func TestStore(t *testing.T) { 10*time.Minute, clientSet, updateCh, - false) + false, + DefaultClassConfig) storer.Run(stopCh) - + invalidSpec := commonIngressSpec + invalidClassName := "blo123" + invalidSpec.IngressClassName = &invalidClassName // create an invalid ingress (different class) invalidIngress := ensureIngress(&networking.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "custom-class", Namespace: ns, - Annotations: map[string]string{ - class.IngressKey: "something", - }, - }, - Spec: networking.IngressSpec{ - Rules: []networking.IngressRule{ - { - Host: "dummy", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{ - { - Path: "/", - Backend: networking.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.FromInt(80), - }, - }, - }, - }, - }, - }, - }, }, + Spec: invalidSpec, }, clientSet, t) err := framework.WaitForIngressInNamespace(clientSet, ns, invalidIngress.Name) if err != nil { @@ -410,7 +711,8 @@ func TestStore(t *testing.T) { 10*time.Minute, clientSet, updateCh, - false) + false, + DefaultClassConfig) storer.Run(stopCh) @@ -456,6 +758,8 @@ func TestStore(t *testing.T) { t.Run("should receive events from secret referenced from ingress", func(t *testing.T) { ns := createNamespace(clientSet, t) defer deleteNamespace(ns, clientSet, t) + ic := createIngressClass(clientSet, t, ingressclass.DefaultControllerName) + defer deleteIngressClass(ic, clientSet, t) createConfigMap(clientSet, ns, t) stopCh := make(chan struct{}) @@ -476,6 +780,11 @@ func TestStore(t *testing.T) { if e.Obj == nil { continue } + + // We should skip IngressClass events + if _, ok := e.Obj.(*networking.IngressClass); ok { + continue + } switch e.Type { case CreateEvent: atomic.AddUint64(&add, 1) @@ -496,7 +805,8 @@ func TestStore(t *testing.T) { 10*time.Minute, clientSet, updateCh, - false) + false, + DefaultClassConfig) storer.Run(stopCh) @@ -509,14 +819,19 @@ func TestStore(t *testing.T) { Namespace: ns, }, Spec: networking.IngressSpec{ + IngressClassName: &ic, TLS: []networking.IngressTLS{ { SecretName: secretName, }, }, - Backend: &networking.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.FromInt(80), + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "http-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, }, }, clientSet, t) @@ -564,6 +879,8 @@ func TestStore(t *testing.T) { t.Run("should create an ingress with a secret which does not exist", func(t *testing.T) { ns := createNamespace(clientSet, t) defer deleteNamespace(ns, clientSet, t) + ic := createIngressClass(clientSet, t, ingressclass.DefaultControllerName) + defer deleteIngressClass(ic, clientSet, t) createConfigMap(clientSet, ns, t) stopCh := make(chan struct{}) @@ -584,6 +901,12 @@ func TestStore(t *testing.T) { if e.Obj == nil { continue } + + // We should skip IngressClass objects here + if _, ok := e.Obj.(*networking.IngressClass); ok { + continue + } + switch e.Type { case CreateEvent: atomic.AddUint64(&add, 1) @@ -604,7 +927,8 @@ func TestStore(t *testing.T) { 10*time.Minute, clientSet, updateCh, - false) + false, + DefaultClassConfig) storer.Run(stopCh) @@ -617,6 +941,7 @@ func TestStore(t *testing.T) { Namespace: ns, }, Spec: networking.IngressSpec{ + IngressClassName: &ic, TLS: []networking.IngressTLS{ { Hosts: secretHosts, @@ -630,10 +955,15 @@ func TestStore(t *testing.T) { HTTP: &networking.HTTPIngressRuleValue{ Paths: []networking.HTTPIngressPath{ { - Path: "/", + Path: "/", + PathType: &pathPrefix, Backend: networking.IngressBackend{ - ServiceName: "http-svc", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "http-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, }, }, @@ -706,6 +1036,33 @@ func deleteNamespace(ns string, clientSet kubernetes.Interface, t *testing.T) { } } +func createIngressClass(clientSet kubernetes.Interface, t *testing.T, controller string) string { + t.Helper() + ingressclass := &networking.IngressClass{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("ingress-nginx-%v", time.Now().Unix()), + //Namespace: "xpto" // TODO: We don't support namespaced ingress-class yet + }, + Spec: networking.IngressClassSpec{ + Controller: controller, + }, + } + ic, err := clientSet.NetworkingV1().IngressClasses().Create(context.TODO(), ingressclass, metav1.CreateOptions{}) + if err != nil { + t.Errorf("error creating ingress class: %v", err) + } + return ic.Name +} + +func deleteIngressClass(ic string, clientSet kubernetes.Interface, t *testing.T) { + t.Helper() + + err := clientSet.NetworkingV1().IngressClasses().Delete(context.TODO(), ic, metav1.DeleteOptions{}) + if err != nil { + t.Errorf("error deleting the ingress class: %v", err) + } +} + func createConfigMap(clientSet kubernetes.Interface, ns string, t *testing.T) string { t.Helper() @@ -725,13 +1082,13 @@ func createConfigMap(clientSet kubernetes.Interface, ns string, t *testing.T) st func ensureIngress(ingress *networking.Ingress, clientSet kubernetes.Interface, t *testing.T) *networking.Ingress { t.Helper() - ing, err := clientSet.NetworkingV1beta1().Ingresses(ingress.Namespace).Update(context.TODO(), ingress, metav1.UpdateOptions{}) + ing, err := clientSet.NetworkingV1().Ingresses(ingress.Namespace).Update(context.TODO(), ingress, metav1.UpdateOptions{}) if err != nil { if k8sErrors.IsNotFound(err) { t.Logf("Ingress %v not found, creating", ingress) - ing, err = clientSet.NetworkingV1beta1().Ingresses(ingress.Namespace).Create(context.TODO(), ingress, metav1.CreateOptions{}) + ing, err = clientSet.NetworkingV1().Ingresses(ingress.Namespace).Create(context.TODO(), ingress, metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating ingress %+v: %v", ingress, err) } @@ -748,7 +1105,7 @@ func ensureIngress(ingress *networking.Ingress, clientSet kubernetes.Interface, func deleteIngress(ingress *networking.Ingress, clientSet kubernetes.Interface, t *testing.T) { t.Helper() - err := clientSet.NetworkingV1beta1().Ingresses(ingress.Namespace).Delete(context.TODO(), ingress.Name, metav1.DeleteOptions{}) + err := clientSet.NetworkingV1().Ingresses(ingress.Namespace).Delete(context.TODO(), ingress.Name, metav1.DeleteOptions{}) if err != nil { t.Errorf("failed to delete ingress %+v: %v", ingress, err) @@ -763,6 +1120,7 @@ func newStore(t *testing.T) *k8sStore { return &k8sStore{ listers: &Lister{ // add more listers if needed + IngressClass: IngressClassLister{cache.NewStore(cache.MetaNamespaceKeyFunc)}, Ingress: IngressLister{cache.NewStore(cache.MetaNamespaceKeyFunc)}, IngressWithAnnotation: IngressWithAnnotationsLister{cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc)}, }, @@ -840,21 +1198,25 @@ func TestUpdateSecretIngressMap(t *testing.T) { func TestListIngresses(t *testing.T) { s := newStore(t) + invalidIngressClass := "something" + validIngressClass := ingressclass.DefaultControllerName ingressToIgnore := &ingress.Ingress{ Ingress: networking.Ingress{ ObjectMeta: metav1.ObjectMeta{ - Name: "test-2", - Namespace: "testns", - Annotations: map[string]string{ - class.IngressKey: "something", - }, + Name: "test-2", + Namespace: "testns", CreationTimestamp: metav1.NewTime(time.Now()), }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "demo", - ServicePort: intstr.FromInt(80), + IngressClassName: &invalidIngressClass, + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "demo", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, }, }, @@ -869,6 +1231,7 @@ func TestListIngresses(t *testing.T) { CreationTimestamp: metav1.NewTime(time.Now()), }, Spec: networking.IngressSpec{ + IngressClassName: &validIngressClass, Rules: []networking.IngressRule{ { Host: "foo.bar", @@ -877,8 +1240,12 @@ func TestListIngresses(t *testing.T) { Paths: []networking.HTTPIngressPath{ { Backend: networking.IngressBackend{ - ServiceName: "demo", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "demo", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, }, }, @@ -891,13 +1258,13 @@ func TestListIngresses(t *testing.T) { } s.listers.IngressWithAnnotation.Add(ingressWithoutPath) - ingressWithNginxClass := &ingress.Ingress{ + ingressWithNginxClassAnnotation := &ingress.Ingress{ Ingress: networking.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: "test-4", Namespace: "testns", Annotations: map[string]string{ - class.IngressKey: "nginx", + ingressclass.IngressKey: ingressclass.DefaultAnnotationValue, }, CreationTimestamp: metav1.NewTime(time.Now()), }, @@ -909,10 +1276,15 @@ func TestListIngresses(t *testing.T) { HTTP: &networking.HTTPIngressRuleValue{ Paths: []networking.HTTPIngressPath{ { - Path: "/demo", + Path: "/demo", + PathType: &pathPrefix, Backend: networking.IngressBackend{ - ServiceName: "demo", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "demo", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, }, }, @@ -923,7 +1295,7 @@ func TestListIngresses(t *testing.T) { }, }, } - s.listers.IngressWithAnnotation.Add(ingressWithNginxClass) + s.listers.IngressWithAnnotation.Add(ingressWithNginxClassAnnotation) ingresses := s.ListIngresses() diff --git a/internal/ingress/controller/tcp.go b/internal/ingress/controller/tcp.go index a97c46a7e..eedecc71a 100644 --- a/internal/ingress/controller/tcp.go +++ b/internal/ingress/controller/tcp.go @@ -82,6 +82,7 @@ func (p *TCPProxy) Handle(conn net.Conn) { hostPort := net.JoinHostPort(proxy.IP, fmt.Sprintf("%v", proxy.Port)) clientConn, err := net.Dial("tcp", hostPort) if err != nil { + klog.V(4).ErrorS(err, "error dialing proxy", "ip", proxy.IP, "port", proxy.Port, "hostname", proxy.Hostname) return } defer clientConn.Close() diff --git a/internal/ingress/controller/template/template.go b/internal/ingress/controller/template/template.go index 98e737a63..597c0866f 100644 --- a/internal/ingress/controller/template/template.go +++ b/internal/ingress/controller/template/template.go @@ -23,22 +23,23 @@ import ( "encoding/hex" "encoding/json" "fmt" + "io" "io/ioutil" "math/rand" // #nosec "net" "net/url" "os" - "os/exec" "reflect" "regexp" "sort" + "strconv" "strings" text_template "text/template" "time" "github.com/pkg/errors" - networkingv1beta1 "k8s.io/api/networking/v1beta1" + networkingv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" @@ -50,9 +51,15 @@ import ( ) const ( - slash = "/" - nonIdempotent = "non_idempotent" - defBufferSize = 65535 + slash = "/" + nonIdempotent = "non_idempotent" + defBufferSize = 65535 + writeIndentOnEmptyLines = true // backward-compatibility +) + +const ( + stateCode = iota + stateComment ) // TemplateWriter is the interface to render a template @@ -86,6 +93,87 @@ func NewTemplate(file string) (*Template, error) { }, nil } +// 1. Removes carriage return symbol (\r) +// 2. Collapses multiple empty lines to single one +// 3. Re-indent +// (ATW: always returns nil) +func cleanConf(in *bytes.Buffer, out *bytes.Buffer) error { + depth := 0 + lineStarted := false + emptyLineWritten := false + state := stateCode + for { + c, err := in.ReadByte() + if err != nil { + if err == io.EOF { + return nil + } + return err // unreachable + } + + needOutput := false + nextDepth := depth + nextLineStarted := lineStarted + + switch state { + case stateCode: + switch c { + case '{': + needOutput = true + nextDepth = depth + 1 + nextLineStarted = true + case '}': + needOutput = true + depth-- + nextDepth = depth + nextLineStarted = true + case ' ', '\t': + needOutput = lineStarted + case '\r': + case '\n': + needOutput = !(!lineStarted && emptyLineWritten) + nextLineStarted = false + case '#': + needOutput = true + nextLineStarted = true + state = stateComment + default: + needOutput = true + nextLineStarted = true + } + case stateComment: + switch c { + case '\r': + case '\n': + needOutput = true + nextLineStarted = false + state = stateCode + default: + needOutput = true + } + } + + if needOutput { + if !lineStarted && (writeIndentOnEmptyLines || c != '\n') { + for i := 0; i < depth; i++ { + err = out.WriteByte('\t') // always nil + if err != nil { + return err + } + } + } + emptyLineWritten = !lineStarted + err = out.WriteByte(c) // always nil + if err != nil { + return err + } + } + + depth = nextDepth + lineStarted = nextLineStarted + } +} + // Write populates a buffer using a template with NGINX configuration // and the servers and upstreams created by Ingress rules func (t *Template) Write(conf config.TemplateConfig) ([]byte, error) { @@ -110,12 +198,9 @@ func (t *Template) Write(conf config.TemplateConfig) ([]byte, error) { // squeezes multiple adjacent empty lines to be single // spaced this is to avoid the use of regular expressions - cmd := exec.Command("/ingress-controller/clean-nginx-conf.sh") - cmd.Stdin = tmplBuf - cmd.Stdout = outCmdBuf - if err := cmd.Run(); err != nil { - klog.Warningf("unexpected error cleaning template: %v", err) - return tmplBuf.Bytes(), nil + err = cleanConf(tmplBuf, outCmdBuf) + if err != nil { + return nil, err } return outCmdBuf.Bytes(), nil @@ -435,7 +520,7 @@ func buildLocation(input interface{}, enforceRegex bool) string { return fmt.Sprintf(`~* "^%s"`, path) } - if location.PathType != nil && *location.PathType == networkingv1beta1.PathTypeExact { + if location.PathType != nil && *location.PathType == networkingv1.PathTypeExact { return fmt.Sprintf(`= %s`, path) } @@ -480,7 +565,7 @@ func shouldApplyGlobalAuth(input interface{}, globalExternalAuthURL string) bool return false } -func buildAuthResponseHeaders(headers []string) []string { +func buildAuthResponseHeaders(proxySetHeader string, headers []string) []string { res := []string{} if len(headers) == 0 { @@ -491,7 +576,7 @@ func buildAuthResponseHeaders(headers []string) []string { 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("proxy_set_header '%v' $authHeader%v;", h, i)) + res = append(res, fmt.Sprintf("%s '%v' $authHeader%v;", proxySetHeader, h, i)) } return res } @@ -583,7 +668,7 @@ func buildProxyPass(host string, b interface{}, loc interface{}) string { var xForwardedPrefix string if len(location.XForwardedPrefix) > 0 { - xForwardedPrefix = fmt.Sprintf("proxy_set_header X-Forwarded-Prefix \"%s\";\n", location.XForwardedPrefix) + xForwardedPrefix = fmt.Sprintf("%s X-Forwarded-Prefix \"%s\";\n", proxySetHeader(location), location.XForwardedPrefix) } return fmt.Sprintf(` @@ -899,10 +984,12 @@ func getIngressInformation(i, h, p interface{}) *ingressInformation { info.Path = "/" } - if ing.Spec.Backend != nil { - info.Service = ing.Spec.Backend.ServiceName - if ing.Spec.Backend.ServicePort.String() != "0" { - info.ServicePort = ing.Spec.Backend.ServicePort.String() + if ing.Spec.DefaultBackend != nil && ing.Spec.DefaultBackend.Service != nil { + info.Service = ing.Spec.DefaultBackend.Service.Name + if ing.Spec.DefaultBackend.Service.Port.Number > 0 { + info.ServicePort = strconv.Itoa(int(ing.Spec.DefaultBackend.Service.Port.Number)) + } else { + info.ServicePort = ing.Spec.DefaultBackend.Service.Port.Name } } @@ -929,14 +1016,16 @@ func getIngressInformation(i, h, p interface{}) *ingressInformation { continue } - if info.Service != "" && rPath.Backend.ServiceName == "" { + if info.Service != "" && rPath.Backend.Service.Name == "" { // empty rule. Only contains a Path and PathType return info } - info.Service = rPath.Backend.ServiceName - if rPath.Backend.ServicePort.String() != "0" { - info.ServicePort = rPath.Backend.ServicePort.String() + info.Service = rPath.Backend.Service.Name + if rPath.Backend.Service.Port.Number > 0 { + info.ServicePort = strconv.Itoa(int(rPath.Backend.Service.Port.Number)) + } else { + info.ServicePort = rPath.Backend.Service.Port.Name } return info diff --git a/internal/ingress/controller/template/template_test.go b/internal/ingress/controller/template/template_test.go index 1af988197..7b99d3275 100644 --- a/internal/ingress/controller/template/template_test.go +++ b/internal/ingress/controller/template/template_test.go @@ -17,6 +17,7 @@ limitations under the License. package template import ( + "bytes" "encoding/base64" "fmt" "io/ioutil" @@ -29,10 +30,10 @@ import ( "testing" jsoniter "github.com/json-iterator/go" + "github.com/pmezard/go-difflib/difflib" apiv1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress" "k8s.io/ingress-nginx/internal/ingress/annotations/authreq" @@ -55,6 +56,8 @@ func init() { } var ( + pathPrefix networking.PathType = networking.PathTypePrefix + // TODO: add tests for SSLPassthrough tmplFuncTestcases = map[string]struct { Path string @@ -178,6 +181,14 @@ proxy_pass http://upstream_balancer;`, } ) +func getTestDataDir() (string, error) { + pwd, err := os.Getwd() + if err != nil { + return "", err + } + return path.Join(pwd, "../../../../test/data"), nil +} + func TestBuildLuaSharedDictionaries(t *testing.T) { invalidType := &ingress.Ingress{} expected := "" @@ -197,11 +208,11 @@ func TestBuildLuaSharedDictionaries(t *testing.T) { servers := []*ingress.Server{ { Hostname: "foo.bar", - Locations: []*ingress.Location{{Path: "/"}}, + Locations: []*ingress.Location{{Path: "/", PathType: &pathPrefix}}, }, { Hostname: "another.host", - Locations: []*ingress.Location{{Path: "/"}}, + Locations: []*ingress.Location{{Path: "/", PathType: &pathPrefix}}, }, } // returns value from config @@ -283,8 +294,9 @@ func TestBuildLocation(t *testing.T) { for k, tc := range tmplFuncTestcases { loc := &ingress.Location{ - Path: tc.Path, - Rewrite: rewrite.Config{Target: tc.Target}, + Path: tc.Path, + PathType: &pathPrefix, + Rewrite: rewrite.Config{Target: tc.Target}, } newLoc := buildLocation(loc, tc.enforceRegex) @@ -301,6 +313,7 @@ func TestBuildProxyPass(t *testing.T) { for k, tc := range tmplFuncTestcases { loc := &ingress.Location{ Path: tc.Path, + PathType: &pathPrefix, Rewrite: rewrite.Config{Target: tc.Target}, Backend: defaultBackend, XForwardedPrefix: tc.XForwardedPrefix, @@ -435,7 +448,7 @@ func TestBuildAuthResponseHeaders(t *testing.T) { "proxy_set_header 'H-With-Caps-And-Dashes' $authHeader1;", } - headers := buildAuthResponseHeaders(externalAuthResponseHeaders) + headers := buildAuthResponseHeaders(proxySetHeader(nil), externalAuthResponseHeaders) if !reflect.DeepEqual(expected, headers) { t.Errorf("Expected \n'%v'\nbut returned \n'%v'", expected, headers) @@ -828,6 +841,7 @@ func TestBuildUpstreamName(t *testing.T) { for k, tc := range tmplFuncTestcases { loc := &ingress.Location{ Path: tc.Path, + PathType: &pathPrefix, Rewrite: rewrite.Config{Target: tc.Target}, Backend: defaultBackend, XForwardedPrefix: tc.XForwardedPrefix, @@ -926,6 +940,76 @@ func TestGetIngressInformation(t *testing.T) { 10, &ingressInformation{}, }, + "valid ingress definition with name validIng in namespace default using a service with name a-svc port number 8080": { + &ingress.Ingress{ + Ingress: networking.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "validIng", + Namespace: apiv1.NamespaceDefault, + Annotations: map[string]string{ + "ingress.annotation": "ok", + }, + }, + Spec: networking.IngressSpec{ + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "a-svc", + Port: networking.ServiceBackendPort{ + Number: 8080, + }, + }, + }, + }, + }, + }, + "host1", + "", + &ingressInformation{ + Namespace: "default", + Rule: "validIng", + Path: "/", + Annotations: map[string]string{ + "ingress.annotation": "ok", + }, + Service: "a-svc", + ServicePort: "8080", + }, + }, + "valid ingress definition with name validIng in namespace default using a service with name a-svc port name b-svc": { + &ingress.Ingress{ + Ingress: networking.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "validIng", + Namespace: apiv1.NamespaceDefault, + Annotations: map[string]string{ + "ingress.annotation": "ok", + }, + }, + Spec: networking.IngressSpec{ + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "a-svc", + Port: networking.ServiceBackendPort{ + Name: "b-svc", + }, + }, + }, + }, + }, + }, + "host1", + "", + &ingressInformation{ + Namespace: "default", + Rule: "validIng", + Path: "/", + Annotations: map[string]string{ + "ingress.annotation": "ok", + }, + Service: "a-svc", + ServicePort: "b-svc", + }, + }, "valid ingress definition with name validIng in namespace default": { &ingress.Ingress{ Ingress: networking.Ingress{ @@ -937,8 +1021,10 @@ func TestGetIngressInformation(t *testing.T) { }, }, Spec: networking.IngressSpec{ - Backend: &networking.IngressBackend{ - ServiceName: "a-svc", + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "a-svc", + }, }, }, }, @@ -948,6 +1034,7 @@ func TestGetIngressInformation(t *testing.T) { &ingressInformation{ Namespace: "default", Rule: "validIng", + Path: "/", Annotations: map[string]string{ "ingress.annotation": "ok", }, @@ -972,10 +1059,15 @@ func TestGetIngressInformation(t *testing.T) { HTTP: &networking.HTTPIngressRuleValue{ Paths: []networking.HTTPIngressPath{ { - Path: "/ok", + Path: "/ok", + PathType: &pathPrefix, Backend: networking.IngressBackend{ - ServiceName: "b-svc", - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: "b-svc", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, }, }, }, @@ -999,6 +1091,56 @@ func TestGetIngressInformation(t *testing.T) { ServicePort: "80", }, }, + "valid ingress definition with name demo in namespace something and path /ok using a service with name b-svc port name b-svc-80": { + &ingress.Ingress{ + Ingress: networking.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: "demo", + Namespace: "something", + Annotations: map[string]string{ + "ingress.annotation": "ok", + }, + }, + Spec: networking.IngressSpec{ + Rules: []networking.IngressRule{ + { + Host: "foo.bar", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/ok", + PathType: &pathPrefix, + Backend: networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "b-svc", + Port: networking.ServiceBackendPort{ + Name: "b-svc-80", + }, + }, + }, + }, + }, + }, + }, + }, + {}, + }, + }, + }, + }, + "foo.bar", + "/ok", + &ingressInformation{ + Namespace: "something", + Rule: "demo", + Annotations: map[string]string{ + "ingress.annotation": "ok", + }, + Service: "b-svc", + ServicePort: "b-svc-80", + }, + }, } for title, testCase := range testcases { @@ -1110,23 +1252,40 @@ func TestBuildCustomErrorLocationsPerServer(t *testing.T) { } func TestProxySetHeader(t *testing.T) { - invalidType := &ingress.Ingress{} - expected := "proxy_set_header" - actual := proxySetHeader(invalidType) - - if expected != actual { - t.Errorf("Expected '%v' but returned '%v'", expected, actual) + tests := []struct { + name string + loc interface{} + expected string + }{ + { + name: "nil", + loc: nil, + expected: "proxy_set_header", + }, + { + name: "invalid type", + loc: &ingress.Ingress{}, + expected: "proxy_set_header", + }, + { + name: "http backend", + loc: &ingress.Location{}, + expected: "proxy_set_header", + }, + { + name: "gRPC backend", + loc: &ingress.Location{ + BackendProtocol: "GRPC", + }, + expected: "grpc_set_header", + }, } - - grpcBackend := &ingress.Location{ - BackendProtocol: "GRPC", - } - - expected = "grpc_set_header" - actual = proxySetHeader(grpcBackend) - - if expected != actual { - t.Errorf("Expected '%v' but returned '%v'", expected, actual) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := proxySetHeader(tt.loc); got != tt.expected { + t.Errorf("proxySetHeader() = %v, expected %v", got, tt.expected) + } + }) } } @@ -1249,7 +1408,8 @@ func TestEnforceRegexModifier(t *testing.T) { Target: "/alright", UseRegex: true, }, - Path: "/ok", + Path: "/ok", + PathType: &pathPrefix, }, } expected = true @@ -1576,3 +1736,34 @@ func TestConvertGoSliceIntoLuaTablet(t *testing.T) { } } } + +func TestCleanConf(t *testing.T) { + testDataDir, err := getTestDataDir() + if err != nil { + t.Error("unexpected error reading conf file: ", err) + } + actual := &bytes.Buffer{} + { + data, err := ioutil.ReadFile(testDataDir + "/cleanConf.src.conf") + if err != nil { + t.Error("unexpected error reading conf file: ", err) + } + in := bytes.NewBuffer(data) + err = cleanConf(in, actual) + if err != nil { + t.Error("cleanConf failed: ", err) + } + } + + expected, err := ioutil.ReadFile(testDataDir + "/cleanConf.expected.conf") + if err != nil { + t.Error("unexpected error reading conf file: ", err) + } + if !bytes.Equal(expected, actual.Bytes()) { + diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{A: strings.SplitAfter(string(expected), "\n"), B: strings.SplitAfter(actual.String(), "\n"), Context: 3}) + if err != nil { + t.Error("failed to get diff for cleanConf", err) + } + t.Errorf("cleanConf result don't match with expected: %s", diff) + } +} diff --git a/internal/ingress/controller/util.go b/internal/ingress/controller/util.go index 5946cb47c..766f07b38 100644 --- a/internal/ingress/controller/util.go +++ b/internal/ingress/controller/util.go @@ -27,6 +27,7 @@ import ( "syscall" api "k8s.io/api/core/v1" + networking "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress" "k8s.io/klog/v2" @@ -47,8 +48,30 @@ func newUpstream(name string) *ingress.Backend { } // upstreamName returns a formatted upstream name based on namespace, service, and port -func upstreamName(namespace string, service string, port intstr.IntOrString) string { - return fmt.Sprintf("%v-%v-%v", namespace, service, port.String()) +func upstreamName(namespace string, service *networking.IngressServiceBackend) string { + if service != nil { + if service.Port.Number > 0 { + return fmt.Sprintf("%s-%s-%d", namespace, service.Name, service.Port.Number) + } + if service.Port.Name != "" { + return fmt.Sprintf("%s-%s-%s", namespace, service.Name, service.Port.Name) + } + } + return fmt.Sprintf("%s-INVALID", namespace) +} + +// upstreamServiceNameAndPort verifies if service is not nil, and then return the +// correct serviceName and Port +func upstreamServiceNameAndPort(service *networking.IngressServiceBackend) (string, intstr.IntOrString) { + if service != nil { + if service.Port.Number > 0 { + return service.Name, intstr.FromInt(int(service.Port.Number)) + } + if service.Port.Name != "" { + return service.Name, intstr.FromString(service.Port.Name) + } + } + return "", intstr.IntOrString{} } // sysctlSomaxconn returns the maximum number of connections that can be queued diff --git a/internal/ingress/metric/main.go b/internal/ingress/metric/main.go index d85e1c979..64810dd36 100644 --- a/internal/ingress/metric/main.go +++ b/internal/ingress/metric/main.go @@ -26,7 +26,6 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/ingress-nginx/internal/ingress" - "k8s.io/ingress-nginx/internal/ingress/annotations/class" "k8s.io/ingress-nginx/internal/ingress/metric/collectors" ) @@ -66,7 +65,7 @@ type collector struct { } // NewCollector creates a new metric collector the for ingress controller -func NewCollector(metricsPerHost bool, registry *prometheus.Registry) (Collector, error) { +func NewCollector(metricsPerHost bool, registry *prometheus.Registry, ingressclass string) (Collector, error) { podNamespace := os.Getenv("POD_NAMESPACE") if podNamespace == "" { podNamespace = "default" @@ -74,22 +73,22 @@ func NewCollector(metricsPerHost bool, registry *prometheus.Registry) (Collector podName := os.Getenv("POD_NAME") - nc, err := collectors.NewNGINXStatus(podName, podNamespace, class.IngressClass) + nc, err := collectors.NewNGINXStatus(podName, podNamespace, ingressclass) if err != nil { return nil, err } - pc, err := collectors.NewNGINXProcess(podName, podNamespace, class.IngressClass) + pc, err := collectors.NewNGINXProcess(podName, podNamespace, ingressclass) if err != nil { return nil, err } - s, err := collectors.NewSocketCollector(podName, podNamespace, class.IngressClass, metricsPerHost) + s, err := collectors.NewSocketCollector(podName, podNamespace, ingressclass, metricsPerHost) if err != nil { return nil, err } - ic := collectors.NewController(podName, podNamespace, class.IngressClass) + ic := collectors.NewController(podName, podNamespace, ingressclass) return Collector(&collector{ nginxStatus: nc, diff --git a/internal/ingress/status/status.go b/internal/ingress/status/status.go index 506ae398c..cabc6b3a2 100644 --- a/internal/ingress/status/status.go +++ b/internal/ingress/status/status.go @@ -275,7 +275,7 @@ func runUpdate(ing *ingress.Ingress, status []apiv1.LoadBalancerIngress, return nil, nil } - ingClient := client.NetworkingV1beta1().Ingresses(ing.Namespace) + ingClient := client.NetworkingV1().Ingresses(ing.Namespace) currIng, err := ingClient.Get(context.TODO(), ing.Name, metav1.GetOptions{}) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("unexpected error searching Ingress %v/%v", ing.Namespace, ing.Name)) diff --git a/internal/ingress/status/status_test.go b/internal/ingress/status/status_test.go index 9ad0c29cf..79bb85891 100644 --- a/internal/ingress/status/status_test.go +++ b/internal/ingress/status/status_test.go @@ -24,12 +24,12 @@ import ( "time" apiv1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" testclient "k8s.io/client-go/kubernetes/fake" "k8s.io/ingress-nginx/internal/ingress" - "k8s.io/ingress-nginx/internal/ingress/annotations/class" + "k8s.io/ingress-nginx/internal/ingress/controller/ingressclass" "k8s.io/ingress-nginx/internal/k8s" "k8s.io/ingress-nginx/internal/task" ) @@ -214,7 +214,7 @@ func buildExtensionsIngresses() []networking.Ingress { Name: "foo_ingress_different_class", Namespace: metav1.NamespaceDefault, Annotations: map[string]string{ - class.IngressKey: "no-nginx", + ingressclass.IngressKey: "no-nginx", }, }, Status: networking.IngressStatus{ @@ -328,7 +328,7 @@ func TestStatusActions(t *testing.T) { newIPs := []apiv1.LoadBalancerIngress{{ IP: "11.0.0.2", }} - fooIngress1, err1 := fk.Client.NetworkingV1beta1().Ingresses(apiv1.NamespaceDefault).Get(context.TODO(), "foo_ingress_1", metav1.GetOptions{}) + fooIngress1, err1 := fk.Client.NetworkingV1().Ingresses(apiv1.NamespaceDefault).Get(context.TODO(), "foo_ingress_1", metav1.GetOptions{}) if err1 != nil { t.Fatalf("unexpected error") } @@ -343,7 +343,7 @@ func TestStatusActions(t *testing.T) { fk.Shutdown() // ingress should be empty newIPs2 := []apiv1.LoadBalancerIngress{} - fooIngress2, err2 := fk.Client.NetworkingV1beta1().Ingresses(apiv1.NamespaceDefault).Get(context.TODO(), "foo_ingress_1", metav1.GetOptions{}) + fooIngress2, err2 := fk.Client.NetworkingV1().Ingresses(apiv1.NamespaceDefault).Get(context.TODO(), "foo_ingress_1", metav1.GetOptions{}) if err2 != nil { t.Fatalf("unexpected error") } @@ -352,7 +352,7 @@ func TestStatusActions(t *testing.T) { t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, newIPs2) } - oic, err := fk.Client.NetworkingV1beta1().Ingresses(metav1.NamespaceDefault).Get(context.TODO(), "foo_ingress_different_class", metav1.GetOptions{}) + oic, err := fk.Client.NetworkingV1().Ingresses(metav1.NamespaceDefault).Get(context.TODO(), "foo_ingress_different_class", metav1.GetOptions{}) if err != nil { t.Fatalf("unexpected error") } diff --git a/internal/ingress/types.go b/internal/ingress/types.go index 84d964b7a..a1cbdf685 100644 --- a/internal/ingress/types.go +++ b/internal/ingress/types.go @@ -18,7 +18,7 @@ package ingress import ( apiv1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/internal/ingress/annotations" diff --git a/internal/k8s/main.go b/internal/k8s/main.go index 364d7c8ec..1487e892a 100644 --- a/internal/k8s/main.go +++ b/internal/k8s/main.go @@ -25,7 +25,7 @@ import ( "k8s.io/klog/v2" apiv1 "k8s.io/api/core/v1" - networkingv1beta1 "k8s.io/api/networking/v1beta1" + networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/version" clientset "k8s.io/client-go/kubernetes" @@ -121,46 +121,37 @@ func MetaNamespaceKey(obj interface{}) string { return key } -// IsIngressV1Beta1Ready indicates if the running Kubernetes version is at least v1.18.0 -var IsIngressV1Beta1Ready bool - // IsIngressV1Ready indicates if the running Kubernetes version is at least v1.19.0 var IsIngressV1Ready bool -// IngressClass indicates the class of the Ingress to use as filter -var IngressClass *networkingv1beta1.IngressClass - // IngressNGINXController defines the valid value of IngressClass // Controller field for ingress-nginx const IngressNGINXController = "k8s.io/ingress-nginx" -// NetworkingIngressAvailable checks if the package "k8s.io/api/networking/v1beta1" -// is available or not and if Ingress V1 is supported (k8s >= v1.18.0) -func NetworkingIngressAvailable(client clientset.Interface) (bool, bool, bool) { - // check kubernetes version to use new ingress package or not - version114, _ := version.ParseGeneric("v1.14.0") - version118, _ := version.ParseGeneric("v1.18.0") +// NetworkingIngressAvailable checks if the package "k8s.io/api/networking/v1" +// is available or not and if Ingress V1 is supported (k8s >= v1.19.0) +func NetworkingIngressAvailable(client clientset.Interface) bool { version119, _ := version.ParseGeneric("v1.19.0") serverVersion, err := client.Discovery().ServerVersion() if err != nil { - return false, false, false + return false } runningVersion, err := version.ParseGeneric(serverVersion.String()) if err != nil { klog.ErrorS(err, "unexpected error parsing running Kubernetes version") - return false, false, false + return false } - return runningVersion.AtLeast(version114), runningVersion.AtLeast(version118), runningVersion.AtLeast(version119) + return runningVersion.AtLeast(version119) } // default path type is Prefix to not break existing definitions -var defaultPathType = networkingv1beta1.PathTypePrefix +var defaultPathType = networkingv1.PathTypePrefix // SetDefaultNGINXPathType sets a default PathType when is not defined. -func SetDefaultNGINXPathType(ing *networkingv1beta1.Ingress) { +func SetDefaultNGINXPathType(ing *networkingv1.Ingress) { for _, rule := range ing.Spec.Rules { if rule.IngressRuleValue.HTTP == nil { continue @@ -172,7 +163,7 @@ func SetDefaultNGINXPathType(ing *networkingv1beta1.Ingress) { p.PathType = &defaultPathType } - if *p.PathType == networkingv1beta1.PathTypeImplementationSpecific { + if *p.PathType == networkingv1.PathTypeImplementationSpecific { p.PathType = &defaultPathType } } diff --git a/internal/net/net.go b/internal/net/net.go index b7fefb8b3..712262f3a 100644 --- a/internal/net/net.go +++ b/internal/net/net.go @@ -29,12 +29,12 @@ func IsIPV6(ip _net.IP) bool { // IsPortAvailable checks if a TCP port is available or not func IsPortAvailable(p int) bool { - conn, err := _net.Dial("tcp", fmt.Sprintf(":%v", p)) + ln, err := _net.Listen("tcp", fmt.Sprintf(":%v", p)) if err != nil { - return true + return false } - defer conn.Close() - return false + defer ln.Close() + return true } // IsIPv6Enabled checks if IPV6 is enabled or not and we have diff --git a/internal/nginx/maxmind.go b/internal/nginx/maxmind.go index 0f3c37016..df9fd2231 100644 --- a/internal/nginx/maxmind.go +++ b/internal/nginx/maxmind.go @@ -21,10 +21,17 @@ import ( "compress/gzip" "fmt" "io" + "net" "net/http" + "net/url" "os" "path" "strings" + "syscall" + "time" + + "k8s.io/apimachinery/pkg/util/wait" + klog "k8s.io/klog/v2" ) // MaxmindLicenseKey maxmind license key to download databases @@ -39,6 +46,15 @@ var MaxmindEditionFiles []string // MaxmindMirror maxmind database mirror url (http://geoip.local) var MaxmindMirror = "" +// MaxmindRetriesCount number of attempts to download the GeoIP DB +var MaxmindRetriesCount = 1 + +// MaxmindRetriesTimeout maxmind download retries timeout in seconds, 0 - do not retry to download if something went wrong +var MaxmindRetriesTimeout = time.Second * 0 + +// minimumRetriesCount minimum value of the MaxmindRetriesCount parameter. If MaxmindRetriesCount less than minimumRetriesCount, it will be set to minimumRetriesCount +const minimumRetriesCount = 1 + const ( geoIPPath = "/etc/nginx/geoip" dbExtension = ".mmdb" @@ -48,27 +64,71 @@ const ( // GeoLite2DBExists checks if the required databases for // the GeoIP2 NGINX module are present in the filesystem +// and indexes the discovered databases for iteration in +// the config. func GeoLite2DBExists() bool { + files := []string{} for _, dbName := range strings.Split(MaxmindEditionIDs, ",") { - if !fileExists(path.Join(geoIPPath, dbName+dbExtension)) { + filename := dbName + dbExtension + if !fileExists(path.Join(geoIPPath, filename)) { + klog.Error(filename, " not found") return false } + files = append(files, filename) } + MaxmindEditionFiles = files return true } // DownloadGeoLite2DB downloads the required databases by the // GeoIP2 NGINX module using a license key from MaxMind. -func DownloadGeoLite2DB() error { - for _, dbName := range strings.Split(MaxmindEditionIDs, ",") { - err := downloadDatabase(dbName) - if err != nil { - return err - } - MaxmindEditionFiles = append(MaxmindEditionFiles, dbName+dbExtension) +func DownloadGeoLite2DB(attempts int, period time.Duration) error { + if attempts < minimumRetriesCount { + attempts = minimumRetriesCount } - return nil + + defaultRetry := wait.Backoff{ + Steps: attempts, + Duration: period, + Factor: 1.5, + Jitter: 0.1, + } + if period == time.Duration(0) { + defaultRetry.Steps = minimumRetriesCount + } + + var lastErr error + retries := 0 + + _ = wait.ExponentialBackoff(defaultRetry, func() (bool, error) { + var dlError error + for _, dbName := range strings.Split(MaxmindEditionIDs, ",") { + dlError = downloadDatabase(dbName) + if dlError != nil { + break + } + } + + lastErr = dlError + if dlError == nil { + return true, nil + } + + if e, ok := dlError.(*url.Error); ok { + if e, ok := e.Err.(*net.OpError); ok { + if e, ok := e.Err.(*os.SyscallError); ok { + if e.Err == syscall.ECONNREFUSED { + retries++ + klog.InfoS("download failed on attempt " + fmt.Sprint(retries)) + return false, nil + } + } + } + } + return true, nil + }) + return lastErr } func createURL(mirror, licenseKey, dbName string) string { @@ -163,7 +223,7 @@ func ValidateGeoLite2DBEditions() error { return nil } -func fileExists(filePath string) bool { +func _fileExists(filePath string) bool { info, err := os.Stat(filePath) if os.IsNotExist(err) { return false @@ -171,3 +231,5 @@ func fileExists(filePath string) bool { return !info.IsDir() } + +var fileExists = _fileExists diff --git a/internal/nginx/maxmind_test.go b/internal/nginx/maxmind_test.go new file mode 100644 index 000000000..ed78c32a1 --- /dev/null +++ b/internal/nginx/maxmind_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2020 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 ( + "reflect" + "testing" +) + +func resetForTesting() { + fileExists = _fileExists + MaxmindLicenseKey = "" + MaxmindEditionIDs = "" + MaxmindEditionFiles = []string{} + MaxmindMirror = "" +} + +func TestGeoLite2DBExists(t *testing.T) { + tests := []struct { + name string + setup func() + want bool + wantFiles []string + }{ + { + name: "empty", + wantFiles: []string{}, + }, + { + name: "existing files", + setup: func() { + MaxmindEditionIDs = "GeoLite2-City,GeoLite2-ASN" + fileExists = func(string) bool { + return true + } + }, + want: true, + wantFiles: []string{"GeoLite2-City.mmdb", "GeoLite2-ASN.mmdb"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resetForTesting() + // mimics assignment in flags.go + config := &MaxmindEditionFiles + + if tt.setup != nil { + tt.setup() + } + if got := GeoLite2DBExists(); got != tt.want { + t.Errorf("GeoLite2DBExists() = %v, want %v", got, tt.want) + } + if !reflect.DeepEqual(MaxmindEditionFiles, tt.wantFiles) { + t.Errorf("nginx.MaxmindEditionFiles = %v, want %v", MaxmindEditionFiles, tt.wantFiles) + } + if !reflect.DeepEqual(*config, tt.wantFiles) { + t.Errorf("config.MaxmindEditionFiles = %v, want %v", *config, tt.wantFiles) + } + }) + } +} diff --git a/rootfs/Dockerfile b/rootfs/Dockerfile index 49abbdac2..7fc8cfee3 100644 --- a/rootfs/Dockerfile +++ b/rootfs/Dockerfile @@ -40,7 +40,6 @@ RUN apk update \ && rm -rf /var/cache/apk/* COPY --chown=www-data:www-data etc /etc -COPY --chown=www-data:www-data ingress-controller /ingress-controller COPY --chown=www-data:www-data bin/${TARGETARCH}/dbg / COPY --chown=www-data:www-data bin/${TARGETARCH}/nginx-ingress-controller / diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index a18922895..4bb5fe18c 100755 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -149,14 +149,16 @@ http { {{ if $all.Cfg.EnableModsecurity }} modsecurity on; + {{ if (not (empty $all.Cfg.ModsecuritySnippet)) }} + modsecurity_rules ' + {{ $all.Cfg.ModsecuritySnippet }} + '; + {{ end }} + modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf; {{ if $all.Cfg.EnableOWASPCoreRules }} modsecurity_rules_file /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf; - {{ else if (not (empty $all.Cfg.ModsecuritySnippet)) }} - modsecurity_rules ' - {{ $all.Cfg.ModsecuritySnippet }} - '; {{ end }} {{ end }} @@ -1176,7 +1178,7 @@ stream { auth_request {{ $authPath }}; auth_request_set $auth_cookie $upstream_http_set_cookie; add_header Set-Cookie $auth_cookie; - {{- range $line := buildAuthResponseHeaders $externalAuth.ResponseHeaders }} + {{- range $line := buildAuthResponseHeaders $proxySetHeader $externalAuth.ResponseHeaders }} {{ $line }} {{- end }} {{ end }} @@ -1194,7 +1196,7 @@ stream { auth_digest {{ $location.BasicDigestAuth.Realm | quote }}; auth_digest_user_file {{ $location.BasicDigestAuth.File }}; {{ end }} - proxy_set_header Authorization ""; + {{ $proxySetHeader }} Authorization ""; {{ end }} {{ end }} diff --git a/rootfs/ingress-controller/clean-nginx-conf.sh b/rootfs/ingress-controller/clean-nginx-conf.sh deleted file mode 100755 index 07900981e..000000000 --- a/rootfs/ingress-controller/clean-nginx-conf.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# Copyright 2017 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This script removes consecutive empty lines in nginx.conf -# Using sed is more simple than using a go regex - -# Sed commands: -# 1. remove the return carrier character/s -# 2. remove empty lines -# 3. replace multiple empty lines - -SCRIPT_ROOT=$(dirname ${BASH_SOURCE}) - -sed -e 's/\r//g' | sed -e 's/^ *$/\'$'\n/g' | sed -e '/^$/{N;/^\n$/D;}' | ${SCRIPT_ROOT}/indent.sh diff --git a/rootfs/ingress-controller/indent.sh b/rootfs/ingress-controller/indent.sh deleted file mode 100755 index 83c0f0005..000000000 --- a/rootfs/ingress-controller/indent.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/awk -f - -# Copyright 2017 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Credits to https://evasive.ru/f29bd7ebacf24a50c582f973a55eee28.html - -{sub(/^[ \t]+/,"");idx=0} -/\{/{ctx++;idx=1} -/\}/{ctx--} -{id="";for(i=idx;i /dev/null; then echo "kind is not installed. Use the package manager or visit the official site https://kind.sigs.k8s.io/" exit 1 @@ -43,14 +45,17 @@ fi DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -export KIND_CLUSTER_NAME=${KIND_CLUSTER_NAME:-ingress-nginx-dev} +# Use 1.0.0-dev to make sure we use the latest configuration in the helm template +export TAG=1.0.0-dev +export ARCH=${ARCH:-amd64} +export REGISTRY=ingress-controller 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.20.2@sha256:8f7ea6e7642c0da54f04a7ee10431549c0257315b3a634f6ef2fecaaedb19bab} + export K8S_VERSION=${K8S_VERSION:-v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6} kind create cluster \ --verbosity=${KIND_LOG_LEVEL} \ @@ -61,8 +66,23 @@ if [ "${SKIP_CLUSTER_CREATION:-false}" = "false" ]; then echo "Kubernetes cluster:" kubectl get nodes -o wide + fi +if [ "${SKIP_IMAGE_CREATION:-false}" = "false" ]; then + if ! command -v ginkgo &> /dev/null; then + go get github.com/onsi/ginkgo/ginkgo@v1.16.4 + fi + echo "[dev-env] building image" + make -C ${DIR}/../../ clean-image build image +fi + + +KIND_WORKERS=$(kind get nodes --name="${KIND_CLUSTER_NAME}" | awk '{printf (NR>1?",":"") $1}') +echo "[dev-env] copying docker images to cluster..." + +kind load docker-image --name="${KIND_CLUSTER_NAME}" --nodes=${KIND_WORKERS} ${REGISTRY}/controller:${TAG} + echo "[dev-env] running helm chart e2e tests..." # Uses a custom chart-testing image to avoid timeouts waiting for namespace deletion. # The changes can be found here: https://github.com/aledbf/chart-testing/commit/41fe0ae0733d0c9a538099fb3cec522e888e3d82 diff --git a/test/e2e/run.sh b/test/e2e/run.sh index d3caf2537..bfe13b428 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.20.2@sha256:8f7ea6e7642c0da54f04a7ee10431549c0257315b3a634f6ef2fecaaedb19bab} + export K8S_VERSION=${K8S_VERSION:-v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6} kind create cluster \ --verbosity=${KIND_LOG_LEVEL} \ @@ -73,7 +73,7 @@ fi if [ "${SKIP_IMAGE_CREATION:-false}" = "false" ]; then if ! command -v ginkgo &> /dev/null; then - go get github.com/onsi/ginkgo/ginkgo + go get github.com/onsi/ginkgo/ginkgo@v1.16.4 fi echo "[dev-env] building image" diff --git a/test/e2e/servicebackend/service_backend.go b/test/e2e/servicebackend/service_backend.go index 86f39b842..0467e434e 100644 --- a/test/e2e/servicebackend/service_backend.go +++ b/test/e2e/servicebackend/service_backend.go @@ -22,13 +22,14 @@ import ( "github.com/onsi/ginkgo" corev1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/test/e2e/framework" ) +var pathtype = networking.PathTypePrefix var _ = framework.IngressNginxDescribe("[Service] backend status code 503", func() { f := framework.NewDefaultFramework("service-backend") @@ -79,6 +80,7 @@ func buildIngressWithNonexistentService(host, namespace, path string) *networkin Namespace: namespace, }, Spec: networking.IngressSpec{ + IngressClassName: framework.GetIngressClassName(namespace), Rules: []networking.IngressRule{ { Host: host, @@ -86,10 +88,15 @@ func buildIngressWithNonexistentService(host, namespace, path string) *networkin HTTP: &networking.HTTPIngressRuleValue{ Paths: []networking.HTTPIngressPath{ { - Path: path, + Path: path, + PathType: &pathtype, Backend: networking.IngressBackend{ - ServiceName: backendService, - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: backendService, + Port: networking.ServiceBackendPort{ + Number: int32(80), + }, + }, }, }, }, @@ -109,6 +116,7 @@ func buildIngressWithUnavailableServiceEndpoints(host, namespace, path string) ( Namespace: namespace, }, Spec: networking.IngressSpec{ + IngressClassName: framework.GetIngressClassName(namespace), Rules: []networking.IngressRule{ { Host: host, @@ -116,10 +124,15 @@ func buildIngressWithUnavailableServiceEndpoints(host, namespace, path string) ( HTTP: &networking.HTTPIngressRuleValue{ Paths: []networking.HTTPIngressPath{ { - Path: path, + Path: path, + PathType: &pathtype, Backend: networking.IngressBackend{ - ServiceName: backendService, - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: backendService, + Port: networking.ServiceBackendPort{ + Number: int32(80), + }, + }, }, }, }, diff --git a/test/e2e/servicebackend/service_externalname.go b/test/e2e/servicebackend/service_externalname.go index bd10519e7..2c33c020f 100644 --- a/test/e2e/servicebackend/service_externalname.go +++ b/test/e2e/servicebackend/service_externalname.go @@ -25,8 +25,8 @@ import ( "github.com/gavv/httpexpect/v2" "github.com/onsi/ginkgo" "github.com/stretchr/testify/assert" - core "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -42,7 +42,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { host := "echo" - svc := &core.Service{ + svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: framework.HTTPBinService, Namespace: f.Namespace, @@ -73,7 +73,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { ginkgo.It("should return 200 for service type=ExternalName without a port defined", func() { host := "echo" - svc := &core.Service{ + svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: framework.HTTPBinService, Namespace: f.Namespace, @@ -107,7 +107,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { ginkgo.It("should return 200 for service type=ExternalName with a port defined", func() { host := "echo" - svc := &core.Service{ + svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: framework.HTTPBinService, Namespace: f.Namespace, @@ -148,7 +148,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { ginkgo.It("should return status 502 for service type=ExternalName with an invalid host", func() { host := "echo" - svc := &core.Service{ + svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: framework.HTTPBinService, Namespace: f.Namespace, @@ -179,7 +179,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { ginkgo.It("should return 200 for service type=ExternalName using a port name", func() { host := "echo" - svc := &core.Service{ + svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: framework.HTTPBinService, Namespace: f.Namespace, @@ -203,7 +203,15 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { "nginx.ingress.kubernetes.io/upstream-vhost": "httpbin.org", } ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, annotations) - ing.Spec.Rules[0].HTTP.Paths[0].Backend.ServicePort = intstr.FromString(host) + namedBackend := networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: framework.HTTPBinService, + Port: networking.ServiceBackendPort{ + Name: host, + }, + }, + } + ing.Spec.Rules[0].HTTP.Paths[0].Backend = namedBackend f.EnsureIngress(ing) f.WaitForNginxServer(host, @@ -221,7 +229,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { ginkgo.It("should return 200 for service type=ExternalName using FQDN with trailing dot", func() { host := "echo" - svc := &core.Service{ + svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: framework.HTTPBinService, Namespace: f.Namespace, @@ -252,7 +260,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { ginkgo.It("should update the external name after a service update", func() { host := "echo" - svc := &core.Service{ + svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: framework.HTTPBinService, Namespace: f.Namespace, @@ -276,7 +284,15 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { "nginx.ingress.kubernetes.io/upstream-vhost": "httpbin.org", } ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, annotations) - ing.Spec.Rules[0].HTTP.Paths[0].Backend.ServicePort = intstr.FromString(host) + namedBackend := networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: framework.HTTPBinService, + Port: networking.ServiceBackendPort{ + Name: host, + }, + }, + } + ing.Spec.Rules[0].HTTP.Paths[0].Backend = namedBackend f.EnsureIngress(ing) f.WaitForNginxServer(host, diff --git a/test/e2e/settings/disable_catch_all.go b/test/e2e/settings/disable_catch_all.go index 1a8791d80..f5d9bfadc 100644 --- a/test/e2e/settings/disable_catch_all.go +++ b/test/e2e/settings/disable_catch_all.go @@ -24,9 +24,8 @@ import ( "github.com/onsi/ginkgo" "github.com/stretchr/testify/assert" appsv1 "k8s.io/api/apps/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/test/e2e/framework" ) @@ -98,9 +97,13 @@ var _ = framework.IngressNginxDescribe("[Flag] disable-catch-all", func() { err := framework.UpdateIngress(f.KubeClientSet, f.Namespace, host, func(ingress *networking.Ingress) error { ingress.Spec.Rules = nil - ingress.Spec.Backend = &networking.IngressBackend{ - ServiceName: framework.EchoService, - ServicePort: intstr.FromInt(80), + ingress.Spec.DefaultBackend = &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: framework.EchoService, + Port: networking.ServiceBackendPort{ + Number: int32(80), + }, + }, } return nil }) diff --git a/test/e2e/settings/disable_service_external_name.go b/test/e2e/settings/disable_service_external_name.go new file mode 100644 index 000000000..910a906ca --- /dev/null +++ b/test/e2e/settings/disable_service_external_name.go @@ -0,0 +1,95 @@ +/* +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. +*/ + +package settings + +import ( + "context" + "net/http" + "strings" + + "github.com/gavv/httpexpect/v2" + "github.com/onsi/ginkgo" + "github.com/stretchr/testify/assert" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "k8s.io/ingress-nginx/test/e2e/framework" +) + +var _ = framework.IngressNginxDescribe("[Flag] disable-service-external-name", func() { + f := framework.NewDefaultFramework("disabled-service-external-name") + + ginkgo.BeforeEach(func() { + f.NewEchoDeploymentWithReplicas(2) + + err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { + args := deployment.Spec.Template.Spec.Containers[0].Args + args = append(args, "--disable-svc-external-name=true") + deployment.Spec.Template.Spec.Containers[0].Args = args + _, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{}) + + return err + }) + assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags") + }) + + ginkgo.It("should ignore services of external-name type", func() { + + nonexternalhost := "echo-svc.com" + + externalhost := "echo-external-svc.com" + svcexternal := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "external", + Namespace: f.Namespace, + }, + Spec: corev1.ServiceSpec{ + ExternalName: "httpbin.org", + Type: corev1.ServiceTypeExternalName, + }, + } + f.EnsureService(svcexternal) + + ingexternal := framework.NewSingleIngress(externalhost, "/", externalhost, f.Namespace, "external", 80, nil) + f.EnsureIngress(ingexternal) + + ing := framework.NewSingleIngress(nonexternalhost, "/", nonexternalhost, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing) + + f.WaitForNginxServer(nonexternalhost, func(cfg string) bool { + return strings.Contains(cfg, "server_name echo-svc.com") + }) + + f.WaitForNginxServer(externalhost, func(cfg string) bool { + return strings.Contains(cfg, "server_name echo-external-svc.com") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", nonexternalhost). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", externalhost). + Expect(). + StatusRange(httpexpect.Status5xx) + + }) +}) diff --git a/test/e2e/settings/geoip2.go b/test/e2e/settings/geoip2.go index 37f99f216..cec35f459 100644 --- a/test/e2e/settings/geoip2.go +++ b/test/e2e/settings/geoip2.go @@ -17,15 +17,23 @@ limitations under the License. package settings import ( + "context" + "fmt" + "path/filepath" "strings" "net/http" "github.com/onsi/ginkgo" + "github.com/stretchr/testify/assert" + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/test/e2e/framework" ) +const testdataURL = "https://github.com/maxmind/MaxMind-DB/blob/5a0be1c0320490b8e4379dbd5295a18a648ff156/test-data/GeoLite2-Country-Test.mmdb?raw=true" + var _ = framework.DescribeSetting("Geoip2", func() { f := framework.NewDefaultFramework("geoip2") @@ -35,6 +43,30 @@ var _ = framework.DescribeSetting("Geoip2", func() { f.NewEchoDeployment() }) + ginkgo.It("should include geoip2 line in config when enabled and db file exists", func() { + edition := "GeoLite2-Country" + + err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { + args := deployment.Spec.Template.Spec.Containers[0].Args + args = append(args, "--maxmind-edition-ids="+edition) + deployment.Spec.Template.Spec.Containers[0].Args = args + _, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{}) + return err + }) + assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags") + + filename := fmt.Sprintf("/etc/nginx/geoip/%s.mmdb", edition) + exec, err := f.ExecIngressPod(fmt.Sprintf(`sh -c "mkdir -p '%s' && wget -O '%s' '%s' 2>&1"`, filepath.Dir(filename), filename, testdataURL)) + framework.Logf(exec) + assert.Nil(ginkgo.GinkgoT(), err, fmt.Sprintln("error downloading test geoip2 db", filename)) + + f.UpdateNginxConfigMapData("use-geoip2", "true") + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, fmt.Sprintf("geoip2 %s", filename)) + }) + }) + ginkgo.It("should only allow requests from specific countries", func() { ginkgo.Skip("GeoIP test are temporarily disabled") diff --git a/test/e2e/settings/global_external_auth.go b/test/e2e/settings/global_external_auth.go old mode 100755 new mode 100644 index 7960b6ca7..1e5bf4301 --- a/test/e2e/settings/global_external_auth.go +++ b/test/e2e/settings/global_external_auth.go @@ -25,7 +25,7 @@ import ( "github.com/onsi/ginkgo" "github.com/stretchr/testify/assert" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" "k8s.io/ingress-nginx/test/e2e/framework" ) diff --git a/test/e2e/settings/global_options.go b/test/e2e/settings/global_options.go new file mode 100644 index 000000000..ef0487cc5 --- /dev/null +++ b/test/e2e/settings/global_options.go @@ -0,0 +1,58 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package settings + +import ( + "fmt" + "strings" + "syscall" + + "github.com/onsi/ginkgo" + "k8s.io/ingress-nginx/test/e2e/framework" +) + +var _ = framework.IngressNginxDescribe("global-options", func() { + f := framework.NewDefaultFramework("global-options") + + ginkgo.It("should have worker_rlimit_nofile option", func() { + f.WaitForNginxConfiguration(func(server string) bool { + return strings.Contains(server, fmt.Sprintf("worker_rlimit_nofile %d;", rlimitMaxNumFiles()-1024)) + + }) + }) + + ginkgo.It("should have worker_rlimit_nofile option and be independent on amount of worker processes", func() { + f.SetNginxConfigMapData(map[string]string{ + "worker-processes": "11", + }) + + f.WaitForNginxConfiguration(func(server string) bool { + return strings.Contains(server, "worker_processes 11;") && + strings.Contains(server, fmt.Sprintf("worker_rlimit_nofile %d;", rlimitMaxNumFiles()-1024)) + }) + }) +}) + +// rlimitMaxNumFiles returns hard limit for RLIMIT_NOFILE +func rlimitMaxNumFiles() int { + var rLimit syscall.Rlimit + err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) + if err != nil { + return 0 + } + return int(rLimit.Max) +} diff --git a/test/e2e/settings/ingress_class.go b/test/e2e/settings/ingress_class.go index 1fa02183f..3ba42f311 100644 --- a/test/e2e/settings/ingress_class.go +++ b/test/e2e/settings/ingress_class.go @@ -18,7 +18,6 @@ package settings import ( "context" - "fmt" "net/http" "strings" "sync" @@ -26,13 +25,11 @@ import ( "github.com/onsi/ginkgo" "github.com/stretchr/testify/assert" appsv1 "k8s.io/api/apps/v1" - networking "k8s.io/api/networking/v1beta1" - rbacv1 "k8s.io/api/rbac/v1" + networkingv1 "k8s.io/api/networking/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/ingress-nginx/internal/ingress/annotations/class" - "k8s.io/ingress-nginx/internal/k8s" + "k8s.io/ingress-nginx/internal/ingress/controller/ingressclass" "k8s.io/ingress-nginx/test/e2e/framework" ) @@ -41,43 +38,20 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() { var doOnce sync.Once - testIngressClassName := "test-new-ingress-class" + otherIngressClassName := "test-new-ingress-class" + otherController := "k8s.io/other-class" ginkgo.BeforeEach(func() { f.NewEchoDeploymentWithReplicas(1) doOnce.Do(func() { - f.KubeClientSet.RbacV1().ClusterRoles().Create(context.TODO(), &rbacv1.ClusterRole{ - ObjectMeta: metav1.ObjectMeta{Name: "ingress-nginx-class"}, - Rules: []rbacv1.PolicyRule{{ - APIGroups: []string{"networking.k8s.io"}, - Resources: []string{"ingressclasses"}, - Verbs: []string{"get", "list", "watch"}, - }}, - }, metav1.CreateOptions{}) - - f.KubeClientSet.RbacV1().ClusterRoleBindings().Create(context.TODO(), &rbacv1.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ingress-nginx-class", - }, - RoleRef: rbacv1.RoleRef{ - APIGroup: "rbac.authorization.k8s.io", - Kind: "ClusterRole", - Name: "ingress-nginx-class", - }, - }, metav1.CreateOptions{}) - - if !f.IsIngressV1Beta1Ready { - return - } - - _, err := f.KubeClientSet.NetworkingV1beta1().IngressClasses(). - Create(context.TODO(), &networking.IngressClass{ + _, err := f.KubeClientSet.NetworkingV1().IngressClasses(). + Create(context.TODO(), &networkingv1.IngressClass{ ObjectMeta: metav1.ObjectMeta{ - Name: testIngressClassName, + Name: otherIngressClassName, }, - Spec: networking.IngressClassSpec{ - Controller: k8s.IngressNGINXController, + Spec: networkingv1.IngressClassSpec{ + Controller: otherController, }, }, metav1.CreateOptions{}) @@ -87,17 +61,23 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() { }) }) - ginkgo.Context("Without a specific ingress-class", func() { - ginkgo.It("should ignore Ingress with class", func() { + ginkgo.Context("With default ingress class config", func() { + ginkgo.It("should ignore Ingress with a different class annotation", func() { invalidHost := "foo" annotations := map[string]string{ - class.IngressKey: "testclass", + ingressclass.IngressKey: "testclass", } ing := framework.NewSingleIngress(invalidHost, "/", invalidHost, f.Namespace, framework.EchoService, 80, annotations) + // We should drop the ingressClassName here as we just want to rely on the annotation in this test + ing.Spec.IngressClassName = nil f.EnsureIngress(ing) validHost := "bar" - ing = framework.NewSingleIngress(validHost, "/", validHost, f.Namespace, framework.EchoService, 80, nil) + annotationClass := map[string]string{ + ingressclass.IngressKey: ingressclass.DefaultAnnotationValue, + } + ing = framework.NewSingleIngress(validHost, "/", validHost, f.Namespace, framework.EchoService, 80, annotationClass) + ing.Spec.IngressClassName = nil f.EnsureIngress(ing) f.WaitForNginxConfiguration(func(cfg string) bool { @@ -117,14 +97,300 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() { Expect(). Status(http.StatusOK) }) + + ginkgo.It("should ignore Ingress with different controller class", func() { + invalidHost := "foo-1" + ing := framework.NewSingleIngress(invalidHost, "/", invalidHost, f.Namespace, framework.EchoService, 80, nil) + ing.Spec.IngressClassName = &otherIngressClassName + f.EnsureIngress(ing) + + validHost := "bar-1" + ing = framework.NewSingleIngress(validHost, "/", validHost, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing) + + f.WaitForNginxConfiguration(func(cfg string) bool { + return !strings.Contains(cfg, "server_name foo-1") && + strings.Contains(cfg, "server_name bar-1") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", invalidHost). + Expect(). + Status(http.StatusNotFound) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", validHost). + Expect(). + Status(http.StatusOK) + }) + + ginkgo.It("should accept both Ingresses with default IngressClassName and IngressClass annotation", func() { + validHostAnnotation := "foo-ok" + annotationClass := map[string]string{ + ingressclass.IngressKey: ingressclass.DefaultAnnotationValue, + } + ing := framework.NewSingleIngress(validHostAnnotation, "/", validHostAnnotation, f.Namespace, framework.EchoService, 80, annotationClass) + // We need to drop the Class here as we just want the annotation + ing.Spec.IngressClassName = nil + f.EnsureIngress(ing) + + validHostClass := "bar-ok" + ing = framework.NewSingleIngress(validHostClass, "/", validHostClass, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing) + + f.WaitForNginxConfiguration(func(cfg string) bool { + return strings.Contains(cfg, "server_name foo-ok") && + strings.Contains(cfg, "server_name bar-ok") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", validHostAnnotation). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", validHostClass). + Expect(). + Status(http.StatusOK) + }) + + ginkgo.It("should ignore Ingress without IngressClass configuration", func() { + invalidHost := "foo-invalid" + ing := framework.NewSingleIngress(invalidHost, "/", invalidHost, f.Namespace, framework.EchoService, 80, nil) + ing.Spec.IngressClassName = nil + f.EnsureIngress(ing) + + validHostClass := "bar-valid" + ing = framework.NewSingleIngress(validHostClass, "/", validHostClass, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing) + + f.WaitForNginxConfiguration(func(cfg string) bool { + return !strings.Contains(cfg, "server_name foo-invalid") && + strings.Contains(cfg, "server_name bar-valid") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", invalidHost). + Expect(). + Status(http.StatusNotFound) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", validHostClass). + Expect(). + Status(http.StatusOK) + }) + + ginkgo.It("should delete Ingress when class is removed", func() { + hostAnnotation := "foo-annotation" + + annotations := map[string]string{ + ingressclass.IngressKey: ingressclass.DefaultAnnotationValue, + } + ing := framework.NewSingleIngress(hostAnnotation, "/", hostAnnotation, f.Namespace, framework.EchoService, 80, annotations) + ing.Spec.IngressClassName = nil + f.EnsureIngress(ing) + + hostClass := "foo-class" + ing = framework.NewSingleIngress(hostClass, "/", hostClass, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing) + + f.WaitForNginxConfiguration(func(cfg string) bool { + return strings.Contains(cfg, "server_name foo-annotation") && + strings.Contains(cfg, "server_name foo-class") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostAnnotation). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostClass). + Expect(). + Status(http.StatusOK) + + ing, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Get(context.TODO(), hostAnnotation, metav1.GetOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + delete(ing.Annotations, ingressclass.IngressKey) + _, err = f.KubeClientSet.NetworkingV1().Ingresses(ing.Namespace).Update(context.TODO(), ing, metav1.UpdateOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + ingWithClass, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Get(context.TODO(), hostClass, metav1.GetOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + ingWithClass.Spec.IngressClassName = nil + _, err = f.KubeClientSet.NetworkingV1().Ingresses(ingWithClass.Namespace).Update(context.TODO(), ingWithClass, metav1.UpdateOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + framework.Sleep() + + f.WaitForNginxConfiguration(func(cfg string) bool { + return !strings.Contains(cfg, "server_name foo-annotation") && + !strings.Contains(cfg, "server_name foo-class") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostAnnotation). + Expect(). + Status(http.StatusNotFound) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostClass). + Expect(). + Status(http.StatusNotFound) + }) + + ginkgo.It("should serve Ingress when class is added", func() { + hostNoAnnotation := "foo-no-annotation" + + ing := framework.NewSingleIngress(hostNoAnnotation, "/", hostNoAnnotation, f.Namespace, framework.EchoService, 80, nil) + ing.Spec.IngressClassName = nil + f.EnsureIngress(ing) + + hostNoClass := "foo-no-class" + ing = framework.NewSingleIngress(hostNoClass, "/", hostNoClass, f.Namespace, framework.EchoService, 80, nil) + ing.Spec.IngressClassName = nil + f.EnsureIngress(ing) + + f.WaitForNginxConfiguration(func(cfg string) bool { + return !strings.Contains(cfg, "server_name foo-no-nnotation") && + !strings.Contains(cfg, "server_name foo-no-class") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostNoAnnotation). + Expect(). + Status(http.StatusNotFound) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostNoClass). + Expect(). + Status(http.StatusNotFound) + + ing, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Get(context.TODO(), hostNoAnnotation, metav1.GetOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + annotation := map[string]string{ + ingressclass.IngressKey: ingressclass.DefaultAnnotationValue, + } + ing.Annotations = annotation + _, err = f.KubeClientSet.NetworkingV1().Ingresses(ing.Namespace).Update(context.TODO(), ing, metav1.UpdateOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + ingWithClass, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Get(context.TODO(), hostNoClass, metav1.GetOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + ingWithClass.Spec.IngressClassName = framework.GetIngressClassName(f.Namespace) + _, err = f.KubeClientSet.NetworkingV1().Ingresses(ingWithClass.Namespace).Update(context.TODO(), ingWithClass, metav1.UpdateOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + framework.Sleep() + + f.WaitForNginxConfiguration(func(cfg string) bool { + return strings.Contains(cfg, "server_name foo-no-annotation") && + strings.Contains(cfg, "server_name foo-no-class") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostNoAnnotation). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostNoClass). + Expect(). + Status(http.StatusOK) + }) + + ginkgo.It("should serve Ingress when class is updated between annotation and ingressClassName", func() { + hostAnnotation2class := "foo-annotation2class" + annotationClass := map[string]string{ + ingressclass.IngressKey: ingressclass.DefaultAnnotationValue, + } + ing := framework.NewSingleIngress(hostAnnotation2class, "/", hostAnnotation2class, f.Namespace, framework.EchoService, 80, annotationClass) + ing.Spec.IngressClassName = nil + f.EnsureIngress(ing) + + hostClass2Annotation := "foo-class2annotation" + ing = framework.NewSingleIngress(hostClass2Annotation, "/", hostClass2Annotation, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing) + + f.WaitForNginxConfiguration(func(cfg string) bool { + return strings.Contains(cfg, "server_name foo-annotation2class") && + strings.Contains(cfg, "server_name foo-class2annotation") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostAnnotation2class). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostClass2Annotation). + Expect(). + Status(http.StatusOK) + + ingAnnotation2Class, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Get(context.TODO(), hostAnnotation2class, metav1.GetOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + delete(ingAnnotation2Class.Annotations, ingressclass.IngressKey) + ingAnnotation2Class.Spec.IngressClassName = framework.GetIngressClassName(ingAnnotation2Class.Namespace) + _, err = f.KubeClientSet.NetworkingV1().Ingresses(ingAnnotation2Class.Namespace).Update(context.TODO(), ingAnnotation2Class, metav1.UpdateOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + ingClass2Annotation, err := f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Get(context.TODO(), hostClass2Annotation, metav1.GetOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + ingClass2Annotation.Spec.IngressClassName = nil + ingClass2Annotation.Annotations = annotationClass + _, err = f.KubeClientSet.NetworkingV1().Ingresses(ingClass2Annotation.Namespace).Update(context.TODO(), ingClass2Annotation, metav1.UpdateOptions{}) + assert.Nil(ginkgo.GinkgoT(), err) + + framework.Sleep() + + f.WaitForNginxConfiguration(func(cfg string) bool { + return strings.Contains(cfg, "server_name foo-annotation2class") && + strings.Contains(cfg, "server_name foo-class2annotation") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostAnnotation2class). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", hostClass2Annotation). + Expect(). + Status(http.StatusOK) + }) + }) - ginkgo.Context("With a specific ingress-class", func() { + ginkgo.Context("With specific ingress-class flags", func() { ginkgo.BeforeEach(func() { err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { args := []string{} for _, v := range deployment.Spec.Template.Spec.Containers[0].Args { - if strings.Contains(v, "--ingress-class") { + if strings.Contains(v, "--ingress-class") && strings.Contains(v, "--controller-class") { continue } @@ -132,6 +398,7 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() { } args = append(args, "--ingress-class=testclass") + args = append(args, "--controller-class=k8s.io/other-class") deployment.Spec.Template.Spec.Containers[0].Args = args _, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{}) @@ -140,25 +407,93 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() { assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags") }) - ginkgo.It("should ignore Ingress with no class", func() { + ginkgo.It("should ignore Ingress with no class and accept the correctly configured Ingresses", func() { invalidHost := "bar" ing := framework.NewSingleIngress(invalidHost, "/", invalidHost, f.Namespace, framework.EchoService, 80, nil) + ing.Spec.IngressClassName = nil f.EnsureIngress(ing) validHost := "foo" annotations := map[string]string{ - class.IngressKey: "testclass", + ingressclass.IngressKey: "testclass", } ing = framework.NewSingleIngress(validHost, "/", validHost, f.Namespace, framework.EchoService, 80, annotations) + // Delete the IngressClass as we want just the annotation here + ing.Spec.IngressClassName = nil f.EnsureIngress(ing) - f.WaitForNginxServer(validHost, func(cfg string) bool { - return strings.Contains(cfg, "server_name foo") - }) + validHostClass := "foobar123" + ing = framework.NewSingleIngress(validHostClass, "/", validHostClass, f.Namespace, framework.EchoService, 80, nil) + ing.Spec.IngressClassName = &otherIngressClassName + f.EnsureIngress(ing) f.WaitForNginxConfiguration(func(cfg string) bool { - return !strings.Contains(cfg, "server_name bar") + return !strings.Contains(cfg, "server_name bar") && + strings.Contains(cfg, "server_name foo") && + strings.Contains(cfg, "server_name foobar123") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", validHost). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", validHostClass). + Expect(). + Status(http.StatusOK) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", invalidHost). + Expect(). + Status(http.StatusNotFound) + }) + + }) + + ginkgo.Context("With watch-ingress-without-class flag", func() { + ginkgo.BeforeEach(func() { + err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { + args := []string{} + for _, v := range deployment.Spec.Template.Spec.Containers[0].Args { + if strings.Contains(v, "--watch-ingress-without-class") && strings.Contains(v, "--controller-class") { + continue + } + + args = append(args, v) + } + + args = append(args, "--watch-ingress-without-class") + deployment.Spec.Template.Spec.Containers[0].Args = args + _, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{}) + + return err + }) + assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags") + }) + + ginkgo.It("should watch Ingress with no class and ignore ingress with a different class", func() { + validHost := "bar" + + ing := framework.NewSingleIngress(validHost, "/", validHost, f.Namespace, framework.EchoService, 80, nil) + ing.Spec.IngressClassName = nil + f.EnsureIngress(ing) + + invalidHost := "foo" + annotations := map[string]string{ + ingressclass.IngressKey: "testclass123", + } + ing = framework.NewSingleIngress(invalidHost, "/", invalidHost, f.Namespace, framework.EchoService, 80, annotations) + ing.Spec.IngressClassName = nil + f.EnsureIngress(ing) + + f.WaitForNginxConfiguration(func(cfg string) bool { + return strings.Contains(cfg, "server_name bar") && + !strings.Contains(cfg, "server_name foo") }) f.HTTPTestClient(). @@ -174,168 +509,5 @@ var _ = framework.IngressNginxDescribe("[Flag] ingress-class", func() { Status(http.StatusNotFound) }) - ginkgo.It("should delete Ingress when class is removed", func() { - host := "foo" - annotations := map[string]string{ - class.IngressKey: "testclass", - } - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) - f.EnsureIngress(ing) - - f.WaitForNginxServer(host, func(cfg string) bool { - return strings.Contains(cfg, "server_name foo") - }) - - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - Expect(). - Status(http.StatusOK) - - ing, err := f.KubeClientSet.NetworkingV1beta1().Ingresses(f.Namespace).Get(context.TODO(), host, metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err) - - delete(ing.Annotations, class.IngressKey) - _, err = f.KubeClientSet.NetworkingV1beta1().Ingresses(ing.Namespace).Update(context.TODO(), ing, metav1.UpdateOptions{}) - assert.Nil(ginkgo.GinkgoT(), err) - - framework.Sleep() - - f.WaitForNginxConfiguration(func(cfg string) bool { - return !strings.Contains(cfg, "server_name foo") - }) - - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - Expect(). - Status(http.StatusNotFound) - }) - }) - - ginkgo.It("check scenarios for IngressClass and ingress.class annotation", func() { - if !f.IsIngressV1Beta1Ready { - ginkgo.Skip("Test requires Kubernetes v1.18 or higher") - } - - pod := f.GetIngressNGINXPod() - - crb, err := f.KubeClientSet.RbacV1().ClusterRoleBindings().Get(context.Background(), "ingress-nginx-class", metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "searching cluster role binding") - - // add service of current namespace - crb.Subjects = append(crb.Subjects, rbacv1.Subject{ - APIGroup: "", - Kind: "ServiceAccount", - Name: pod.Spec.ServiceAccountName, - Namespace: f.Namespace, - }) - - _, err = f.KubeClientSet.RbacV1().ClusterRoleBindings().Update(context.Background(), crb, metav1.UpdateOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "searching cluster role binding") - - err = f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { - args := []string{} - for _, v := range deployment.Spec.Template.Spec.Containers[0].Args { - if strings.Contains(v, "--ingress-class") { - continue - } - - args = append(args, v) - } - - args = append(args, fmt.Sprintf("--ingress-class=%v", testIngressClassName)) - deployment.Spec.Template.Spec.Containers[0].Args = args - _, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{}) - return err - }) - assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags") - - host := "ingress.class" - - ginkgo.By("only having IngressClassName") - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil) - ing.Spec.IngressClassName = &testIngressClassName - f.EnsureIngress(ing) - - f.WaitForNginxConfiguration(func(cfg string) bool { - return strings.Contains(cfg, fmt.Sprintf("server_name %v", host)) - }) - - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - Expect(). - Status(http.StatusOK) - - ginkgo.By("only having ingress.class annotation") - ing, err = f.KubeClientSet.NetworkingV1beta1().Ingresses(f.Namespace).Get(context.TODO(), host, metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err) - - ing.Annotations = map[string]string{ - class.IngressKey: testIngressClassName, - } - ing.Spec.IngressClassName = nil - - _, err = f.KubeClientSet.NetworkingV1beta1().Ingresses(f.Namespace).Update(context.TODO(), ing, metav1.UpdateOptions{}) - assert.Nil(ginkgo.GinkgoT(), err) - - f.WaitForNginxConfiguration(func(cfg string) bool { - return strings.Contains(cfg, fmt.Sprintf("server_name %v", host)) - }) - - framework.Sleep() - - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - Expect(). - Status(http.StatusOK) - - ginkgo.By("having an invalid ingress.class annotation and no IngressClassName") - ing, err = f.KubeClientSet.NetworkingV1beta1().Ingresses(f.Namespace).Get(context.TODO(), host, metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err) - - ing.Annotations = map[string]string{ - class.IngressKey: "invalid", - } - ing.Spec.IngressClassName = nil - - _, err = f.KubeClientSet.NetworkingV1beta1().Ingresses(f.Namespace).Update(context.TODO(), ing, metav1.UpdateOptions{}) - assert.Nil(ginkgo.GinkgoT(), err) - - framework.Sleep() - - f.WaitForNginxConfiguration(func(cfg string) bool { - return !strings.Contains(cfg, fmt.Sprintf("server_name %v", host)) - }) - - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - Expect(). - Status(http.StatusNotFound) - - ginkgo.By("not having ingress.class annotation and invalid IngressClassName") - ing, err = f.KubeClientSet.NetworkingV1beta1().Ingresses(f.Namespace).Get(context.TODO(), host, metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err) - ing.Annotations = map[string]string{} - invalidClassName := "invalidclass" - ing.Spec.IngressClassName = &invalidClassName - - _, err = f.KubeClientSet.NetworkingV1beta1().Ingresses(f.Namespace).Update(context.TODO(), ing, metav1.UpdateOptions{}) - assert.Nil(ginkgo.GinkgoT(), err) - - framework.Sleep() - - f.WaitForNginxConfiguration(func(cfg string) bool { - return !strings.Contains(cfg, fmt.Sprintf("server_name %v", host)) - }) - - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - Expect(). - Status(http.StatusNotFound) }) }) diff --git a/test/e2e/settings/no_auth_locations.go b/test/e2e/settings/no_auth_locations.go index dd7112b5a..2d32b05d6 100644 --- a/test/e2e/settings/no_auth_locations.go +++ b/test/e2e/settings/no_auth_locations.go @@ -25,9 +25,8 @@ import ( "github.com/onsi/ginkgo" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/test/e2e/framework" ) @@ -96,6 +95,7 @@ var _ = framework.DescribeSetting("[Security] no-auth-locations", func() { }) func buildBasicAuthIngressWithSecondPath(host, namespace, secretName, pathName string) *networking.Ingress { + pathtype := networking.PathTypePrefix return &networking.Ingress{ ObjectMeta: metav1.ObjectMeta{ Name: host, @@ -106,6 +106,7 @@ func buildBasicAuthIngressWithSecondPath(host, namespace, secretName, pathName s }, }, Spec: networking.IngressSpec{ + IngressClassName: framework.GetIngressClassName(namespace), Rules: []networking.IngressRule{ { Host: host, @@ -113,17 +114,27 @@ func buildBasicAuthIngressWithSecondPath(host, namespace, secretName, pathName s HTTP: &networking.HTTPIngressRuleValue{ Paths: []networking.HTTPIngressPath{ { - Path: "/", + Path: "/", + PathType: &pathtype, Backend: networking.IngressBackend{ - ServiceName: framework.EchoService, - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: framework.EchoService, + Port: networking.ServiceBackendPort{ + Number: int32(80), + }, + }, }, }, { - Path: pathName, + Path: pathName, + PathType: &pathtype, Backend: networking.IngressBackend{ - ServiceName: framework.EchoService, - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: framework.EchoService, + Port: networking.ServiceBackendPort{ + Number: int32(80), + }, + }, }, }, }, diff --git a/test/e2e/settings/server_tokens.go b/test/e2e/settings/server_tokens.go index 43ccc86d3..e84639b08 100644 --- a/test/e2e/settings/server_tokens.go +++ b/test/e2e/settings/server_tokens.go @@ -21,13 +21,13 @@ import ( "github.com/onsi/ginkgo" - networking "k8s.io/api/networking/v1beta1" + networking "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/ingress-nginx/test/e2e/framework" ) var _ = framework.DescribeSetting("server-tokens", func() { + pathtype := networking.PathTypePrefix f := framework.NewDefaultFramework("server-tokens") serverTokens := "server-tokens" @@ -57,6 +57,7 @@ var _ = framework.DescribeSetting("server-tokens", func() { Annotations: map[string]string{}, }, Spec: networking.IngressSpec{ + IngressClassName: &f.IngressClass, Rules: []networking.IngressRule{ { Host: serverTokens, @@ -64,10 +65,15 @@ var _ = framework.DescribeSetting("server-tokens", func() { HTTP: &networking.HTTPIngressRuleValue{ Paths: []networking.HTTPIngressPath{ { - Path: "/", + Path: "/", + PathType: &pathtype, Backend: networking.IngressBackend{ - ServiceName: framework.EchoService, - ServicePort: intstr.FromInt(80), + Service: &networking.IngressServiceBackend{ + Name: framework.EchoService, + Port: networking.ServiceBackendPort{ + Number: int32(80), + }, + }, }, }, }, diff --git a/test/e2e/status/update.go b/test/e2e/status/update.go index af0c6b9a4..23679afdc 100644 --- a/test/e2e/status/update.go +++ b/test/e2e/status/update.go @@ -84,17 +84,17 @@ var _ = framework.IngressNginxDescribe("[Status] status update", func() { err = cmd.Process.Kill() assert.Nil(ginkgo.GinkgoT(), err, "unexpected error terminating kubectl proxy") - ing, err = f.KubeClientSet.NetworkingV1beta1().Ingresses(f.Namespace).Get(context.TODO(), host, metav1.GetOptions{}) + ing, err = f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Get(context.TODO(), host, metav1.GetOptions{}) assert.Nil(ginkgo.GinkgoT(), err, "unexpected error getting %s/%v Ingress", f.Namespace, host) ing.Status.LoadBalancer.Ingress = []apiv1.LoadBalancerIngress{} - _, err = f.KubeClientSet.NetworkingV1beta1().Ingresses(f.Namespace).UpdateStatus(context.TODO(), ing, metav1.UpdateOptions{}) + _, err = f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).UpdateStatus(context.TODO(), ing, metav1.UpdateOptions{}) assert.Nil(ginkgo.GinkgoT(), err, "unexpected error cleaning Ingress status") framework.Sleep(10 * time.Second) err = f.KubeClientSet.CoreV1(). ConfigMaps(f.Namespace). - Delete(context.TODO(), "ingress-controller-leader-nginx", metav1.DeleteOptions{}) + Delete(context.TODO(), "ingress-controller-leader", metav1.DeleteOptions{}) assert.Nil(ginkgo.GinkgoT(), err, "unexpected error deleting leader election configmap") _, cmd, err = f.KubectlProxy(port) @@ -109,7 +109,7 @@ var _ = framework.IngressNginxDescribe("[Status] status update", func() { }() err = wait.Poll(5*time.Second, 4*time.Minute, func() (done bool, err error) { - ing, err = f.KubeClientSet.NetworkingV1beta1().Ingresses(f.Namespace).Get(context.TODO(), host, metav1.GetOptions{}) + ing, err = f.KubeClientSet.NetworkingV1().Ingresses(f.Namespace).Get(context.TODO(), host, metav1.GetOptions{}) if err != nil { return false, nil } diff --git a/test/e2e/wait-for-nginx.sh b/test/e2e/wait-for-nginx.sh index 1eb8b32cc..9a37d1ffc 100755 --- a/test/e2e/wait-for-nginx.sh +++ b/test/e2e/wait-for-nginx.sh @@ -73,6 +73,10 @@ controller: periodSeconds: 1 service: type: NodePort + electionID: ingress-controller-leader + ingressClassResource: + # We will create and remove each IC/ClusterRole/ClusterRoleBinding per test so there's no conflict + enabled: false extraArgs: tcp-services-configmap: $NAMESPACE/tcp-services # e2e tests do not require information about ingress status