diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 0e892d626..406a7ad0a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,16 +7,6 @@ assignees: '' --- - - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e3781887a..c1c815678 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,6 @@ + ## What this PR does / why we need it: @@ -33,36 +34,3 @@ fixes # - [ ] I've read the [CONTRIBUTION](https://github.com/kubernetes/ingress-nginx/blob/main/CONTRIBUTING.md) guide - [ ] I have added unit and/or e2e tests to cover my changes. - [ ] All new and existing tests passed. -- [ ] Added Release Notes. - -## Does my pull request need a release note? -Any user-visible or operator-visible change qualifies for a release note. This could be a: - -- CLI change -- API change -- UI change -- configuration schema change -- behavioral change -- change in non-functional attributes such as efficiency or availability, availability of a new platform -- a warning about a deprecation -- fix of a previous Known Issue -- fix of a vulnerability (CVE) - -No release notes are required for changes to the following: - -- Tests -- Build infrastructure -- Fixes for unreleased bugs - -For more tips on writing good release notes, check out the [Release Notes Handbook](https://github.com/kubernetes/sig-release/tree/master/release-team/role-handbooks/release-notes) - - -```release-note -PLACE RELEASE NOTES HERE -``` diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 28a5e5580..5ad21ca95 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -17,3 +17,11 @@ updates: - "area/dependency" - "release-note-none" - "ok-to-test" + - package-ecosystem: "docker" + directory: "/images" + schedule: + interval: "weekly" + labels: + - "area/dependency" + - "release-note-none" + - "ok-to-test" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 61f5970db..19d39ab70 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -22,6 +22,7 @@ on: required: false type: boolean + permissions: contents: read @@ -39,7 +40,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 id: filter @@ -65,10 +66,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Run Gosec Security Scanner - uses: securego/gosec@1af1d5bb49259b62e45c505db397dd2ada5d74f8 # v2.14.0 + uses: securego/gosec@a459eb0ba387d9bd083d5c2e2354dbeef2465038 # v2.15.0 with: # G601 for zz_generated.deepcopy.go # G306 TODO: Expect WriteFile permissions to be 0600 or less @@ -82,13 +83,13 @@ jobs: (needs.changes.outputs.go == 'true') steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up Go id: go - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 with: - go-version: '1.19' + go-version: '1.20' check-latest: true - name: Run Lint @@ -101,13 +102,13 @@ jobs: (needs.changes.outputs.go == 'true') steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up Go id: go - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 with: - go-version: '1.19' + go-version: '1.20' check-latest: true - name: Run go-fmt @@ -120,13 +121,13 @@ jobs: (needs.changes.outputs.go == 'true') steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up Go id: go - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 with: - go-version: '1.19' + go-version: '1.20' check-latest: true - name: Run test @@ -141,13 +142,13 @@ jobs: steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set up Go id: go - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 with: - go-version: '1.19' + go-version: '1.20' check-latest: true - name: Set up QEMU @@ -155,7 +156,7 @@ jobs: - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@8c0edbc76e98fa90f69d9a2c020dcb50019dc325 # v2.2.1 + uses: docker/setup-buildx-action@4b4e9c3e2d4531116a6f8ba8e71fc6e2cb6e6c8c # v2.5.0 with: version: latest @@ -166,7 +167,7 @@ jobs: run: | sudo apt-get -qq update || true sudo apt-get install -y pigz - curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.25.5/bin/linux/amd64/kubectl + curl -LO https://dl.k8s.io/release/v1.25.5/bin/linux/amd64/kubectl chmod +x ./kubectl sudo mv ./kubectl /usr/local/bin/kubectl @@ -188,11 +189,11 @@ jobs: | pigz > docker.tar.gz - name: cache - uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1 + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 with: name: docker.tar.gz path: docker.tar.gz - + retention-days: 5 helm: name: Helm chart runs-on: ubuntu-latest @@ -204,20 +205,20 @@ jobs: strategy: matrix: - k8s: [v1.23.13, v1.24.7, v1.25.3, v1.26.0] + k8s: [v1.24.12, v1.25.8, v1.26.3,v1.27.1] steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Setup Go - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 with: - go-version: '1.19' + go-version: '1.20' check-latest: true - name: cache - uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3.0.1 + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: docker.tar.gz @@ -254,11 +255,6 @@ jobs: run: | kind create cluster --image=kindest/node:${{ matrix.k8s }} - - uses: geekyeggo/delete-artifact@54ab544f12cdb7b71613a16a2b5a37a9ade990af # v2.0.0 - with: - name: docker.tar.gz - failOnError: false - - name: Load images from cache run: | echo "loading docker images..." @@ -284,14 +280,14 @@ jobs: strategy: matrix: - k8s: [v1.23.13, v1.24.7, v1.25.3, v1.26.0] + k8s: [v1.24.12, v1.25.8, v1.26.3,v1.27.1] steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: cache - uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3.0.1 + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: docker.tar.gz @@ -300,11 +296,6 @@ jobs: run: | kind create cluster --image=kindest/node:${{ matrix.k8s }} --config test/e2e/kind.yaml - - uses: geekyeggo/delete-artifact@54ab544f12cdb7b71613a16a2b5a37a9ade990af # v2.0.0 - with: - name: docker.tar.gz - failOnError: false - - name: Load images from cache run: | echo "loading docker images..." @@ -320,12 +311,13 @@ jobs: make kind-e2e-test - name: Uplaod e2e junit-reports - uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1 + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 if: success() || failure() with: name: e2e-test-reports-${{ matrix.k8s }} path: 'test/junitreports/report*.xml' + kubernetes-chroot: name: Kubernetes chroot runs-on: ubuntu-latest @@ -337,15 +329,15 @@ jobs: strategy: matrix: - k8s: [v1.23.13, v1.24.7, v1.25.3, v1.26.0] + k8s: [v1.24.12, v1.25.8, v1.26.3,v1.27.1] steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: cache - uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3.0.1 + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: docker.tar.gz @@ -354,11 +346,6 @@ jobs: run: | kind create cluster --image=kindest/node:${{ matrix.k8s }} --config test/e2e/kind.yaml - - uses: geekyeggo/delete-artifact@54ab544f12cdb7b71613a16a2b5a37a9ade990af # v2.0.0 - with: - name: docker.tar.gz - failOnError: false - - name: Load images from cache run: | echo "loading docker images..." @@ -374,8 +361,8 @@ jobs: kind get kubeconfig > $HOME/.kube/kind-config-kind make kind-e2e-test - - name: Uplaod e2e junit-reports - uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1 + - name: Upload e2e junit-reports + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 if: success() || failure() with: name: e2e-test-reports-chroot-${{ matrix.k8s }} @@ -391,7 +378,7 @@ jobs: PLATFORMS: linux/amd64,linux/arm64 steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 id: filter-images @@ -408,8 +395,8 @@ jobs: - 'images/echo/**' go-grpc-greeter-server: - 'images/go-grpc-greeter-server/**' - httpbin: - - 'images/httpbin/**' + httpbun: + - 'images/httpbun/**' kube-webhook-certgen: - 'images/kube-webhook-certgen/**' ext-auth-example-authsvc: @@ -435,10 +422,10 @@ jobs: if: ${{ steps.filter-images.outputs.go-grpc-greeter-server == 'true' }} run: | cd images/go-grpc-greeter-server && make build - - name: httpbin image build + - name: httpbun image build if: ${{ steps.filter-images.outputs.httpbin == 'true' }} run: | - cd images/httpbin && make build + cd images/httpbun && make build - name: kube-webhook-certgen image build if: ${{ steps.filter-images.outputs.kube-webhook-certgen == 'true' }} run: | @@ -460,11 +447,11 @@ jobs: strategy: matrix: - k8s: [v1.23.13, v1.24.7, v1.25.3, v1.26.0] + k8s: [v1.24.12, v1.25.8, v1.26.3,v1.27.1] steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 id: filter-images @@ -483,9 +470,9 @@ jobs: - name: Set up Go id: go if: ${{ steps.filter-images.outputs.kube-webhook-certgen == 'true' }} - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 with: - go-version: '1.19' + go-version: '1.20' check-latest: true - name: kube-webhook-certgen image build diff --git a/.github/workflows/depreview.yaml b/.github/workflows/depreview.yaml index 758e4b95f..de9243f16 100644 --- a/.github/workflows/depreview.yaml +++ b/.github/workflows/depreview.yaml @@ -9,6 +9,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: 'Dependency Review' - uses: actions/dependency-review-action@0ff3da6f81b812d4ec3cf37a04e2308c7a723730 # v3.0.2 + uses: actions/dependency-review-action@f46c48ed6d4f1227fb2d9ea62bf6bcbed315589e # v3.0.4 diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 241921ecf..1a2ceaa83 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 id: filter @@ -47,7 +47,7 @@ jobs: steps: - name: Checkout master - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Deploy uses: ./.github/actions/mkdocs diff --git a/.github/workflows/helm.yaml b/.github/workflows/helm.yaml index 5d96507a1..2a82fa124 100644 --- a/.github/workflows/helm.yaml +++ b/.github/workflows/helm.yaml @@ -23,7 +23,19 @@ jobs: steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + + - name: Run Artifact Hub lint + run: | + wget https://github.com/artifacthub/hub/releases/download/v1.5.0/ah_1.5.0_linux_amd64.tar.gz + echo 'ad0e44c6ea058ab6b85dbf582e88bad9fdbc64ded0d1dd4edbac65133e5c87da *ah_1.5.0_linux_amd64.tar.gz' | shasum -c + tar -xzvf ah_1.5.0_linux_amd64.tar.gz ah + ./ah lint -p charts/ingress-nginx || exit 1 + rm -f ./ah ./ah_1.5.0_linux_amd64.tar.gz + + - name: Lint + run: | + ./build/run-in-docker.sh ./hack/verify-chart-lint.sh - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1 id: filter @@ -49,7 +61,7 @@ jobs: steps: - name: Checkout master - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: # Fetch entire history. Required for chart-releaser; see https://github.com/helm/chart-releaser-action/issues/13#issuecomment-602063896 fetch-depth: 0 @@ -61,7 +73,7 @@ jobs: git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" - name: Helm Chart Releaser - uses: helm/chart-releaser-action@98bccfd32b0f76149d188912ac8e45ddd3f8695f # v1.4.1 + uses: helm/chart-releaser-action@be16258da8010256c6e82849661221415f031968 # v1.5.0 env: CR_SKIP_EXISTING: "false" CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/perftest.yaml b/.github/workflows/perftest.yaml index 89dfdfad6..9e87bf1b2 100644 --- a/.github/workflows/perftest.yaml +++ b/.github/workflows/perftest.yaml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Install K6 run: | diff --git a/.github/workflows/plugin.yaml b/.github/workflows/plugin.yaml index 779cd1da8..f77c59937 100644 --- a/.github/workflows/plugin.yaml +++ b/.github/workflows/plugin.yaml @@ -17,18 +17,18 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 with: - go-version: 1.19 + go-version: 1.20 check-latest: true - name: Run GoReleaser - uses: goreleaser/goreleaser-action@8f67e590f2d095516493f017008adc464e63adb1 # v4.1.0 + uses: goreleaser/goreleaser-action@f82d6c1c344bcacabba2c841718984797f664a6b # v4.2.0 with: version: latest args: release --rm-dist @@ -36,6 +36,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Update new version in krew-index - uses: rajatjindal/krew-release-bot@92da038bbf995803124a8e50ebd438b2f37bbbb0 # v0.0.43 + uses: rajatjindal/krew-release-bot@df3eb197549e3568be8b4767eec31c5e8e8e6ad8 # v0.0.46 with: krew_template_file: cmd/plugin/krew.yaml diff --git a/.github/workflows/project.yml b/.github/workflows/project.yml index d75435712..95537e16c 100644 --- a/.github/workflows/project.yml +++ b/.github/workflows/project.yml @@ -13,7 +13,7 @@ jobs: repository-projects: write issues: write steps: - - uses: actions/add-to-project@960fbad431afda394cfcf8743445e741acd19e85 # v0.4.0 + - uses: actions/add-to-project@31b3f3ccdc584546fc445612dec3f38ff5edb41c # v0.5.0 with: project-url: https://github.com/orgs/kubernetes/projects/104 github-token: ${{ secrets.PROJECT_WRITER }} diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 6af70e691..72acf608a 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -27,12 +27,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2 + uses: ossf/scorecard-action@80e868c13c90f172d68d1f4501dee99e2479f7af # v2.1.3 with: results_file: results.sarif results_format: sarif @@ -51,7 +51,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1 + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 with: name: SARIF file path: results.sarif diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 736585e05..b038f522b 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -13,10 +13,10 @@ jobs: pull-requests: write steps: - - uses: actions/stale@6f05e4244c9a0b2ed3401882b05d701dd0a7289b # v7.0.0 + - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 # v8.0.0 with: - stale-issue-message: 'This is stale, but we won't close it automatically, just bare in mind the maintainers may be busy with other tasks and will reach your issue ASAP. If you have any question or request to prioritize this, please reach `#ingress-nginx-dev` on Kubernetes Slack.' - stale-pr-message: 'This is stale, but we won't close it automatically, just bare in mind the maintainers may be busy with other tasks and will reach your issue ASAP. If you have any question or request to prioritize this, please reach `#ingress-nginx-dev` on Kubernetes Slack.' + stale-issue-message: "This is stale, but we won't close it automatically, just bare in mind the maintainers may be busy with other tasks and will reach your issue ASAP. If you have any question or request to prioritize this, please reach `#ingress-nginx-dev` on Kubernetes Slack." + stale-pr-message: "This is stale, but we won't close it automatically, just bare in mind the maintainers may be busy with other tasks and will reach your issue ASAP. If you have any question or request to prioritize this, please reach `#ingress-nginx-dev` on Kubernetes Slack." stale-issue-label: lifecycle/frozen stale-pr-label: lifecycle/frozen days-before-issue-stale: 30 diff --git a/.github/workflows/vulnerability-scans.yaml b/.github/workflows/vulnerability-scans.yaml index 67fad3187..069c9f974 100644 --- a/.github/workflows/vulnerability-scans.yaml +++ b/.github/workflows/vulnerability-scans.yaml @@ -22,7 +22,7 @@ jobs: versions: ${{ steps.version.outputs.TAGS }} steps: - name: Checkout code - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: fetch-depth: 0 @@ -42,7 +42,7 @@ jobs: echo "${SHORT_TAGS[0]},${SHORT_TAGS[1]},${SHORT_TAGS[2]}" TAGS_JSON="[\"${SHORT_TAGS[0]}\",\"${SHORT_TAGS[1]}\",\"${SHORT_TAGS[2]}\"]" echo "${TAGS_JSON}" - echo "::set-output name=TAGS::${TAGS_JSON}" + echo "TAGS=${TAGS_JSON}" >> $GITHUB_OUTPUT scan: runs-on: ubuntu-latest @@ -52,7 +52,7 @@ jobs: versions: ${{ fromJSON(needs.version.outputs.versions) }} steps: - name: Checkout code - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3.2.0 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - shell: bash id: test @@ -60,7 +60,7 @@ jobs: - name: Scan image with AquaSec/Trivy id: scan - uses: aquasecurity/trivy-action@9ab158e8597f3b310480b9a69402b419bc03dbd5 # v0.8.0 + uses: aquasecurity/trivy-action@e5f43133f6e8736992c9f3c1b3296e24b37e17f2 # v0.10.0 with: image-ref: registry.k8s.io/ingress-nginx/controller:${{ matrix.versions }} format: 'sarif' diff --git a/Changelog.md.gotmpl b/Changelog.md.gotmpl new file mode 100644 index 000000000..d35df8ade --- /dev/null +++ b/Changelog.md.gotmpl @@ -0,0 +1,15 @@ +# Changelog + +### {{ .Version }} +Images: +{{ with .ControllerImages }} +{{ range . }} * {{ .Registry }}/{{ .Name }}:{{ .Tag}}@{{ .Digest }} +{{ end }} {{ end }} +### All Changes: +{{ with .Updates }} +{{ range . }}* {{ . }} +{{ end }}{{ end }} +### Dependencies updates: {{ with .DepUpdates }} +{{ range . }}* {{ . }} +{{ end }} {{ end }} +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/controller-{{ .PreviousControllerVersion }}...controller-{{ .NewControllerVersion }} diff --git a/RELEASE.md b/MANUAL_RELEASE.md similarity index 96% rename from RELEASE.md rename to MANUAL_RELEASE.md index ca0faa4e1..d7144b85d 100644 --- a/RELEASE.md +++ b/MANUAL_RELEASE.md @@ -103,7 +103,7 @@ Promoting the images basically means that images, that were pushed to staging co - Fork that other project (if you don't have a fork already). -- Other project to fork [Github repo kubernetes/k8s.io](http://github.com/kubernetes/k8s.io) +- Other project to fork [GitHub repo kubernetes/k8s.io](http://github.com/kubernetes/k8s.io) - Fetch --all and rebase to upstream if already forked. @@ -111,7 +111,7 @@ Promoting the images basically means that images, that were pushed to staging co - In the related branch, of your fork, edit the file /registry.k8s.io/images/k8s-staging-ingress-nginx/images.yaml. -- For making it easier, you can edit your branch directly in the browser. But be careful about making any mistake. +- For making, it easier, you can edit your branch directly in the browser. But be careful about making any mistake. - Insert the sha(s) & the tag(s), in a new line, in this file [Project kubernetes/k8s.io Ingress-Nginx-Controller Images](https://github.com/kubernetes/k8s.io/blob/main/k8s.gcr.io/images/k8s-staging-ingress-nginx/images.yaml) Look at this [example PR and the diff](https://github.com/kubernetes/k8s.io/pull/2536) to see how it was done before @@ -132,7 +132,7 @@ Promoting the images basically means that images, that were pushed to staging co - Make sure to get the tag and sha of the promoted image from the step before, either from cloudbuild or from [here](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/ingress-nginx/controller). -- This involves editing of several different files. So carefully follow the steps below and double check all changes with diff/grep etc., repeatedly. Mistakes here impact endusers. +- This involves editing of several files. So carefully follow the steps below and double check all changes with diff/grep etc., repeatedly. Mistakes here impact endusers. ### a. Make sure your git workspace is ready @@ -160,7 +160,7 @@ Promoting the images basically means that images, that were pushed to staging co - [TAG](https://github.com/kubernetes/ingress-nginx/blob/main/TAG#L1) ### c. Edit the helm Chart - - Change the below mentioned [Fields in Chart.yaml](https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/Chart.yaml) + - Change the below-mentioned [Fields in Chart.yaml](https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/Chart.yaml) - version - appVersion - kubeVersion (**ONLY if applicable**) @@ -168,7 +168,7 @@ Promoting the images basically means that images, that were pushed to staging co - artifacthub.io/prerelease: "true" - artifacthub.io/changes: | - Replace this line and other lines under this annotation with the Changelog. One process to generate the Changelog is described below - - Install and configure github cli as per the docs of gh-cli https://cli.github.com/, + - Install and configure GitHub cli as per the docs of gh-cli https://cli.github.com/, - Change dir to your clone, of your fork, of the ingress-nginx project - Run the below command and save the output to a txt file diff --git a/Makefile b/Makefile index 0ce3e3cef..fc40a39bb 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ TAG ?= $(shell cat TAG) # e2e settings # Allow limiting the scope of the e2e tests. By default run everything -FOCUS ?= .* +FOCUS ?= # number of parallel test E2E_NODES ?= 7 # run e2e test suite with tests that check for memory leaks? (default is false) @@ -147,17 +147,16 @@ test: ## Run go unit tests. .PHONY: lua-test lua-test: ## Run lua unit tests. @build/run-in-docker.sh \ - BUSTED_ARGS=$(BUSTED_ARGS) \ MAC_OS=$(MAC_OS) \ test/test-lua.sh .PHONY: e2e-test e2e-test: ## Run e2e tests (expects access to a working Kubernetes cluster). - @build/run-e2e-suite.sh + @test/e2e/run-e2e-suite.sh .PHONY: kind-e2e-test kind-e2e-test: ## Run e2e tests using kind. - @test/e2e/run.sh + @test/e2e/run-kind-e2e.sh .PHONY: kind-e2e-chart-tests kind-e2e-chart-tests: ## Run helm chart e2e tests diff --git a/NEW_RELEASE_PROCESS.md b/NEW_RELEASE_PROCESS.md new file mode 100644 index 000000000..cdb683abf --- /dev/null +++ b/NEW_RELEASE_PROCESS.md @@ -0,0 +1,9 @@ +# Semi-Automated Release Process + +1. Update TAG +2. Cloud Build +3. k8s.io PR +4. git pull origin main +5. git checkout -b $RELEASE_VERSION +6. mage release:newrelease $RELEASE_VERSION +7. Wait for PR \ No newline at end of file diff --git a/NGINX_BASE b/NGINX_BASE index 72093c593..5f1751bbf 100644 --- a/NGINX_BASE +++ b/NGINX_BASE @@ -1 +1 @@ -registry.k8s.io/ingress-nginx/nginx:21aa7f55a3325c1c26de0dfb62ede4c0a809a994@sha256:da6b877ed96dada46ed6e379051c2dd461dd5d329af7a7531820ad3e16197e20 \ No newline at end of file +registry.k8s.io/ingress-nginx/nginx:91057c439cf07ffb62887b8a8bda66ce3cbe39ca@sha256:3b650123c755392f8c0eb9a356b12716327106e624ab5f5b43bc25ab130978fb \ No newline at end of file diff --git a/OWNERS b/OWNERS index 71f3328f1..da1da1b2e 100644 --- a/OWNERS +++ b/OWNERS @@ -9,3 +9,4 @@ reviewers: emeritus_approvers: - aledbf # 2020-04-02 - bowei # 2022-10-12 +- ElvinEfendi # 2023-04-23 diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 49806abdb..cd9001dd2 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -11,27 +11,28 @@ aliases: - strongjz ingress-nginx-maintainers: - - ElvinEfendi - rikatz - strongjz + - cpanato + - puerco - tao12345666333 ingress-nginx-reviewers: - - ElvinEfendi - rikatz - strongjz + - puerco + - cpanato - tao12345666333 ingress-nginx-helm-maintainers: - - ChiefAlexander - cpanato + - strongjz ingress-nginx-helm-reviewers: - - ChiefAlexander - cpanato + - strongjz ingress-nginx-docs-maintainers: - - IamNoah1 - longwuyuan - tao12345666333 diff --git a/README.md b/README.md index f8c020b68..86f95cb9b 100644 --- a/README.md +++ b/README.md @@ -34,25 +34,28 @@ For detailed changes on the `ingress-nginx` helm chart, please check the followi ### Supported Versions table Supported versions for the ingress-nginx project mean that we have completed E2E tests, and they are passing for -the versions listed. Ingress-Nginx versions may work on older versions but the project does not make that guarantee. +the versions listed. Ingress-Nginx versions may work on older versions but the project does not make that guarantee. -| Ingress-NGINX version | k8s supported version | Alpine Version | Nginx Version | -|-----------------------|------------------------------|----------------|---------------| -| v1.5.1 | 1.25, 1.24, 1.23 | 3.16.2 | 1.21.6 | -| v1.4.0 | 1.25, 1.24, 1.23, 1.22 | 3.16.2 | 1.19.10† | -| v1.3.1 | 1.24, 1.23, 1.22, 1.21, 1.20 | 3.16.2 | 1.19.10† | -| v1.3.0 | 1.24, 1.23, 1.22, 1.21, 1.20 | 3.16.0 | 1.19.10† | -| v1.2.1 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.6 | 1.19.10† | -| v1.1.3 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.4 | 1.19.10† | -| v1.1.2 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | -| v1.1.1 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | -| v1.1.0 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | -| v1.0.5 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | -| v1.0.4 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | -| v1.0.3 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | -| v1.0.2 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | -| v1.0.1 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | -| v1.0.0 | 1.22, 1.21, 1.20, 1.19 | 3.13.5 | 1.20.1 | +| | Ingress-NGINX version | k8s supported version | Alpine Version | Nginx Version | Helm Chart Version | +|:-----:|------------------------|------------------------------|----------------|---------------|--------------------| +| 🔄 | **v1.7.1** | 1.27,1.26, 1.25, 1.24 | 3.17.2 | 1.21.6 | 4.6.* | +| 🔄 | **v1.7.0** | 1.26, 1.25, 1.24 | 3.17.2 | 1.21.6 | 4.6.* | +| 🔄 | **v1.6.4** | 1.26, 1.25, 1.24, 1.23 | 3.17.0 | 1.21.6 | 4.5.* | +| 🔄| **v1.5.1** | 1.25, 1.24, 1.23 | 3.16.2 | 1.21.6 | 4.4.* | +| | v1.4.0 | 1.25, 1.24, 1.23, 1.22 | 3.16.2 | 1.19.10† | 4.3.0 | +| | v1.3.1 | 1.24, 1.23, 1.22, 1.21, 1.20 | 3.16.2 | 1.19.10† | 4.2.5 | +| | v1.3.0 | 1.24, 1.23, 1.22, 1.21, 1.20 | 3.16.0 | 1.19.10† | 4.2.3 | +| | v1.2.1 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.6 | 1.19.10† | 4.1.4 | +| | v1.1.3 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.4 | 1.19.10† | 4.0.19 | +| | v1.1.2 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | 4.0.18 | +| | v1.1.1 | 1.23, 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | 4.0.17 | +| | v1.1.0 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | 4.0.13 | +| | v1.0.5 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | 4.0.9 | +| | v1.0.4 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | 4.0.6 | +| | v1.0.3 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | 4.0.5 | +| | v1.0.2 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | 4.0.3 | +| | v1.0.1 | 1.22, 1.21, 1.20, 1.19 | 3.14.2 | 1.19.9† | 4.0.2 | +| | v1.0.0 | 1.22, 1.21, 1.20, 1.19 | 3.13.5 | 1.20.1 | 4.0.1 | † _This build is diff --git a/TAG b/TAG index c9b3c015f..668c7899c 100644 --- a/TAG +++ b/TAG @@ -1 +1,2 @@ -v1.5.1 \ No newline at end of file +v1.7.1 + diff --git a/build/dev-env.sh b/build/dev-env.sh index 09609367a..3d21b7e15 100755 --- a/build/dev-env.sh +++ b/build/dev-env.sh @@ -62,7 +62,7 @@ echo "[dev-env] building image" make build image docker tag "${REGISTRY}/controller:${TAG}" "${DEV_IMAGE}" -export K8S_VERSION=${K8S_VERSION:-v1.25.2@sha256:9be91e9e9cdf116809841fc77ebdb8845443c4c72fe5218f3ae9eb57fdb4bace} +export K8S_VERSION=${K8S_VERSION:-v1.26.3@sha256:61b92f38dff6ccc29969e7aa154d34e38b89443af1a2c14e6cfbd2df6419c66f} KIND_CLUSTER_NAME="ingress-nginx-dev" diff --git a/build/run-in-docker.sh b/build/run-in-docker.sh index 44ca2d5f7..3a6aeb43d 100755 --- a/build/run-in-docker.sh +++ b/build/run-in-docker.sh @@ -44,7 +44,7 @@ function cleanup { } trap cleanup EXIT -E2E_IMAGE=${E2E_IMAGE:-registry.k8s.io/ingress-nginx/e2e-test-runner:v20221221-controller-v1.5.1-62-g6ffaef32a@sha256:8f025472964cd15ae2d379503aba150565a8d78eb36b41ddfc5f1e3b1ca81a8e} +E2E_IMAGE=${E2E_IMAGE:-registry.k8s.io/ingress-nginx/e2e-test-runner:v20230314-helm-chart-4.5.2-32-g520384b11@sha256:754c62f9a5efd1ee515ee908ecc16c0c4d1dda96a8cc8019667182a55f3a9035} if [[ "$RUNTIME" == podman ]]; then # Podman does not support both tag and digest @@ -87,7 +87,7 @@ if [[ "$DOCKER_IN_DOCKER_ENABLED" == "true" ]]; then echo "..reached DIND check TRUE block, inside run-in-docker.sh" echo "FLAGS=$FLAGS" #go env - go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo@v2.6.1 + go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo@v2.9.0 find / -type f -name ginkgo 2>/dev/null which ginkgo /bin/bash -c "${FLAGS}" diff --git a/changelog/Changelog-1.5.2.md b/changelog/Changelog-1.6.4.md similarity index 51% rename from changelog/Changelog-1.5.2.md rename to changelog/Changelog-1.6.4.md index 8b2617924..5f940d1c4 100644 --- a/changelog/Changelog-1.5.2.md +++ b/changelog/Changelog-1.6.4.md @@ -1,13 +1,60 @@ # Changelog -### 1.5.2 +### 1.6.4 Images: - * registry.k8s.io/ingress-nginx/controller:controller-v1.5.2@sha256:3870522ed937c9efb94bfa31a7eb16009831567a0d4cbe01846fc5486d622655 - * registry.k8s.io/ingress-nginx/controller-chroot:controller-v1.5.2@sha256:84613555694f2c59a8b2551126d226c9aa648544ebf0cde1e0df942f7dbce42b + * registry.k8s.io/controller:controller-v1.6.4@sha256:15be4666c53052484dd2992efacf2f50ea77a78ae8aa21ccd91af6baaa7ea22f + * registry.k8s.io/controller-chroot:controller-v1.6.4@sha256:0de01e2c316c3ca7847ca13b32d077af7910d07f21a4a82f81061839764f8f81 ### All Changes: +* remove tests and regex path checks (#9626) +* Fix incorrect annotation name in upstream hashing configuration (#9617) +* Release docs for Controller v1.6.3 and Helm v4.5.0 (#9614) +* Revert Implement pathType validation (#9511) (#9607) +* update history and allow to pass a target test (#9605) +* Allow to pass a target test (#9542) +* Replace deprecated command with environment file (#9581) +* build 1.6.2 to fix (#9569) +* add lint on chart before release (#9570) +* tcpproxy: increase buffer size to 16K (#9548) +* Move and spell-check Kubernetes 1.22 migration FAQ (#9544) +* Add CORS template check inside location for externalAuth.SignURL (#8814) +* fix(grafana-dashboard): remove hardcoded namespace references (#9523) +* Replace deprecated command with environment file (#9581) +* add lint on chart before release (#9570) +* Switch logic on path type validation and setting it to false (#9543) +* tcpproxy: increase buffer size to 16K (#9548) +* Move and spell-check Kubernetes 1.22 migration FAQ (#9544) +* Add CORS template check inside location for externalAuth.SignURL (#8814) +* fix(grafana-dashboard): remove hardcoded namespace references (#9523) +* Align default value for keepalive_request with NGINX default (#9518) +* feat(configmap): expose gzip-disable (#9505) +* Values: Add missing `controller.metrics.service.labels`. (#9501) +* Add docs about orphan_ingress metric (#9514) +* Add new prometheus metric for orphaned ingress (#8230) +* Sanitise request metrics in monitoring docs (#9384) +* Change default value of enable-brotli (#9500) +* feat: support topology aware hints (#9165) +* Remove 1.5.2 from readme (#9498) +* Remove nonexistent load flag from docker build commands (#9122) +* added option to disable sync event creation (#8528) +* Add buildResolvers to the stream module (#9184) +* fix: disable auth access logs (#9049) +* Adding ipdenylist annotation (#8795) +* Add update updateStrategy and minReadySeconds for defaultBackend (#8506) +* Fix indentation on serviceAccount annotation (#9129) +* Update monitoring.md (#9269) +* add github actions stale bot (#9439) +* Admission Webhooks/Job: Add `NetworkPolicy`. (#9218) +* update OpenTelemetry image (#9491) +* bump OpenTelemetry (#9489) +* Optional podman support (#9294) +* fix change images (#9463) +* move tests to gh actions (#9461) +* Automated Release Controller 1.5.2 (#9455) +* Add sslpassthrough tests (#9457) +* updated the link in RELEASE.md file (#9456) * restart 1.5.2 release process (#9450) * Update command line arguments documentation (#9224) * start release 1.5.2 (#9445) @@ -43,7 +90,6 @@ Images: * remove the configmap related permissions (#9310) * remove hardcoded datasource from grafana dashboard (#9284) * update gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b to 3.0.0 (#9277) -* Validate ingress path fields (#9309) * added SAN to cert create command (#9295) * Missing controller.ingressClass (#9304) * OpenTelemetry static linking (#9286) @@ -54,6 +100,17 @@ Images: * add containerSecurityContext to extraModules init containers (kubernetes#9016) (#9242) ### Dependencies updates: +* Bump google.golang.org/grpc from 1.52.0 to 1.52.3 (#9555) +* Bump k8s.io/klog/v2 from 2.80.1 to 2.90.0 (#9553) +* Bump sigs.k8s.io/controller-runtime from 0.13.1 to 0.14.2 (#9552) +* Bump google.golang.org/grpc from 1.51.0 to 1.52.0 (#9512) +* Bump `client-go` to remove dependence on go-autorest dependency (#9488) +* Bump google.golang.org/grpc from 1.52.0 to 1.52.3 (#9555) +* Bump k8s.io/klog/v2 from 2.80.1 to 2.90.0 (#9553) +* Bump sigs.k8s.io/controller-runtime from 0.13.1 to 0.14.2 (#9552) +* Bump google.golang.org/grpc from 1.51.0 to 1.52.0 (#9512) +* Bump `client-go` to remove dependence on go-autorest dependency (#9488) +* Bump golang.org/x/crypto from 0.4.0 to 0.5.0 (#9494) * Bump golang.org/x/crypto from 0.3.0 to 0.4.0 (#9397) * Bump github.com/onsi/ginkgo/v2 from 2.6.0 to 2.6.1 (#9432) * Bump github.com/onsi/ginkgo/v2 from 2.6.0 to 2.6.1 (#9421) @@ -76,4 +133,4 @@ Images: * Bump actions/dependency-review-action from 2.5.1 to 3.0.0 (#9301) * Bump k8s.io/component-base from 0.25.3 to 0.25.4 (#9300) -**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/controller-controller-v1.5.1...controller-controller-v1.5.2 +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/controller-controller-v1.5.1...controller-controller-v1.6.4 diff --git a/changelog/Changelog-1.7.0.md b/changelog/Changelog-1.7.0.md new file mode 100644 index 000000000..6a938c5f5 --- /dev/null +++ b/changelog/Changelog-1.7.0.md @@ -0,0 +1,78 @@ +# Changelog + +### 1.7.0 +Images: + + * registry.k8s.io/ingress-nginx/controller:v1.7.0@sha256:7612338342a1e7b8090bef78f2a04fffcadd548ccaabe8a47bf7758ff549a5f7 + * registry.k8s.io/ingress-nginx/controller-chroot:v1.7.0@sha256:e84ef3b44c8efeefd8b0aa08770a886bfea1f04c53b61b4ba9a7204e9f1a7edc + +### All Changes: + +* kick off 1.7.0 build (#9775) +* Update exposing-tcp-udp-services.md (#9777) +* feat: OpenTelemetry module integration (#9062) +* drop k8s 1.23 support (#9772) +* Fix canary-weight-total annotation ignored in rule backends (#9729) +* fix: controller psp's volume config (#9740) +* Fix several Helm YAML issues with extraModules and extraInitContainers (#9709) +* docs(helm): fix value key in readme for enabling certManager (#9640) +* updated digest and sha for e2e-test-echo (#9760) +* updated digest and sha for e2e-test-fastcgi-helloserver (#9759) +* updated digest and sha for opentelemetry (#9758) +* updated digest and sha for e2e-test-cfssl (#9757) +* updated kube-webhook-certgen digest and tags (#9756) +* updated nginx-error digest and tags (#9755) +* added upgrade ginkgo documentation for contributors (#9753) +* changes Makefile of echo folder to trigger code-build (#9754) +* Chart: Drop `controller.headers`, rework DH param secret. (#9659) +* updated NGINX_BASE image with latest tag (#9747) +* Deployment/DaemonSet: Label pods using `ingress-nginx.labels`. (#9732) +* bumped ginkgo to v2.9.0 (#9722) +* HPA: autoscaling/v2beta1 deprecated, bump apiVersion to v2 for defaultBackend (#9731) +* update to golang 1.20 (#9690) +* Indent values.yaml using 2 instead of 4 spaces (#9656) +* fix some comments (#9688) +* migrate mitchellh/hashstructure to v2 (#9651) +* changed v1.6.3 to v1.6.4 on deploy docs (#9647) +* controller: Don't panic when ready condition in a endpointslice is missing (#9550) +* Rework Ginkgo usage (#9522) +* code clean for fsnotify (#9571) +* Optimize the document for readability (#9551) +* sets.String is deprecated: use generic Set instead. new ways: s1 := Set[string]{} s2 := New[string]() (#9589) +* Adjust the import package order and use http library variables (#9587) +* Optimize the judgment mode to remove redundant transformations (#9588) +* Fix rewrite example (#9633) +* remove tests and regex path checks (#9626) +* Fix incorrect annotation name in upstream hashing configuration (#9617) +* Release docs for Controller v1.6.3 and Helm v4.5.0 (#9614) + +### Dependencies updates: +* Bump aquasecurity/trivy-action from 0.8.0 to 0.9.2 (#9767) +* Bump k8s.io/component-base from 0.26.2 to 0.26.3 (#9764) +* Bump actions/dependency-review-action from 3.0.3 to 3.0.4 (#9766) +* Bump actions/add-to-project from 0.4.0 to 0.4.1 (#9765) +* Bump actions/dependency-review-action from 3.0.2 to 3.0.3 (#9727) +* Bump github.com/prometheus/common from 0.41.0 to 0.42.0 (#9724) +* Bump golang.org/x/crypto from 0.6.0 to 0.7.0 (#9723) +* Bump actions/download-artifact from 3.0.1 to 3.0.2 (#9721) +* Bump goreleaser/goreleaser-action from 4.1.0 to 4.2.0 (#9718) +* Bump actions/upload-artifact from 3.1.1 to 3.1.2 (#9717) +* Bump docker/setup-buildx-action from 2.2.1 to 2.5.0 (#9719) +* Bump helm/chart-releaser-action from 1.4.1 to 1.5.0 (#9720) +* Bump github.com/onsi/ginkgo/v2 from 2.6.1 to 2.9.0 (#9695) +* Bump k8s.io/klog/v2 from 2.90.0 to 2.90.1 (#9694) +* Bump golang.org/x/crypto in /magefiles (#9691) +* Bump k8s.io/component-base from 0.26.1 to 0.26.2 (#9696) +* Bump github.com/prometheus/common from 0.40.0 to 0.41.0 (#9698) +* Bump sigs.k8s.io/controller-runtime from 0.14.2 to 0.14.5 (#9697) +* Bump golang.org/x/net in /magefiles (#9692) +* Bump golang.org/x/sys in /images/custom-error-pages/rootfs (#9671) +* Bump github.com/stretchr/testify from 1.8.1 to 1.8.2 (#9675) +* Bump github.com/prometheus/common from 0.39.0 to 0.40.0 (#9653) +* Bump golang.org/x/net from 0.6.0 to 0.7.0 (#9646) +* Bump golang.org/x/net in /images/kube-webhook-certgen/rootfs (#9645) +* Bump google.golang.org/grpc from 1.52.3 to 1.53.0 (#9610) +* Bump github.com/prometheus/client_golang (#9630) +* Bump golang.org/x/crypto from 0.5.0 to 0.6.0 (#9609) + +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/controller-controller-v1.6.3...controller-controller-v1.7.0 diff --git a/changelog/Changelog-1.7.1.md b/changelog/Changelog-1.7.1.md new file mode 100644 index 000000000..9b8422c7e --- /dev/null +++ b/changelog/Changelog-1.7.1.md @@ -0,0 +1,52 @@ +# Changelog + +### 1.7.1 +Images: + + * registry.k8s.io/ingress-nginx/controller:v1.7.1@sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407 + * registry.k8s.io/ingress-nginx/controller-chroot:v1.7.1@sha256:e35d5ab487861b9d419c570e3530589229224a0762c7b4d2e2222434abb8d988 + +### All Changes: + +* Update TAG - 1.7.1 (#9922) +* Update dependabot to watch docker images (#9600) +* [helm] Support custom port configuration for internal service (#9846) +* Add support for --container flag (#9703) +* Fix typo in OpenTelemetry (#9903) +* ensure make lua-test runs locally (#9902) +* update k8s.io dependecies to v0.26.4 (#9893) +* Adding resource type to default HPA configuration to resolve issues with Terraform helm chart usage (#9803) +* I have not been able to fulfill my maintainer responsibilities for a while already, making it official now. (#9883) +* Update k8s versions (#9879) +* README: Update `external-dns` link. (#9866) +* Fastcgi configmap should be on the same namespace of ingress (#9863) +* Deprecate and remove influxdb feature (#9861) +* Remove deprecated annotation secure-upstream (#9862) +* Exclude socket metrics (#9770) +* Chart: Improve `README.md`. (#9831) +* update all container tags with date and sha, upgrade all containers (#9834) +* updated NGINX_BASE image in project (#9829) +* ISO 8601 date format (#9682) +* Values: Fix indention of commented values. (#9812) +* The Ingress-Nginx project recently released version 1.7.0 of the controller, but the deployment documentation still referenced version 1.6.4. This commit updates the documentation to reference the latest version, ensuring that users have access to the most up-to-date information. Fixes#9787 (#9788) + +### Dependencies updates: +* Bump github.com/opencontainers/runc from 1.1.6 to 1.1.7 (#9912) +* Bump github.com/prometheus/client_golang from 1.14.0 to 1.15.0 (#9868) +* Bump aquasecurity/trivy-action from 0.9.2 to 0.10.0 (#9888) +* Bump github.com/opencontainers/runc from 1.1.5 to 1.1.6 (#9867) +* Bump actions/checkout from 3.5.0 to 3.5.2 (#9870) +* Bump golang.org/x/crypto from 0.7.0 to 0.8.0 (#9838) +* Bump github.com/spf13/cobra from 1.6.1 to 1.7.0 (#9839) +* Bump actions/add-to-project from 0.4.1 to 0.5.0 (#9840) +* Bump actions/checkout from 3.4.0 to 3.5.0 (#9798) +* Bump ossf/scorecard-action from 2.1.2 to 2.1.3 (#9823) +* Bump github.com/opencontainers/runc from 1.1.4 to 1.1.5 (#9806) +* Bump actions/stale from 7.0.0 to 8.0.0 (#9799) +* Bump rajatjindal/krew-release-bot from 0.0.43 to 0.0.46 (#9797) +* Bump actions/setup-go from 3.5.0 to 4.0.0 (#9796) +* Bump github.com/imdario/mergo from 0.3.13 to 0.3.15 (#9795) +* Bump google.golang.org/grpc from 1.53.0 to 1.54.0 (#9794) +* Bump sigs.k8s.io/controller-runtime from 0.14.5 to 0.14.6 (#9822) + +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/controller-controller-v1.7.0...controller-controller-v1.7.1 diff --git a/charts/ingress-nginx/Chart.yaml b/charts/ingress-nginx/Chart.yaml index 2a15960f7..81ebfc875 100644 --- a/charts/ingress-nginx/Chart.yaml +++ b/charts/ingress-nginx/Chart.yaml @@ -1,31 +1,25 @@ +annotations: + artifacthub.io/changes: | + - "[helm] Support custom port configuration for internal service (#9846)" + - "Adding resource type to default HPA configuration to resolve issues with Terraform helm chart usage (#9803)" + - "Update Ingress-Nginx version controller-v1.7.1" + artifacthub.io/prerelease: "false" apiVersion: v2 -name: ingress-nginx -# When the version is modified, make sure the artifacthub.io/changes list is updated -# Also update CHANGELOG.md -version: 4.4.2 -appVersion: 1.5.1 +appVersion: 1.7.1 +description: Ingress controller for Kubernetes using NGINX as a reverse proxy and + load balancer +engine: gotpl home: https://github.com/kubernetes/ingress-nginx -description: Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer icon: https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Nginx_logo.svg/500px-Nginx_logo.svg.png keywords: - - ingress - - nginx -sources: - - https://github.com/kubernetes/ingress-nginx +- ingress +- nginx +kubeVersion: '>=1.20.0-0' maintainers: - - name: rikatz - - name: strongjz - - name: tao12345666333 -engine: gotpl -kubeVersion: ">=1.20.0-0" -annotations: - # Use this annotation to indicate that this chart version is a pre-release. - # https://artifacthub.io/docs/topics/annotations/helm/ - artifacthub.io/prerelease: "false" - # List of changes for the release in artifacthub.io - # https://artifacthub.io/packages/helm/ingress-nginx/ingress-nginx?modal=changelog - artifacthub.io/changes: | - - Adding support for disabling liveness and readiness probes to the Helm chart - - add:(admission-webhooks) ability to set securityContext - - Updated Helm chart to use the fullname for the electionID if not specified - - Rename controller-wehbooks-networkpolicy.yaml +- name: rikatz +- name: strongjz +- name: tao12345666333 +name: ingress-nginx +sources: +- https://github.com/kubernetes/ingress-nginx +version: 4.6.1 diff --git a/charts/ingress-nginx/README.md b/charts/ingress-nginx/README.md index 6c56caf6a..e2dd6ef3c 100644 --- a/charts/ingress-nginx/README.md +++ b/charts/ingress-nginx/README.md @@ -2,16 +2,15 @@ [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer -![Version: 4.4.2](https://img.shields.io/badge/Version-4.4.2-informational?style=flat-square) ![AppVersion: 1.5.1](https://img.shields.io/badge/AppVersion-1.5.1-informational?style=flat-square) +![Version: 4.6.1](https://img.shields.io/badge/Version-4.6.1-informational?style=flat-square) ![AppVersion: 1.7.1](https://img.shields.io/badge/AppVersion-1.7.1-informational?style=flat-square) To use, add `ingressClassName: nginx` spec field or the `kubernetes.io/ingress.class: nginx` annotation to your Ingress resources. This chart bootstraps an ingress-nginx deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. -## Prerequisites +## Requirements -- Chart version 3.x.x: Kubernetes v1.16+ -- Chart version 4.x.x and above: Kubernetes v1.19+ +Kubernetes: `>=1.20.0-0` ## Get Repo Info @@ -52,10 +51,6 @@ helm upgrade [RELEASE_NAME] [CHART] --install _See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ -### Upgrading With Zero Downtime in Production - -By default the ingress-nginx controller has service interruptions whenever it's pods are restarted or redeployed. In order to fix that, see the excellent blog post by Lindsay Landry from Codecademy: [Kubernetes: Nginx and Zero Downtime in Production](https://medium.com/codecademy-engineering/kubernetes-nginx-and-zero-downtime-in-production-2c910c6a5ed8). - ### Migrating from stable/nginx-ingress There are two main ways to migrate a release from `stable/nginx-ingress` to `ingress-nginx/ingress-nginx` chart: @@ -66,7 +61,6 @@ There are two main ways to migrate a release from `stable/nginx-ingress` to `ing 1. Redirect your DNS traffic from the old controller to the new controller 1. Log traffic from both controllers during this changeover 1. [Uninstall](#uninstall-chart) the old controller once traffic has fully drained from it - 1. For details on all of these steps see [Upgrading With Zero Downtime in Production](#upgrading-with-zero-downtime-in-production) Note that there are some different and upgraded configurations between the two charts, described by Rimas Mocevicius from JFrog in the "Upgrading to ingress-nginx Helm chart" section of [Migrating from Helm chart nginx-ingress to ingress-nginx](https://rimusz.net/migrating-to-ingress-nginx). As the `ingress-nginx/ingress-nginx` chart continues to update, you will want to check current differences by running [helm configuration](#configuration) commands on both charts. @@ -85,14 +79,14 @@ else it would make it impossible to evacuate a node. See [gh issue #7127](https: ### Prometheus Metrics -The Nginx ingress controller can export Prometheus metrics, by setting `controller.metrics.enabled` to `true`. +The Ingress-Nginx Controller can export Prometheus metrics, by setting `controller.metrics.enabled` to `true`. You can add Prometheus annotations to the metrics service using `controller.metrics.service.annotations`. Alternatively, if you use the Prometheus Operator, you can enable ServiceMonitor creation using `controller.metrics.serviceMonitor.enabled`. And set `controller.metrics.serviceMonitor.additionalLabels.release="prometheus"`. "release=prometheus" should match the label configured in the prometheus servicemonitor ( see `kubectl get servicemonitor prometheus-kube-prom-prometheus -oyaml -n prometheus`) ### ingress-nginx nginx\_status page/stats server -Previous versions of this chart had a `controller.stats.*` configuration block, which is now obsolete due to the following changes in nginx ingress controller: +Previous versions of this chart had a `controller.stats.*` configuration block, which is now obsolete due to the following changes in Ingress-Nginx Controller: - In [0.16.1](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0161), the vts (virtual host traffic status) dashboard was removed - In [0.23.0](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230), the status page at port 18080 is now a unix socket webserver only available at localhost. @@ -100,7 +94,7 @@ Previous versions of this chart had a `controller.stats.*` configuration block, ### ExternalDNS Service Configuration -Add an [ExternalDNS](https://github.com/kubernetes-incubator/external-dns) annotation to the LoadBalancer service: +Add an [ExternalDNS](https://github.com/kubernetes-sigs/external-dns) annotation to the LoadBalancer service: ```yaml controller: @@ -126,19 +120,6 @@ controller: service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600' ``` -### AWS route53-mapper - -To configure the LoadBalancer service with the [route53-mapper addon](https://github.com/kubernetes/kops/blob/be63d4f1a7a46daaf1c4c482527328236850f111/addons/route53-mapper/README.md), add the `domainName` annotation and `dns` label: - -```yaml -controller: - service: - labels: - dns: "route53" - annotations: - domainName: "kubernetes-example.com" -``` - ### Additional Internal Load Balancer This setup is useful when you need both external and internal load balancers but don't want to have multiple ingress controllers and multiple ingress objects per application. @@ -212,7 +193,7 @@ Optionally you can set `controller.service.loadBalancerIP` if you need a static ### Ingress Admission Webhooks -With nginx-ingress-controller version 0.25+, the nginx ingress controller pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent bad ingress from being added to the cluster. +With nginx-ingress-controller version 0.25+, the Ingress-Nginx Controller pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent bad ingress from being added to the cluster. **This feature is enabled by default since 0.31.0.** With nginx-ingress-controller in 0.25.* work only with kubernetes 1.14+, 0.26 fix [this issue](https://github.com/kubernetes/ingress-nginx/pull/4521) @@ -221,14 +202,14 @@ With nginx-ingress-controller in 0.25.* work only with kubernetes 1.14+, 0.26 fi A validating and configuration requires the endpoint to which the request is sent to use TLS. It is possible to set up custom certificates to do this, but in most cases, a self-signed certificate is enough. The setup of this component requires some more complex orchestration when using helm. The steps are created to be idempotent and to allow turning the feature on and off without running into helm quirks. 1. A pre-install hook provisions a certificate into the same namespace using a format compatible with provisioning using end user certificates. If the certificate already exists, the hook exits. -2. The ingress nginx controller pod is configured to use a TLS proxy container, which will load that certificate. +2. The Ingress-Nginx Controller pod is configured to use a TLS proxy container, which will load that certificate. 3. Validating and Mutating webhook configurations are created in the cluster. 4. A post-install hook reads the CA from the secret created by step 1 and patches the Validating and Mutating webhook configurations. This process will allow a custom CA provisioned by some other process to also be patched into the webhook configurations. The chosen failure policy is also patched into the webhook configurations #### Alternatives It should be possible to use [cert-manager/cert-manager](https://github.com/cert-manager/cert-manager) if a more complete solution is required. -You can enable automatic self-signed TLS certificate provisioning via cert-manager by setting the `controller.admissionWebhooks.certManager.enable` value to true. +You can enable automatic self-signed TLS certificate provisioning via cert-manager by setting the `controller.admissionWebhooks.certManager.enabled` value to true. Please ensure that cert-manager is correctly installed and configured. @@ -244,10 +225,6 @@ Detail of how and why are in [this issue](https://github.com/helm/charts/pull/13 As of version `1.26.0` of this chart, by simply not providing any clusterIP value, `invalid: spec.clusterIP: Invalid value: "": field is immutable` will no longer occur since `clusterIP: ""` will not be rendered. -## Requirements - -Kubernetes: `>=1.20.0-0` - ## Values | Key | Type | Default | Description | @@ -271,11 +248,11 @@ Kubernetes: `>=1.20.0-0` | controller.admissionWebhooks.networkPolicyEnabled | bool | `false` | | | controller.admissionWebhooks.objectSelector | object | `{}` | | | controller.admissionWebhooks.patch.enabled | bool | `true` | | -| controller.admissionWebhooks.patch.image.digest | string | `"sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f"` | | +| controller.admissionWebhooks.patch.image.digest | string | `"sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f"` | | | controller.admissionWebhooks.patch.image.image | string | `"ingress-nginx/kube-webhook-certgen"` | | | controller.admissionWebhooks.patch.image.pullPolicy | string | `"IfNotPresent"` | | | controller.admissionWebhooks.patch.image.registry | string | `"registry.k8s.io"` | | -| controller.admissionWebhooks.patch.image.tag | string | `"v20220916-gd32f8c343"` | | +| controller.admissionWebhooks.patch.image.tag | string | `"v20230312-helm-chart-4.5.2-28-g66a760794"` | | | controller.admissionWebhooks.patch.labels | object | `{}` | Labels to be added to patch job resources | | controller.admissionWebhooks.patch.nodeSelector."kubernetes.io/os" | string | `"linux"` | | | controller.admissionWebhooks.patch.podAnnotations | object | `{}` | | @@ -297,7 +274,6 @@ Kubernetes: `>=1.20.0-0` | controller.allowSnippetAnnotations | bool | `true` | This configuration defines if Ingress Controller should allow users to set their own *-snippet annotations, otherwise this is forbidden / dropped when users add those annotations. Global snippets in ConfigMap are still respected | | controller.annotations | object | `{}` | Annotations to be added to the controller Deployment or DaemonSet # | | controller.autoscaling.annotations | object | `{}` | | -| controller.autoscaling.apiVersion | string | `"autoscaling/v2"` | | | controller.autoscaling.behavior | object | `{}` | | | controller.autoscaling.enabled | bool | `false` | | | controller.autoscaling.maxReplicas | int | `11` | | @@ -316,15 +292,16 @@ Kubernetes: `>=1.20.0-0` | controller.dnsPolicy | string | `"ClusterFirst"` | Optionally change this to ClusterFirstWithHostNet in case you have 'hostNetwork: true'. By default, while using host network, name resolution uses the host's DNS. If you wish nginx-controller to keep resolving names inside the k8s network, use ClusterFirstWithHostNet. | | controller.electionID | string | `""` | Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader' | | controller.enableMimalloc | bool | `true` | Enable mimalloc as a drop-in replacement for malloc. # ref: https://github.com/microsoft/mimalloc # | +| controller.enableTopologyAwareRouting | bool | `false` | This configuration enables Topology Aware Routing feature, used together with service annotation service.kubernetes.io/topology-aware-hints="auto" Defaults to false | | controller.existingPsp | string | `""` | Use an existing PSP instead of creating one | -| controller.extraArgs | object | `{}` | Additional command line arguments to pass to nginx-ingress-controller E.g. to specify the default SSL certificate you can use | +| controller.extraArgs | object | `{}` | Additional command line arguments to pass to Ingress-Nginx Controller E.g. to specify the default SSL certificate you can use | | controller.extraContainers | list | `[]` | Additional containers to be added to the controller pod. See https://github.com/lemonldap-ng-controller/lemonldap-ng-controller as example. | | controller.extraEnvs | list | `[]` | Additional environment variables to set | | controller.extraInitContainers | list | `[]` | Containers, which are run before the app containers are started. | | controller.extraModules | list | `[]` | Modules, which are mounted into the core nginx image. See values.yaml for a sample to add opentelemetry module | | controller.extraVolumeMounts | list | `[]` | Additional volumeMounts to the controller main container. | | controller.extraVolumes | list | `[]` | Additional volumes to the controller pod. | -| controller.healthCheckHost | string | `""` | Address to bind the health check endpoint. It is better to set this option to the internal node address if the ingress nginx controller is running in the `hostNetwork: true` mode. | +| controller.healthCheckHost | string | `""` | Address to bind the health check endpoint. It is better to set this option to the internal node address if the Ingress-Nginx Controller is running in the `hostNetwork: true` mode. | | controller.healthCheckPath | string | `"/healthz"` | Path of the health check endpoint. All requests received on the port defined by the healthz-port parameter are forwarded internally to this path. | | controller.hostNetwork | bool | `false` | Required for use with CNI based kubernetes installations (such as ones set up by kubeadm), since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920 is merged | | controller.hostPort.enabled | bool | `false` | Enable 'hostPort' or not | @@ -333,13 +310,13 @@ Kubernetes: `>=1.20.0-0` | controller.hostname | object | `{}` | Optionally customize the pod hostname. | | controller.image.allowPrivilegeEscalation | bool | `true` | | | controller.image.chroot | bool | `false` | | -| controller.image.digest | string | `"sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629"` | | -| controller.image.digestChroot | string | `"sha256:c1c091b88a6c936a83bd7b098662760a87868d12452529bad0d178fb36147345"` | | +| controller.image.digest | string | `"sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407"` | | +| controller.image.digestChroot | string | `"sha256:e35d5ab487861b9d419c570e3530589229224a0762c7b4d2e2222434abb8d988"` | | | controller.image.image | string | `"ingress-nginx/controller"` | | | controller.image.pullPolicy | string | `"IfNotPresent"` | | | controller.image.registry | string | `"registry.k8s.io"` | | | controller.image.runAsUser | int | `101` | | -| controller.image.tag | string | `"v1.5.1"` | | +| controller.image.tag | string | `"v1.7.1"` | | | controller.ingressClass | string | `"nginx"` | For backwards compatibility with ingress.class annotation, use ingressClass. Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation | | controller.ingressClassByName | bool | `false` | Process IngressClass per name (additionally as per spec.controller). | | controller.ingressClassResource.controllerValue | string | `"k8s.io/ingress-nginx"` | Controller-value of the controller that is processing this ingressClass | @@ -377,6 +354,7 @@ Kubernetes: `>=1.20.0-0` | controller.metrics.prometheusRule.rules | list | `[]` | | | controller.metrics.service.annotations | object | `{}` | | | controller.metrics.service.externalIPs | list | `[]` | List of IP addresses at which the stats-exporter service is available # Ref: https://kubernetes.io/docs/user-guide/services/#external-ips # | +| controller.metrics.service.labels | object | `{}` | Labels to be added to the metrics service resource | | controller.metrics.service.loadBalancerSourceRanges | list | `[]` | | | controller.metrics.service.nameSuffix | string | `"metrics"` | - Suffix to be used to name the metrics service | | controller.metrics.service.servicePort | int | `10254` | | @@ -395,7 +373,7 @@ Kubernetes: `>=1.20.0-0` | controller.nodeSelector | object | `{"kubernetes.io/os":"linux"}` | Node labels for controller pod assignment # Ref: https://kubernetes.io/docs/user-guide/node-selection/ # | | controller.opentelemetry.containerSecurityContext.allowPrivilegeEscalation | bool | `false` | | | controller.opentelemetry.enabled | bool | `false` | | -| controller.opentelemetry.image | string | `"registry.k8s.io/ingress-nginx/opentelemetry:v20230107-helm-chart-4.4.2-2-g96b3d2165@sha256:331b9bebd6acfcd2d3048abbdd86555f5be76b7e3d0b5af4300b04235c6056c9"` | | +| controller.opentelemetry.image | string | `"registry.k8s.io/ingress-nginx/opentelemetry:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:40f766ac4a9832f36f217bb0e98d44c8d38faeccbfe861fbc1a76af7e9ab257f"` | | | controller.podAnnotations | object | `{}` | Annotations to be added to controller pods # | | controller.podLabels | object | `{}` | Labels to add to the pod container metadata | | controller.podSecurityContext | object | `{}` | Security Context policies for controller pods | @@ -413,7 +391,7 @@ Kubernetes: `>=1.20.0-0` | controller.readinessProbe.successThreshold | int | `1` | | | controller.readinessProbe.timeoutSeconds | int | `1` | | | controller.replicaCount | int | `1` | | -| controller.reportNodeInternalIp | bool | `false` | Bare-metal considerations via the host network https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#via-the-host-network Ingress status was blank because there is no Service exposing the NGINX Ingress controller in a configuration using the host network, the default --publish-service flag used in standard cloud setups does not apply | +| controller.reportNodeInternalIp | bool | `false` | Bare-metal considerations via the host network https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#via-the-host-network Ingress status was blank because there is no Service exposing the Ingress-Nginx Controller in a configuration using the host network, the default --publish-service flag used in standard cloud setups does not apply | | controller.resources.requests.cpu | string | `"100m"` | | | controller.resources.requests.memory | string | `"90Mi"` | | | controller.scope.enabled | bool | `false` | Enable 'scope' or not | @@ -430,6 +408,8 @@ Kubernetes: `>=1.20.0-0` | controller.service.internal.enabled | bool | `false` | Enables an additional internal load balancer (besides the external one). | | controller.service.internal.loadBalancerSourceRanges | list | `[]` | Restrict access For LoadBalancer service. Defaults to 0.0.0.0/0. | | controller.service.internal.nameSuffix | string | `"internal"` | - Suffix to be used to name the internal service | +| controller.service.internal.ports | object | `{}` | Custom port mapping for internal service | +| controller.service.internal.targetPorts | object | `{}` | Custom target port mapping for internal service | | controller.service.ipFamilies | list | `["IPv4"]` | List of IP families (e.g. IPv4, IPv6) assigned to the service. This field is usually assigned automatically based on cluster configuration and the ipFamilyPolicy field. # Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/ | | controller.service.ipFamilyPolicy | string | `"SingleStack"` | Represents the dual-stack-ness requested or required by this Service. Possible values are SingleStack, PreferDualStack or RequireDualStack. The ipFamilies and clusterIPs fields depend on the value of this field. # Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/ | | controller.service.labels | object | `{}` | | @@ -509,7 +489,7 @@ Kubernetes: `>=1.20.0-0` | defaultBackend.serviceAccount.name | string | `""` | | | defaultBackend.tolerations | list | `[]` | Node tolerations for server scheduling to nodes with taints # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ # | | defaultBackend.updateStrategy | object | `{}` | The update strategy to apply to the Deployment or DaemonSet # | -| dhParam | string | `nil` | A base64-encoded Diffie-Hellman parameter. This can be generated with: `openssl dhparam 4096 2> /dev/null | base64` # Ref: https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/ssl-dh-param | +| dhParam | string | `""` | A base64-encoded Diffie-Hellman parameter. This can be generated with: `openssl dhparam 4096 2> /dev/null | base64` # Ref: https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/ssl-dh-param | | imagePullSecrets | list | `[]` | Optional array of imagePullSecrets containing private registry credentials # Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ | | podSecurityPolicy.enabled | bool | `false` | | | portNamePrefix | string | `""` | Prefix for TCP and UDP ports names in ingress controller service # Some cloud providers, like Yandex Cloud may have a requirements for a port name regex to support cloud load balancer integration | @@ -522,4 +502,3 @@ Kubernetes: `>=1.20.0-0` | serviceAccount.name | string | `""` | | | tcp | object | `{}` | TCP service key-value pairs # Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md # | | udp | object | `{}` | UDP service key-value pairs # Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md # | - diff --git a/charts/ingress-nginx/README.md.gotmpl b/charts/ingress-nginx/README.md.gotmpl index 78e4f38d4..4a35a40b3 100644 --- a/charts/ingress-nginx/README.md.gotmpl +++ b/charts/ingress-nginx/README.md.gotmpl @@ -7,10 +7,7 @@ To use, add `ingressClassName: nginx` spec field or the `kubernetes.io/ingress.c This chart bootstraps an ingress-nginx deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. -## Prerequisites - -- Chart version 3.x.x: Kubernetes v1.16+ -- Chart version 4.x.x and above: Kubernetes v1.19+ +{{ template "chart.requirementsSection" . }} ## Get Repo Info @@ -51,10 +48,6 @@ helm upgrade [RELEASE_NAME] [CHART] --install _See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ -### Upgrading With Zero Downtime in Production - -By default the ingress-nginx controller has service interruptions whenever it's pods are restarted or redeployed. In order to fix that, see the excellent blog post by Lindsay Landry from Codecademy: [Kubernetes: Nginx and Zero Downtime in Production](https://medium.com/codecademy-engineering/kubernetes-nginx-and-zero-downtime-in-production-2c910c6a5ed8). - ### Migrating from stable/nginx-ingress There are two main ways to migrate a release from `stable/nginx-ingress` to `ingress-nginx/ingress-nginx` chart: @@ -65,7 +58,6 @@ There are two main ways to migrate a release from `stable/nginx-ingress` to `ing 1. Redirect your DNS traffic from the old controller to the new controller 1. Log traffic from both controllers during this changeover 1. [Uninstall](#uninstall-chart) the old controller once traffic has fully drained from it - 1. For details on all of these steps see [Upgrading With Zero Downtime in Production](#upgrading-with-zero-downtime-in-production) Note that there are some different and upgraded configurations between the two charts, described by Rimas Mocevicius from JFrog in the "Upgrading to ingress-nginx Helm chart" section of [Migrating from Helm chart nginx-ingress to ingress-nginx](https://rimusz.net/migrating-to-ingress-nginx). As the `ingress-nginx/ingress-nginx` chart continues to update, you will want to check current differences by running [helm configuration](#configuration) commands on both charts. @@ -84,14 +76,14 @@ else it would make it impossible to evacuate a node. See [gh issue #7127](https: ### Prometheus Metrics -The Nginx ingress controller can export Prometheus metrics, by setting `controller.metrics.enabled` to `true`. +The Ingress-Nginx Controller can export Prometheus metrics, by setting `controller.metrics.enabled` to `true`. You can add Prometheus annotations to the metrics service using `controller.metrics.service.annotations`. Alternatively, if you use the Prometheus Operator, you can enable ServiceMonitor creation using `controller.metrics.serviceMonitor.enabled`. And set `controller.metrics.serviceMonitor.additionalLabels.release="prometheus"`. "release=prometheus" should match the label configured in the prometheus servicemonitor ( see `kubectl get servicemonitor prometheus-kube-prom-prometheus -oyaml -n prometheus`) ### ingress-nginx nginx\_status page/stats server -Previous versions of this chart had a `controller.stats.*` configuration block, which is now obsolete due to the following changes in nginx ingress controller: +Previous versions of this chart had a `controller.stats.*` configuration block, which is now obsolete due to the following changes in Ingress-Nginx Controller: - In [0.16.1](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0161), the vts (virtual host traffic status) dashboard was removed - In [0.23.0](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230), the status page at port 18080 is now a unix socket webserver only available at localhost. @@ -99,7 +91,7 @@ Previous versions of this chart had a `controller.stats.*` configuration block, ### ExternalDNS Service Configuration -Add an [ExternalDNS](https://github.com/kubernetes-incubator/external-dns) annotation to the LoadBalancer service: +Add an [ExternalDNS](https://github.com/kubernetes-sigs/external-dns) annotation to the LoadBalancer service: ```yaml controller: @@ -125,19 +117,6 @@ controller: service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600' ``` -### AWS route53-mapper - -To configure the LoadBalancer service with the [route53-mapper addon](https://github.com/kubernetes/kops/blob/be63d4f1a7a46daaf1c4c482527328236850f111/addons/route53-mapper/README.md), add the `domainName` annotation and `dns` label: - -```yaml -controller: - service: - labels: - dns: "route53" - annotations: - domainName: "kubernetes-example.com" -``` - ### Additional Internal Load Balancer This setup is useful when you need both external and internal load balancers but don't want to have multiple ingress controllers and multiple ingress objects per application. @@ -211,7 +190,7 @@ Optionally you can set `controller.service.loadBalancerIP` if you need a static ### Ingress Admission Webhooks -With nginx-ingress-controller version 0.25+, the nginx ingress controller pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent bad ingress from being added to the cluster. +With nginx-ingress-controller version 0.25+, the Ingress-Nginx Controller pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent bad ingress from being added to the cluster. **This feature is enabled by default since 0.31.0.** With nginx-ingress-controller in 0.25.* work only with kubernetes 1.14+, 0.26 fix [this issue](https://github.com/kubernetes/ingress-nginx/pull/4521) @@ -220,14 +199,14 @@ With nginx-ingress-controller in 0.25.* work only with kubernetes 1.14+, 0.26 fi A validating and configuration requires the endpoint to which the request is sent to use TLS. It is possible to set up custom certificates to do this, but in most cases, a self-signed certificate is enough. The setup of this component requires some more complex orchestration when using helm. The steps are created to be idempotent and to allow turning the feature on and off without running into helm quirks. 1. A pre-install hook provisions a certificate into the same namespace using a format compatible with provisioning using end user certificates. If the certificate already exists, the hook exits. -2. The ingress nginx controller pod is configured to use a TLS proxy container, which will load that certificate. +2. The Ingress-Nginx Controller pod is configured to use a TLS proxy container, which will load that certificate. 3. Validating and Mutating webhook configurations are created in the cluster. 4. A post-install hook reads the CA from the secret created by step 1 and patches the Validating and Mutating webhook configurations. This process will allow a custom CA provisioned by some other process to also be patched into the webhook configurations. The chosen failure policy is also patched into the webhook configurations #### Alternatives It should be possible to use [cert-manager/cert-manager](https://github.com/cert-manager/cert-manager) if a more complete solution is required. -You can enable automatic self-signed TLS certificate provisioning via cert-manager by setting the `controller.admissionWebhooks.certManager.enable` value to true. +You can enable automatic self-signed TLS certificate provisioning via cert-manager by setting the `controller.admissionWebhooks.certManager.enabled` value to true. Please ensure that cert-manager is correctly installed and configured. @@ -243,8 +222,4 @@ Detail of how and why are in [this issue](https://github.com/helm/charts/pull/13 As of version `1.26.0` of this chart, by simply not providing any clusterIP value, `invalid: spec.clusterIP: Invalid value: "": field is immutable` will no longer occur since `clusterIP: ""` will not be rendered. -{{ template "chart.requirementsSection" . }} - {{ template "chart.valuesSection" . }} - -{{ template "helm-docs.versionFooter" . }} diff --git a/charts/ingress-nginx/changelog/.gitkeep b/charts/ingress-nginx/changelog/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/charts/ingress-nginx/changelog/Changelog-4.5.2.md b/charts/ingress-nginx/changelog/Changelog-4.5.2.md new file mode 100644 index 000000000..b6d8a3b0c --- /dev/null +++ b/charts/ingress-nginx/changelog/Changelog-4.5.2.md @@ -0,0 +1,13 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### 4.5.2 + +* add lint on chart before release (#9570) +* ci: remove setup-helm step (#9404) +* feat(helm): Optionally use cert-manager instead admission patch (#9279) +* run helm release on main only and when the chart/value changes only (#9290) +* Update Ingress-Nginx version controller-v1.6.4 + +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.4.3...helm-chart-4.5.2 diff --git a/charts/ingress-nginx/changelog/Changelog-4.6.0.md b/charts/ingress-nginx/changelog/Changelog-4.6.0.md new file mode 100644 index 000000000..469aaba8c --- /dev/null +++ b/charts/ingress-nginx/changelog/Changelog-4.6.0.md @@ -0,0 +1,24 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### 4.5.3 + +* docs(helm): fix value key in readme for enabling certManager (#9640) +* Upgrade alpine 3.17.2 +* Upgrade golang 1.20 +* Drop testing/support for Kubernetes 1.23 +* docs(helm): fix value key in readme for enabling certManager (#9640) +* Update Ingress-Nginx version controller-v1.7.0 +* feat: OpenTelemetry module integration (#9062) +* canary-weight-total annotation ignored in rule backends (#9729) +* fix controller psp's volume config (#9740) +* Fix several Helm YAML issues with extraModules and extraInitContainers (#9709) +* Chart: Drop `controller.headers`, rework DH param secret. (#9659) +* Deployment/DaemonSet: Label pods using `ingress-nginx.labels`. (#9732) +* HPA: autoscaling/v2beta1 deprecated, bump apiVersion to v2 for defaultBackend (#9731) +* Fix incorrect annotation name in upstream hashing configuration (#9617) + +* Update Ingress-Nginx version controller-v1.7.0 + +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.5.2...helm-chart-4.6.0 diff --git a/charts/ingress-nginx/changelog/Changelog-4.6.1.md b/charts/ingress-nginx/changelog/Changelog-4.6.1.md new file mode 100644 index 000000000..57d99b8db --- /dev/null +++ b/charts/ingress-nginx/changelog/Changelog-4.6.1.md @@ -0,0 +1,11 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### 4.6.1 + +* [helm] Support custom port configuration for internal service (#9846) +* Adding resource type to default HPA configuration to resolve issues with Terraform helm chart usage (#9803) +* Update Ingress-Nginx version controller-v1.7.1 + +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.6.0...helm-chart-4.6.1 diff --git a/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml b/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml index fd8df8de5..663ccb9d1 100644 --- a/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml +++ b/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml @@ -11,3 +11,9 @@ controller: enabled: true annotations: service.beta.kubernetes.io/aws-load-balancer-internal: "true" + ports: + http: 443 + https: 80 + targetPorts: + http: 443 + https: 80 diff --git a/charts/ingress-nginx/templates/NOTES.txt b/charts/ingress-nginx/templates/NOTES.txt index 8985c56c0..9fe35c785 100644 --- a/charts/ingress-nginx/templates/NOTES.txt +++ b/charts/ingress-nginx/templates/NOTES.txt @@ -71,10 +71,3 @@ If TLS is enabled for the Ingress, a Secret containing the certificate and key m tls.crt: tls.key: type: kubernetes.io/tls - -{{- if .Values.controller.headers }} -################################################################################# -###### WARNING: `controller.headers` has been deprecated! ##### -###### It has been renamed to `controller.proxySetHeaders`. ##### -################################################################################# -{{- end }} diff --git a/charts/ingress-nginx/templates/_params.tpl b/charts/ingress-nginx/templates/_params.tpl index cdda63891..504d7b6cf 100644 --- a/charts/ingress-nginx/templates/_params.tpl +++ b/charts/ingress-nginx/templates/_params.tpl @@ -51,6 +51,9 @@ {{- if .Values.controller.watchIngressWithoutClass }} - --watch-ingress-without-class=true {{- end }} +{{- if .Values.controller.enableTopologyAwareRouting }} +- --enable-topology-aware-routing=true +{{- end }} {{- range $key, $value := .Values.controller.extraArgs }} {{- /* Accept keys without values or with false as value */}} {{- if eq ($value | quote | len) 2 }} diff --git a/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml b/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml index f8d15faf9..38feb721f 100644 --- a/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml +++ b/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml @@ -1,4 +1,4 @@ -{{- if or .Values.controller.proxySetHeaders .Values.controller.headers -}} +{{- if .Values.controller.proxySetHeaders -}} apiVersion: v1 kind: ConfigMap metadata: @@ -10,10 +10,5 @@ metadata: {{- end }} name: {{ include "ingress-nginx.fullname" . }}-custom-proxy-headers namespace: {{ .Release.Namespace }} -data: -{{- if .Values.controller.proxySetHeaders }} -{{ toYaml .Values.controller.proxySetHeaders | indent 2 }} -{{ else if and .Values.controller.headers (not .Values.controller.proxySetHeaders) }} -{{ toYaml .Values.controller.headers | indent 2 }} -{{- end }} +data: {{ toYaml .Values.controller.proxySetHeaders | nindent 2 }} {{- end }} diff --git a/charts/ingress-nginx/templates/controller-configmap.yaml b/charts/ingress-nginx/templates/controller-configmap.yaml index f28b26e1e..9ec2b8369 100644 --- a/charts/ingress-nginx/templates/controller-configmap.yaml +++ b/charts/ingress-nginx/templates/controller-configmap.yaml @@ -17,13 +17,12 @@ data: {{- if .Values.controller.addHeaders }} add-headers: {{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-custom-add-headers {{- end }} -{{- if or .Values.controller.proxySetHeaders .Values.controller.headers }} +{{- if .Values.controller.proxySetHeaders }} proxy-set-headers: {{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-custom-proxy-headers {{- end }} {{- if .Values.dhParam }} - ssl-dh-param: {{ printf "%s/%s" .Release.Namespace (include "ingress-nginx.controller.fullname" .) }} + ssl-dh-param: {{ .Release.Namespace }}/{{ include "ingress-nginx.controller.fullname" . }} {{- end }} {{- range $key, $value := .Values.controller.config }} - {{- $key | nindent 2 }}: {{ $value | quote }} + {{- $key | nindent 2 }}: {{ $value | quote }} {{- end }} - diff --git a/charts/ingress-nginx/templates/controller-daemonset.yaml b/charts/ingress-nginx/templates/controller-daemonset.yaml index 3a8180c44..08a3fb34c 100644 --- a/charts/ingress-nginx/templates/controller-daemonset.yaml +++ b/charts/ingress-nginx/templates/controller-daemonset.yaml @@ -33,7 +33,7 @@ spec: {{- end }} {{- end }} labels: - {{- include "ingress-nginx.selectorLabels" . | nindent 8 }} + {{- include "ingress-nginx.labels" . | nindent 8 }} app.kubernetes.io/component: controller {{- with .Values.controller.labels }} {{- toYaml . | nindent 8 }} @@ -178,17 +178,14 @@ spec: {{- end }} {{- if .Values.controller.extraModules }} {{- range .Values.controller.extraModules }} - - name: {{ .Name }} - image: {{ .Image }} - command: ['sh', '-c', '/usr/local/bin/init_module.sh'] - {{- if (or $.Values.controller.containerSecurityContext .containerSecurityContext) }} - securityContext: {{ .containerSecurityContext | default $.Values.controller.containerSecurityContext | toYaml | nindent 14 }} - {{- end }} - volumeMounts: - - name: modules - mountPath: /modules_mount + {{ $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }} +{{ include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | indent 8 }} {{- end }} {{- end }} + {{- if .Values.controller.opentelemetry.enabled}} + {{ $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }} + {{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext) | nindent 8}} + {{- end}} {{- end }} {{- if .Values.controller.hostNetwork }} hostNetwork: {{ .Values.controller.hostNetwork }} @@ -207,9 +204,9 @@ spec: {{- end }} serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }} terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} - {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes .Values.controller.extraModules) }} + {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }} volumes: - {{- if .Values.controller.extraModules }} + {{- if (or .Values.controller.extraModules .Values.controller.opentelemetry.enabled)}} - name: modules emptyDir: {} {{- end }} diff --git a/charts/ingress-nginx/templates/controller-deployment.yaml b/charts/ingress-nginx/templates/controller-deployment.yaml index 55b704a6b..4889932f3 100644 --- a/charts/ingress-nginx/templates/controller-deployment.yaml +++ b/charts/ingress-nginx/templates/controller-deployment.yaml @@ -37,7 +37,7 @@ spec: {{- end }} {{- end }} labels: - {{- include "ingress-nginx.selectorLabels" . | nindent 8 }} + {{- include "ingress-nginx.labels" . | nindent 8 }} app.kubernetes.io/component: controller {{- with .Values.controller.labels }} {{- toYaml . | nindent 8 }} @@ -185,7 +185,7 @@ spec: {{- if .Values.controller.extraModules }} {{- range .Values.controller.extraModules }} {{ $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }} - {{- include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext | nindent 8) }} +{{ include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | indent 8 }} {{- end }} {{- end }} {{- if .Values.controller.opentelemetry.enabled}} diff --git a/charts/ingress-nginx/templates/controller-hpa.yaml b/charts/ingress-nginx/templates/controller-hpa.yaml index d1e78bdfc..96a91f533 100644 --- a/charts/ingress-nginx/templates/controller-hpa.yaml +++ b/charts/ingress-nginx/templates/controller-hpa.yaml @@ -1,12 +1,9 @@ -{{- if and .Values.controller.autoscaling.enabled (or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both")) -}} -{{- if not .Values.controller.keda.enabled }} - -apiVersion: {{ .Values.controller.autoscaling.apiVersion }} +{{- if and (or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both")) .Values.controller.autoscaling.enabled (not .Values.controller.keda.enabled) -}} +apiVersion: {{ ternary "autoscaling/v2" "autoscaling/v2beta2" (.Capabilities.APIVersions.Has "autoscaling/v2") }} kind: HorizontalPodAutoscaler metadata: - annotations: {{- with .Values.controller.autoscaling.annotations }} - {{- toYaml . | trimSuffix "\n" | nindent 4 }} + annotations: {{ toYaml . | nindent 4 }} {{- end }} labels: {{- include "ingress-nginx.labels" . | nindent 4 }} @@ -24,14 +21,6 @@ spec: minReplicas: {{ .Values.controller.autoscaling.minReplicas }} maxReplicas: {{ .Values.controller.autoscaling.maxReplicas }} metrics: - {{- with .Values.controller.autoscaling.targetMemoryUtilizationPercentage }} - - type: Resource - resource: - name: memory - target: - type: Utilization - averageUtilization: {{ . }} - {{- end }} {{- with .Values.controller.autoscaling.targetCPUUtilizationPercentage }} - type: Resource resource: @@ -40,6 +29,14 @@ spec: type: Utilization averageUtilization: {{ . }} {{- end }} + {{- with .Values.controller.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} {{- with .Values.controller.autoscalingTemplate }} {{- toYaml . | nindent 2 }} {{- end }} @@ -48,5 +45,3 @@ spec: {{- toYaml . | nindent 4 }} {{- end }} {{- end }} -{{- end }} - diff --git a/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml b/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml index 899d3cc5d..230307cd7 100644 --- a/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml +++ b/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml @@ -10,6 +10,9 @@ metadata: {{- end }} name: {{ include "ingress-nginx.controller.fullname" . }} namespace: {{ .Release.Namespace }} + {{- if .Values.controller.annotations }} + annotations: {{ toYaml .Values.controller.annotations | nindent 4 }} + {{- end }} spec: selector: matchLabels: diff --git a/charts/ingress-nginx/templates/controller-psp.yaml b/charts/ingress-nginx/templates/controller-psp.yaml index 2e0499ce9..3c499b9d4 100644 --- a/charts/ingress-nginx/templates/controller-psp.yaml +++ b/charts/ingress-nginx/templates/controller-psp.yaml @@ -28,9 +28,9 @@ spec: volumes: - 'configMap' - 'emptyDir' - #- 'projected' + - 'projected' - 'secret' - #- 'downwardAPI' + - 'downwardAPI' {{- if .Values.controller.hostNetwork }} hostNetwork: {{ .Values.controller.hostNetwork }} {{- end }} diff --git a/charts/ingress-nginx/templates/controller-secret.yaml b/charts/ingress-nginx/templates/controller-secret.yaml new file mode 100644 index 000000000..f3744232f --- /dev/null +++ b/charts/ingress-nginx/templates/controller-secret.yaml @@ -0,0 +1,15 @@ +{{- if .Values.dhParam -}} +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} +data: + dhparam.pem: {{ .Values.dhParam }} +{{- end }} diff --git a/charts/ingress-nginx/templates/controller-service-internal.yaml b/charts/ingress-nginx/templates/controller-service-internal.yaml index 968fc9f05..b0e5c919c 100644 --- a/charts/ingress-nginx/templates/controller-service-internal.yaml +++ b/charts/ingress-nginx/templates/controller-service-internal.yaml @@ -29,9 +29,9 @@ spec: {{- $setNodePorts := (or (eq .Values.controller.service.type "NodePort") (eq .Values.controller.service.type "LoadBalancer")) }} {{- if .Values.controller.service.enableHttp }} - name: http - port: {{ .Values.controller.service.ports.http }} + port: {{ .Values.controller.service.internal.ports.http | default .Values.controller.service.ports.http }} protocol: TCP - targetPort: {{ .Values.controller.service.targetPorts.http }} + targetPort: {{ .Values.controller.service.internal.targetPorts.http | default .Values.controller.service.targetPorts.http }} {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }} appProtocol: http {{- end }} @@ -41,9 +41,9 @@ spec: {{- end }} {{- if .Values.controller.service.enableHttps }} - name: https - port: {{ .Values.controller.service.ports.https }} + port: {{ .Values.controller.service.internal.ports.https | default .Values.controller.service.ports.https }} protocol: TCP - targetPort: {{ .Values.controller.service.targetPorts.https }} + targetPort: {{ .Values.controller.service.internal.targetPorts.https | default .Values.controller.service.targetPorts.https }} {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }} appProtocol: https {{- end }} diff --git a/charts/ingress-nginx/templates/default-backend-hpa.yaml b/charts/ingress-nginx/templates/default-backend-hpa.yaml index 594d26525..faaf4fa75 100644 --- a/charts/ingress-nginx/templates/default-backend-hpa.yaml +++ b/charts/ingress-nginx/templates/default-backend-hpa.yaml @@ -1,33 +1,40 @@ {{- if and .Values.defaultBackend.enabled .Values.defaultBackend.autoscaling.enabled }} -apiVersion: autoscaling/v2beta1 +apiVersion: {{ ternary "autoscaling/v2" "autoscaling/v2beta2" (.Capabilities.APIVersions.Has "autoscaling/v2") }} kind: HorizontalPodAutoscaler metadata: + {{- with .Values.defaultBackend.autoscaling.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} labels: {{- include "ingress-nginx.labels" . | nindent 4 }} app.kubernetes.io/component: default-backend {{- with .Values.defaultBackend.labels }} {{- toYaml . | nindent 4 }} {{- end }} - name: {{ template "ingress-nginx.defaultBackend.fullname" . }} + name: {{ include "ingress-nginx.defaultBackend.fullname" . }} namespace: {{ .Release.Namespace }} spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment - name: {{ template "ingress-nginx.defaultBackend.fullname" . }} + name: {{ include "ingress-nginx.defaultBackend.fullname" . }} minReplicas: {{ .Values.defaultBackend.autoscaling.minReplicas }} maxReplicas: {{ .Values.defaultBackend.autoscaling.maxReplicas }} metrics: -{{- with .Values.defaultBackend.autoscaling.targetCPUUtilizationPercentage }} - - type: Resource - resource: - name: cpu - targetAverageUtilization: {{ . }} -{{- end }} -{{- with .Values.defaultBackend.autoscaling.targetMemoryUtilizationPercentage }} - - type: Resource - resource: - name: memory - targetAverageUtilization: {{ . }} -{{- end }} + {{- with .Values.defaultBackend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} + {{- with .Values.defaultBackend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} {{- end }} diff --git a/charts/ingress-nginx/templates/dh-param-secret.yaml b/charts/ingress-nginx/templates/dh-param-secret.yaml deleted file mode 100644 index 12e7a4f63..000000000 --- a/charts/ingress-nginx/templates/dh-param-secret.yaml +++ /dev/null @@ -1,10 +0,0 @@ -{{- with .Values.dhParam -}} -apiVersion: v1 -kind: Secret -metadata: - name: {{ include "ingress-nginx.controller.fullname" $ }} - labels: - {{- include "ingress-nginx.labels" $ | nindent 4 }} -data: - dhparam.pem: {{ . }} -{{- end }} diff --git a/charts/ingress-nginx/values.yaml b/charts/ingress-nginx/values.yaml index 2caa406fa..e9d37b5f8 100644 --- a/charts/ingress-nginx/values.yaml +++ b/charts/ingress-nginx/values.yaml @@ -23,71 +23,58 @@ controller: ## for backwards compatibility consider setting the full image url via the repository value below ## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail ## repository: - tag: "v1.5.1" - digest: sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629 - digestChroot: sha256:c1c091b88a6c936a83bd7b098662760a87868d12452529bad0d178fb36147345 + tag: "v1.7.1" + digest: sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407 + digestChroot: sha256:e35d5ab487861b9d419c570e3530589229224a0762c7b4d2e2222434abb8d988 pullPolicy: IfNotPresent # www-data -> uid 101 runAsUser: 101 allowPrivilegeEscalation: true - # -- Use an existing PSP instead of creating one existingPsp: "" - # -- Configures the controller container name containerName: controller - # -- Configures the ports that the nginx-controller listens on containerPort: http: 80 https: 443 - # -- Will add custom configuration options to Nginx https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/ config: {} - # -- Annotations to be added to the controller config configuration configmap. configAnnotations: {} - # -- Will add custom headers before sending traffic to backends according to https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/custom-headers proxySetHeaders: {} - # -- Will add custom headers before sending response traffic to the client according to: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#add-headers addHeaders: {} - # -- Optionally customize the pod dnsConfig. dnsConfig: {} - # -- Optionally customize the pod hostname. hostname: {} - # -- Optionally change this to ClusterFirstWithHostNet in case you have 'hostNetwork: true'. # By default, while using host network, name resolution uses the host's DNS. If you wish nginx-controller # to keep resolving names inside the k8s network, use ClusterFirstWithHostNet. dnsPolicy: ClusterFirst - # -- Bare-metal considerations via the host network https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#via-the-host-network - # Ingress status was blank because there is no Service exposing the NGINX Ingress controller in a configuration using the host network, the default --publish-service flag used in standard cloud setups does not apply + # Ingress status was blank because there is no Service exposing the Ingress-Nginx Controller in a configuration using the host network, the default --publish-service flag used in standard cloud setups does not apply reportNodeInternalIp: false - # -- Process Ingress objects without ingressClass annotation/ingressClassName field # Overrides value for --watch-ingress-without-class flag of the controller binary # Defaults to false watchIngressWithoutClass: false - # -- Process IngressClass per name (additionally as per spec.controller). ingressClassByName: false - + # -- This configuration enables Topology Aware Routing feature, used together with service annotation service.kubernetes.io/topology-aware-hints="auto" + # Defaults to false + enableTopologyAwareRouting: false # -- This configuration defines if Ingress Controller should allow users to set # their own *-snippet annotations, otherwise this is forbidden / dropped # when users add those annotations. # Global snippets in ConfigMap are still respected allowSnippetAnnotations: true - # -- Required for use with CNI based kubernetes installations (such as ones set up by kubeadm), # since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920 # is merged hostNetwork: false - ## Use host ports 80 and 443 ## Disabled by default hostPort: @@ -98,10 +85,8 @@ controller: http: 80 # -- 'hostPort' https port https: 443 - # -- Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader' electionID: "" - ## This section refers to the creation of the IngressClass resource ## IngressClass resources are supported since k8s >= 1.18 and required since k8s >= 1.19 ingressClassResource: @@ -113,23 +98,19 @@ controller: default: false # -- Controller-value of the controller that is processing this ingressClass 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 # does not require extra parameters. parameters: {} - # -- For backwards compatibility with ingress.class annotation, use ingressClass. # Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation ingressClass: nginx - # -- Labels to add to the pod container metadata podLabels: {} # key: value # -- Security Context policies for controller pods podSecurityContext: {} - # -- See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for notes on enabling and using sysctls sysctls: {} # sysctls: @@ -145,7 +126,6 @@ controller: # -- Allows overriding of the publish service to bind to # Must be / pathOverride: "" - # Limit the scope of the controller to a specific namespace scope: # -- Enable 'scope' or not @@ -155,27 +135,22 @@ controller: # -- When scope.enabled == false, instead of watching all namespaces, we watching namespaces whose labels # only match with namespaceSelector. Format like foo=bar. Defaults to empty, means watching all namespaces. namespaceSelector: "" - # -- Allows customization of the configmap / nginx-configmap namespace; defaults to $(POD_NAMESPACE) configMapNamespace: "" - tcp: # -- Allows customization of the tcp-services-configmap; defaults to $(POD_NAMESPACE) configMapNamespace: "" # -- Annotations to be added to the tcp config configmap annotations: {} - udp: # -- Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE) configMapNamespace: "" # -- Annotations to be added to the udp config configmap annotations: {} - # -- Maxmind license key to download GeoLite2 Databases. ## https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases maxmindLicenseKey: "" - - # -- Additional command line arguments to pass to nginx-ingress-controller + # -- Additional command line arguments to pass to Ingress-Nginx Controller # E.g. to specify the default SSL certificate you can use extraArgs: {} ## extraArgs: @@ -192,7 +167,6 @@ controller: # -- Use a `DaemonSet` or `Deployment` kind: Deployment - # -- Annotations to be added to the controller Deployment or DaemonSet ## annotations: {} @@ -204,7 +178,6 @@ controller: # keel.sh/policy: patch # keel.sh/trigger: poll - # -- The update strategy to apply to the Deployment or DaemonSet ## updateStrategy: {} @@ -215,8 +188,6 @@ controller: # -- `minReadySeconds` to avoid killing pods before we are ready ## minReadySeconds: 0 - - # -- Node tolerations for server scheduling to nodes with taints ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ ## @@ -230,68 +201,66 @@ controller: ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity ## affinity: {} - # # An example of preferred pod anti-affinity, weight is in the range 1-100 - # podAntiAffinity: - # preferredDuringSchedulingIgnoredDuringExecution: - # - weight: 100 - # podAffinityTerm: - # labelSelector: - # matchExpressions: - # - key: app.kubernetes.io/name - # operator: In - # values: - # - ingress-nginx - # - key: app.kubernetes.io/instance - # operator: In - # values: - # - ingress-nginx - # - key: app.kubernetes.io/component - # operator: In - # values: - # - controller - # topologyKey: kubernetes.io/hostname + # # An example of preferred pod anti-affinity, weight is in the range 1-100 + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - weight: 100 + # podAffinityTerm: + # labelSelector: + # matchExpressions: + # - key: app.kubernetes.io/name + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/instance + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/component + # operator: In + # values: + # - controller + # topologyKey: kubernetes.io/hostname - # # An example of required pod anti-affinity - # podAntiAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # - labelSelector: - # matchExpressions: - # - key: app.kubernetes.io/name - # operator: In - # values: - # - ingress-nginx - # - key: app.kubernetes.io/instance - # operator: In - # values: - # - ingress-nginx - # - key: app.kubernetes.io/component - # operator: In - # values: - # - controller - # topologyKey: "kubernetes.io/hostname" + # # An example of required pod anti-affinity + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - labelSelector: + # matchExpressions: + # - key: app.kubernetes.io/name + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/instance + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/component + # operator: In + # values: + # - controller + # topologyKey: "kubernetes.io/hostname" # -- Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in. ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ ## topologySpreadConstraints: [] - # - maxSkew: 1 - # topologyKey: topology.kubernetes.io/zone - # whenUnsatisfiable: DoNotSchedule - # labelSelector: - # matchLabels: - # app.kubernetes.io/instance: ingress-nginx-internal + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app.kubernetes.io/instance: ingress-nginx-internal # -- `terminationGracePeriodSeconds` to avoid killing pods before we are ready ## wait up to five minutes for the drain of connections ## terminationGracePeriodSeconds: 300 - # -- Node labels for controller pod assignment ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ ## nodeSelector: kubernetes.io/os: linux - ## Liveness and readiness probe values ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes ## @@ -328,23 +297,17 @@ controller: timeoutSeconds: 1 successThreshold: 1 failureThreshold: 3 - - # -- Path of the health check endpoint. All requests received on the port defined by # the healthz-port parameter are forwarded internally to this path. healthCheckPath: "/healthz" - # -- Address to bind the health check endpoint. # It is better to set this option to the internal node address - # if the ingress nginx controller is running in the `hostNetwork: true` mode. + # if the Ingress-Nginx Controller is running in the `hostNetwork: true` mode. healthCheckHost: "" - # -- Annotations to be added to controller pods ## podAnnotations: {} - replicaCount: 1 - # -- Define either 'minAvailable' or 'maxUnavailable', never both. minAvailable: 1 # -- Define either 'minAvailable' or 'maxUnavailable', never both. @@ -355,16 +318,14 @@ controller: ## Ideally, there should be no limits. ## https://engineering.indeedblog.com/blog/2019/12/cpu-throttling-regression-fix/ resources: - ## limits: - ## cpu: 100m - ## memory: 90Mi + ## limits: + ## cpu: 100m + ## memory: 90Mi requests: cpu: 100m memory: 90Mi - # Mutually exclusive with keda autoscaling autoscaling: - apiVersion: autoscaling/v2 enabled: false annotations: {} minReplicas: 1 @@ -372,19 +333,18 @@ controller: targetCPUUtilizationPercentage: 50 targetMemoryUtilizationPercentage: 50 behavior: {} - # scaleDown: - # stabilizationWindowSeconds: 300 - # policies: - # - type: Pods - # value: 1 - # periodSeconds: 180 - # scaleUp: - # stabilizationWindowSeconds: 300 - # policies: - # - type: Pods - # value: 2 - # periodSeconds: 60 - + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 2 + # periodSeconds: 60 autoscalingTemplate: [] # Custom or additional autoscaling metrics # ref: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-custom-metrics @@ -414,40 +374,36 @@ controller: # annotations: # key: value triggers: [] - # - type: prometheus - # metadata: - # serverAddress: http://:9090 - # metricName: http_requests_total - # threshold: '100' - # query: sum(rate(http_requests_total{deployment="my-deployment"}[2m])) + # - type: prometheus + # metadata: + # serverAddress: http://:9090 + # metricName: http_requests_total + # threshold: '100' + # query: sum(rate(http_requests_total{deployment="my-deployment"}[2m])) behavior: {} - # scaleDown: - # stabilizationWindowSeconds: 300 - # policies: - # - type: Pods - # value: 1 - # periodSeconds: 180 - # scaleUp: - # stabilizationWindowSeconds: 300 - # policies: - # - type: Pods - # value: 2 - # periodSeconds: 60 - + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 2 + # periodSeconds: 60 # -- Enable mimalloc as a drop-in replacement for malloc. ## ref: https://github.com/microsoft/mimalloc ## enableMimalloc: true - ## Override NGINX template customTemplate: configMapName: "" configMapKey: "" - service: enabled: true - # -- If enabled is adding an appProtocol option for Kubernetes service. An appProtocol field replacing annotations that were # using for setting a backend protocol. Here is an example for AWS: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http # It allows choosing the protocol for each backend specified in the Kubernetes service. @@ -455,7 +411,6 @@ controller: # Will be ignored for Kubernetes versions older than 1.20 ## appProtocol: true - annotations: {} labels: {} # clusterIP: "" @@ -464,14 +419,11 @@ controller: ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips ## externalIPs: [] - # -- Used by cloud providers to connect the resulting `LoadBalancer` to a pre-existing static IP according to https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer loadBalancerIP: "" loadBalancerSourceRanges: [] - enableHttp: true enableHttps: true - ## Set external traffic policy to: "Local" to preserve source IP on providers supporting it. ## Ref: https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typeloadbalancer # externalTrafficPolicy: "" @@ -490,23 +442,18 @@ controller: # The ipFamilies and clusterIPs fields depend on the value of this field. ## Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/ ipFamilyPolicy: "SingleStack" - # -- List of IP families (e.g. IPv4, IPv6) assigned to the service. This field is usually assigned automatically # based on cluster configuration and the ipFamilyPolicy field. ## Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/ ipFamilies: - IPv4 - ports: http: 80 https: 443 - targetPorts: http: http https: https - type: LoadBalancer - ## type: NodePort ## nodePorts: ## http: 32080 @@ -518,21 +465,17 @@ controller: https: "" tcp: {} udp: {} - external: enabled: true - internal: # -- Enables an additional internal load balancer (besides the external one). enabled: false # -- Annotations are mandatory for the load balancer to come up. Varies with the cloud service. annotations: {} - # loadBalancerIP: "" # -- Restrict access For LoadBalancer service. Defaults to 0.0.0.0/0. loadBalancerSourceRanges: [] - ## Set external traffic policy to: "Local" to preserve source IP on ## providers supporting it ## Ref: https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typeloadbalancer @@ -541,10 +484,19 @@ controller: # --- Suffix to be used to name the internal service nameSuffix: internal + # -- Custom port mapping for internal service + ports: {} + # http: 80 + # https: 443 + + # -- Custom target port mapping for internal service + targetPorts: {} + # http: http + # https: https + # shareProcessNamespace enables process namespace sharing within the pod. # This can be used for example to signal log rotation using `kill -USR1` from a sidecar. shareProcessNamespace: false - # -- Additional containers to be added to the controller pod. # See https://github.com/lemonldap-ng-controller/lemonldap-ng-controller as example. extraContainers: [] @@ -587,6 +539,8 @@ controller: # -- Modules, which are mounted into the core nginx image. See values.yaml for a sample to add opentelemetry module extraModules: [] + # - name: mytestmodule + # image: registry.k8s.io/ingress-nginx/mytestmodule # containerSecurityContext: # allowPrivilegeEscalation: false # @@ -596,10 +550,9 @@ controller: opentelemetry: enabled: false - image: registry.k8s.io/ingress-nginx/opentelemetry:v20230107-helm-chart-4.4.2-2-g96b3d2165@sha256:331b9bebd6acfcd2d3048abbdd86555f5be76b7e3d0b5af4300b04235c6056c9 + image: registry.k8s.io/ingress-nginx/opentelemetry:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:40f766ac4a9832f36f217bb0e98d44c8d38faeccbfe861fbc1a76af7e9ab257f containerSecurityContext: allowPrivilegeEscalation: false - admissionWebhooks: annotations: {} # ignore-check.kube-linter.io/no-read-only-rootfs: "This deployment needs write access to root filesystem". @@ -626,11 +579,9 @@ controller: objectSelector: {} # -- Labels to be added to admission webhooks labels: {} - # -- Use an existing PSP instead of creating one existingPsp: "" networkPolicyEnabled: false - service: annotations: {} # clusterIP: "" @@ -641,23 +592,20 @@ controller: nameSuffix: admission servicePort: 443 type: ClusterIP - createSecretJob: securityContext: allowPrivilegeEscalation: false resources: {} - # limits: - # cpu: 10m - # memory: 20Mi - # requests: - # cpu: 10m - # memory: 20Mi - + # limits: + # cpu: 10m + # memory: 20Mi + # requests: + # cpu: 10m + # memory: 20Mi patchWebhookJob: securityContext: allowPrivilegeEscalation: false resources: {} - patch: enabled: true image: @@ -666,8 +614,8 @@ controller: ## for backwards compatibility consider setting the full image url via the repository value below ## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail ## repository: - tag: v20220916-gd32f8c343 - digest: sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + tag: v20230312-helm-chart-4.5.2-28-g66a760794 + digest: sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f pullPolicy: IfNotPresent # -- Provide a priority class name to the webhook patching job ## @@ -682,37 +630,36 @@ controller: runAsNonRoot: true runAsUser: 2000 fsGroup: 2000 - # Use certmanager to generate webhook certs certManager: enabled: false # self-signed root certificate rootCert: - duration: "" # default to be 5y + # default to be 5y + duration: "" admissionCert: - duration: "" # default to be 1y - # issuerRef: - # name: "issuer" - # kind: "ClusterIssuer" - + # default to be 1y + duration: "" + # issuerRef: + # name: "issuer" + # kind: "ClusterIssuer" metrics: port: 10254 portName: metrics # if this port is changed, change healthz-port: in extraArgs: accordingly enabled: false - service: annotations: {} # prometheus.io/scrape: "true" # prometheus.io/port: "10254" - + # -- Labels to be added to the metrics service resource + labels: {} # clusterIP: "" # -- List of IP addresses at which the stats-exporter service is available ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips ## externalIPs: [] - # loadBalancerIP: "" loadBalancerSourceRanges: [] # --- Suffix to be used to name the metrics service @@ -721,7 +668,6 @@ controller: type: ClusterIP # externalTrafficPolicy: "" # nodePort: "" - serviceMonitor: enabled: false additionalLabels: {} @@ -738,46 +684,44 @@ controller: targetLabels: [] relabelings: [] metricRelabelings: [] - prometheusRule: enabled: false additionalLabels: {} # namespace: "" rules: [] - # # These are just examples rules, please adapt them to your needs - # - alert: NGINXConfigFailed - # expr: count(nginx_ingress_controller_config_last_reload_successful == 0) > 0 - # for: 1s - # labels: - # severity: critical - # annotations: - # description: bad ingress config - nginx config test failed - # summary: uninstall the latest ingress changes to allow config reloads to resume - # - alert: NGINXCertificateExpiry - # expr: (avg(nginx_ingress_controller_ssl_expire_time_seconds) by (host) - time()) < 604800 - # for: 1s - # labels: - # severity: critical - # annotations: - # description: ssl certificate(s) will expire in less then a week - # summary: renew expiring certificates to avoid downtime - # - alert: NGINXTooMany500s - # expr: 100 * ( sum( nginx_ingress_controller_requests{status=~"5.+"} ) / sum(nginx_ingress_controller_requests) ) > 5 - # for: 1m - # labels: - # severity: warning - # annotations: - # description: Too many 5XXs - # summary: More than 5% of all requests returned 5XX, this requires your attention - # - alert: NGINXTooMany400s - # expr: 100 * ( sum( nginx_ingress_controller_requests{status=~"4.+"} ) / sum(nginx_ingress_controller_requests) ) > 5 - # for: 1m - # labels: - # severity: warning - # annotations: - # description: Too many 4XXs - # summary: More than 5% of all requests returned 4XX, this requires your attention - + # # These are just examples rules, please adapt them to your needs + # - alert: NGINXConfigFailed + # expr: count(nginx_ingress_controller_config_last_reload_successful == 0) > 0 + # for: 1s + # labels: + # severity: critical + # annotations: + # description: bad ingress config - nginx config test failed + # summary: uninstall the latest ingress changes to allow config reloads to resume + # - alert: NGINXCertificateExpiry + # expr: (avg(nginx_ingress_controller_ssl_expire_time_seconds) by (host) - time()) < 604800 + # for: 1s + # labels: + # severity: critical + # annotations: + # description: ssl certificate(s) will expire in less then a week + # summary: renew expiring certificates to avoid downtime + # - alert: NGINXTooMany500s + # expr: 100 * ( sum( nginx_ingress_controller_requests{status=~"5.+"} ) / sum(nginx_ingress_controller_requests) ) > 5 + # for: 1m + # labels: + # severity: warning + # annotations: + # description: Too many 5XXs + # summary: More than 5% of all requests returned 5XX, this requires your attention + # - alert: NGINXTooMany400s + # expr: 100 * ( sum( nginx_ingress_controller_requests{status=~"4.+"} ) / sum(nginx_ingress_controller_requests) ) > 5 + # for: 1m + # labels: + # severity: warning + # annotations: + # description: Too many 4XXs + # summary: More than 5% of all requests returned 4XX, this requires your attention # -- Improve connection draining when ingress controller pod is deleted using a lifecycle hook: # With this new hook, we increased the default terminationGracePeriodSeconds from 30 seconds # to 300, allowing the draining of connections up to five minutes. @@ -790,19 +734,15 @@ controller: exec: command: - /wait-shutdown - priorityClassName: "" - # -- Rollback limit ## revisionHistoryLimit: 10 - ## Default 404 backend ## defaultBackend: ## enabled: false - name: defaultbackend image: registry: registry.k8s.io @@ -817,21 +757,16 @@ defaultBackend: runAsNonRoot: true readOnlyRootFilesystem: true allowPrivilegeEscalation: false - # -- Use an existing PSP instead of creating one existingPsp: "" - extraArgs: {} - serviceAccount: create: true name: "" automountServiceAccountToken: true # -- Additional environment variables to set for defaultBackend pods extraEnvs: [] - port: 8080 - ## Readiness and liveness probes for default backend ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ ## @@ -847,7 +782,6 @@ defaultBackend: periodSeconds: 5 successThreshold: 1 timeoutSeconds: 5 - # -- The update strategy to apply to the Deployment or DaemonSet ## updateStrategy: {} @@ -858,7 +792,6 @@ defaultBackend: # -- `minReadySeconds` to avoid killing pods before we are ready ## minReadySeconds: 0 - # -- Node tolerations for server scheduling to nodes with taints ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ ## @@ -869,19 +802,16 @@ defaultBackend: # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" affinity: {} - # -- Security Context policies for controller pods # See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for # notes on enabling and using sysctls ## podSecurityContext: {} - # -- Security Context policies for controller main container. # See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for # notes on enabling and using sysctls ## containerSecurityContext: {} - # -- Labels to add to the pod container metadata podLabels: {} # key: value @@ -891,15 +821,11 @@ defaultBackend: ## nodeSelector: kubernetes.io/os: linux - # -- Annotations to be added to default backend pods ## podAnnotations: {} - replicaCount: 1 - minAvailable: 1 - resources: {} # limits: # cpu: 10m @@ -925,43 +851,35 @@ defaultBackend: maxReplicas: 2 targetCPUUtilizationPercentage: 50 targetMemoryUtilizationPercentage: 50 - service: annotations: {} - # clusterIP: "" # -- List of IP addresses at which the default backend service is available ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips ## externalIPs: [] - # loadBalancerIP: "" loadBalancerSourceRanges: [] servicePort: 80 type: ClusterIP - priorityClassName: "" # -- Labels to be added to the default backend resources labels: {} - ## Enable RBAC as per https://github.com/kubernetes/ingress-nginx/blob/main/docs/deploy/rbac.md and https://github.com/kubernetes/ingress-nginx/issues/266 rbac: create: true scope: false - ## If true, create & use Pod Security Policy resources ## https://kubernetes.io/docs/concepts/policy/pod-security-policy/ podSecurityPolicy: enabled: false - serviceAccount: create: true name: "" automountServiceAccountToken: true # -- Annotations for the controller service account annotations: {} - # -- Optional array of imagePullSecrets containing private registry credentials ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ imagePullSecrets: [] @@ -982,8 +900,7 @@ udp: {} # -- Prefix for TCP and UDP ports names in ingress controller service ## Some cloud providers, like Yandex Cloud may have a requirements for a port name regex to support cloud load balancer integration portNamePrefix: "" - # -- (string) A base64-encoded Diffie-Hellman parameter. # This can be generated with: `openssl dhparam 4096 2> /dev/null | base64` ## Ref: https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/ssl-dh-param -dhParam: +dhParam: "" diff --git a/cmd/dataplane/main.go b/cmd/dataplane/main.go index 0ab978429..6fd559e4d 100644 --- a/cmd/dataplane/main.go +++ b/cmd/dataplane/main.go @@ -70,7 +70,7 @@ func main() { mc := metric.NewDummyCollector() if conf.EnableMetrics { // TODO: Ingress class is not a part of dataplane anymore - mc, err = metric.NewCollector(conf.MetricsPerHost, conf.ReportStatusClasses, reg, conf.IngressClassConfiguration.Controller, *conf.MetricsBuckets) + mc, err = metric.NewCollector(conf.MetricsPerHost, conf.ReportStatusClasses, reg, conf.IngressClassConfiguration.Controller, *conf.MetricsBuckets, conf.ExcludeSocketMetrics) if err != nil { klog.Fatalf("Error creating prometheus collector: %v", err) } diff --git a/cmd/nginx/main.go b/cmd/nginx/main.go index 9f0973ec9..48dd933dc 100644 --- a/cmd/nginx/main.go +++ b/cmd/nginx/main.go @@ -133,7 +133,7 @@ func main() { mc := metric.NewDummyCollector() if conf.EnableMetrics { - mc, err = metric.NewCollector(conf.MetricsPerHost, conf.ReportStatusClasses, reg, conf.IngressClassConfiguration.Controller, *conf.MetricsBuckets) + mc, err = metric.NewCollector(conf.MetricsPerHost, conf.ReportStatusClasses, reg, conf.IngressClassConfiguration.Controller, *conf.MetricsBuckets, conf.ExcludeSocketMetrics) if err != nil { klog.Fatalf("Error creating prometheus collector: %v", err) } diff --git a/cmd/plugin/commands/backends/backends.go b/cmd/plugin/commands/backends/backends.go index 341c62a9c..afc98e4d6 100644 --- a/cmd/plugin/commands/backends/backends.go +++ b/cmd/plugin/commands/backends/backends.go @@ -30,7 +30,7 @@ import ( // CreateCommand creates and returns this cobra subcommand func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { - var pod, deployment, selector *string + var pod, deployment, selector, container *string cmd := &cobra.Command{ Use: "backends", Short: "Inspect the dynamic backend information of an ingress-nginx instance", @@ -47,7 +47,7 @@ func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { return fmt.Errorf("--list and --backend cannot both be specified") } - util.PrintError(backends(flags, *pod, *deployment, *selector, backend, onlyList)) + util.PrintError(backends(flags, *pod, *deployment, *selector, *container, backend, onlyList)) return nil }, } @@ -55,6 +55,7 @@ func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { pod = util.AddPodFlag(cmd) deployment = util.AddDeploymentFlag(cmd) selector = util.AddSelectorFlag(cmd) + container = util.AddContainerFlag(cmd) cmd.Flags().String("backend", "", "Output only the information for the given backend") cmd.Flags().Bool("list", false, "Output a newline-separated list of backend names") @@ -62,7 +63,7 @@ func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { return cmd } -func backends(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string, backend string, onlyList bool) error { +func backends(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string, container string, backend string, onlyList bool) error { var command []string if onlyList { command = []string{"/dbg", "backends", "list"} @@ -77,7 +78,7 @@ func backends(flags *genericclioptions.ConfigFlags, podName string, deployment s return err } - out, err := kubectl.PodExecString(flags, &pod, command) + out, err := kubectl.PodExecString(flags, &pod, container, command) if err != nil { return err } diff --git a/cmd/plugin/commands/certs/certs.go b/cmd/plugin/commands/certs/certs.go index 07fd08ad3..88b721ee3 100644 --- a/cmd/plugin/commands/certs/certs.go +++ b/cmd/plugin/commands/certs/certs.go @@ -30,7 +30,7 @@ import ( // CreateCommand creates and returns this cobra subcommand func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { - var pod, deployment, selector *string + var pod, deployment, selector, container *string cmd := &cobra.Command{ Use: "certs", Short: "Output the certificate data stored in an ingress-nginx pod", @@ -40,7 +40,7 @@ func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { return err } - util.PrintError(certs(flags, *pod, *deployment, *selector, host)) + util.PrintError(certs(flags, *pod, *deployment, *selector, *container, host)) return nil }, } @@ -50,11 +50,12 @@ func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { pod = util.AddPodFlag(cmd) deployment = util.AddDeploymentFlag(cmd) selector = util.AddSelectorFlag(cmd) + container = util.AddContainerFlag(cmd) return cmd } -func certs(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string, host string) error { +func certs(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string, container string, host string) error { command := []string{"/dbg", "certs", "get", host} pod, err := request.ChoosePod(flags, podName, deployment, selector) @@ -62,7 +63,7 @@ func certs(flags *genericclioptions.ConfigFlags, podName string, deployment stri return err } - out, err := kubectl.PodExecString(flags, &pod, command) + out, err := kubectl.PodExecString(flags, &pod, container, command) if err != nil { return err } diff --git a/cmd/plugin/commands/conf/conf.go b/cmd/plugin/commands/conf/conf.go index 5caa2a649..a7f03a062 100644 --- a/cmd/plugin/commands/conf/conf.go +++ b/cmd/plugin/commands/conf/conf.go @@ -32,7 +32,7 @@ import ( // CreateCommand creates and returns this cobra subcommand func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { - var pod, deployment, selector *string + var pod, deployment, selector, container *string cmd := &cobra.Command{ Use: "conf", Short: "Inspect the generated nginx.conf", @@ -42,7 +42,7 @@ func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { return err } - util.PrintError(conf(flags, host, *pod, *deployment, *selector)) + util.PrintError(conf(flags, host, *pod, *deployment, *selector, *container)) return nil }, } @@ -50,17 +50,18 @@ func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { pod = util.AddPodFlag(cmd) deployment = util.AddDeploymentFlag(cmd) selector = util.AddSelectorFlag(cmd) + container = util.AddContainerFlag(cmd) return cmd } -func conf(flags *genericclioptions.ConfigFlags, host string, podName string, deployment string, selector string) error { +func conf(flags *genericclioptions.ConfigFlags, host string, podName string, deployment string, selector string, container string) error { pod, err := request.ChoosePod(flags, podName, deployment, selector) if err != nil { return err } - nginxConf, err := kubectl.PodExecString(flags, &pod, []string{"/dbg", "conf"}) + nginxConf, err := kubectl.PodExecString(flags, &pod, container, []string{"/dbg", "conf"}) if err != nil { return err } diff --git a/cmd/plugin/commands/exec/exec.go b/cmd/plugin/commands/exec/exec.go index 5f1a31913..f06aaeb23 100644 --- a/cmd/plugin/commands/exec/exec.go +++ b/cmd/plugin/commands/exec/exec.go @@ -29,19 +29,21 @@ import ( // CreateCommand creates and returns this cobra subcommand func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { opts := execFlags{} - var pod, deployment, selector *string + var pod, deployment, selector, container *string cmd := &cobra.Command{ Use: "exec", Short: "Execute a command inside an ingress-nginx pod", RunE: func(cmd *cobra.Command, args []string) error { - util.PrintError(exec(flags, *pod, *deployment, *selector, args, opts)) + util.PrintError(exec(flags, *pod, *deployment, *selector, *container, args, opts)) return nil }, } pod = util.AddPodFlag(cmd) deployment = util.AddDeploymentFlag(cmd) selector = util.AddSelectorFlag(cmd) + container = util.AddContainerFlag(cmd) + cmd.Flags().BoolVarP(&opts.TTY, "tty", "t", false, "Stdin is a TTY") cmd.Flags().BoolVarP(&opts.Stdin, "stdin", "i", false, "Pass stdin to the container") @@ -53,7 +55,7 @@ type execFlags struct { Stdin bool } -func exec(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string, cmd []string, opts execFlags) error { +func exec(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string, container string, cmd []string, opts execFlags) error { pod, err := request.ChoosePod(flags, podName, deployment, selector) if err != nil { return err @@ -67,7 +69,7 @@ func exec(flags *genericclioptions.ConfigFlags, podName string, deployment strin args = append(args, "-i") } - args = append(args, []string{"-n", pod.Namespace, pod.Name, "--"}...) + args = append(args, []string{"-n", pod.Namespace, "-c", container, pod.Name, "--"}...) args = append(args, cmd...) return kubectl.Exec(flags, args) } diff --git a/cmd/plugin/commands/general/general.go b/cmd/plugin/commands/general/general.go index 44e02ca88..fa6c1301f 100644 --- a/cmd/plugin/commands/general/general.go +++ b/cmd/plugin/commands/general/general.go @@ -30,29 +30,30 @@ import ( // CreateCommand creates and returns this cobra subcommand func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { - var pod, deployment, selector *string + var pod, deployment, selector, container *string cmd := &cobra.Command{ Use: "general", Short: "Inspect the other dynamic ingress-nginx information", RunE: func(cmd *cobra.Command, args []string) error { - util.PrintError(general(flags, *pod, *deployment, *selector)) + util.PrintError(general(flags, *pod, *deployment, *selector, *container)) return nil }, } pod = util.AddPodFlag(cmd) deployment = util.AddDeploymentFlag(cmd) selector = util.AddSelectorFlag(cmd) + container = util.AddContainerFlag(cmd) return cmd } -func general(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string) error { +func general(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string, container string) error { pod, err := request.ChoosePod(flags, podName, deployment, selector) if err != nil { return err } - out, err := kubectl.PodExecString(flags, &pod, []string{"/dbg", "general"}) + out, err := kubectl.PodExecString(flags, &pod, container, []string{"/dbg", "general"}) if err != nil { return err } diff --git a/cmd/plugin/commands/logs/logs.go b/cmd/plugin/commands/logs/logs.go index 55cd008dc..56f4fc640 100644 --- a/cmd/plugin/commands/logs/logs.go +++ b/cmd/plugin/commands/logs/logs.go @@ -31,19 +31,20 @@ import ( // CreateCommand creates and returns this cobra subcommand func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { o := logsFlags{} - var pod, deployment, selector *string + var pod, deployment, selector, container *string cmd := &cobra.Command{ Use: "logs", Short: "Get the kubernetes logs for an ingress-nginx pod", RunE: func(cmd *cobra.Command, args []string) error { - util.PrintError(logs(flags, *pod, *deployment, *selector, o)) + util.PrintError(logs(flags, *pod, *deployment, *selector, *container, o)) return nil }, } pod = util.AddPodFlag(cmd) deployment = util.AddDeploymentFlag(cmd) selector = util.AddSelectorFlag(cmd) + container = util.AddContainerFlag(cmd) cmd.Flags().BoolVarP(&o.Follow, "follow", "f", o.Follow, "Specify if the logs should be streamed.") cmd.Flags().BoolVar(&o.Timestamps, "timestamps", o.Timestamps, "Include timestamps on each line in the log output") @@ -94,13 +95,13 @@ func (o *logsFlags) toStrings() []string { return r } -func logs(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string, opts logsFlags) error { +func logs(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string, container string, opts logsFlags) error { pod, err := request.ChoosePod(flags, podName, deployment, selector) if err != nil { return err } - cmd := []string{"logs", "-n", pod.Namespace, pod.Name} + cmd := []string{"logs", "-n", pod.Namespace, "-c", container, pod.Name} cmd = append(cmd, opts.toStrings()...) return kubectl.Exec(flags, cmd) } diff --git a/cmd/plugin/commands/ssh/ssh.go b/cmd/plugin/commands/ssh/ssh.go index 5e8b49fac..fe1b3e9fe 100644 --- a/cmd/plugin/commands/ssh/ssh.go +++ b/cmd/plugin/commands/ssh/ssh.go @@ -28,27 +28,28 @@ import ( // CreateCommand creates and returns this cobra subcommand func CreateCommand(flags *genericclioptions.ConfigFlags) *cobra.Command { - var pod, deployment, selector *string + var pod, deployment, selector, container *string cmd := &cobra.Command{ Use: "ssh", Short: "ssh into a running ingress-nginx pod", RunE: func(cmd *cobra.Command, args []string) error { - util.PrintError(ssh(flags, *pod, *deployment, *selector)) + util.PrintError(ssh(flags, *pod, *deployment, *selector, *container)) return nil }, } pod = util.AddPodFlag(cmd) deployment = util.AddDeploymentFlag(cmd) selector = util.AddSelectorFlag(cmd) + container = util.AddContainerFlag(cmd) return cmd } -func ssh(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string) error { +func ssh(flags *genericclioptions.ConfigFlags, podName string, deployment string, selector string, container string) error { pod, err := request.ChoosePod(flags, podName, deployment, selector) if err != nil { return err } - return kubectl.Exec(flags, []string{"exec", "-it", "-n", pod.Namespace, pod.Name, "--", "/bin/bash"}) + return kubectl.Exec(flags, []string{"exec", "-it", "-n", pod.Namespace, "-c", container, pod.Name, "--", "/bin/bash"}) } diff --git a/cmd/plugin/kubectl/kubectl.go b/cmd/plugin/kubectl/kubectl.go index c11ba5b77..3f31a2104 100644 --- a/cmd/plugin/kubectl/kubectl.go +++ b/cmd/plugin/kubectl/kubectl.go @@ -31,8 +31,8 @@ import ( // PodExecString takes a pod and a command, uses kubectl exec to run the command in the pod // and returns stdout as a string -func PodExecString(flags *genericclioptions.ConfigFlags, pod *apiv1.Pod, args []string) (string, error) { - args = append([]string{"exec", "-n", pod.Namespace, pod.Name}, args...) +func PodExecString(flags *genericclioptions.ConfigFlags, pod *apiv1.Pod, container string, args []string) (string, error) { + args = append([]string{"exec", "-n", pod.Namespace, "-c", container, pod.Name}, args...) return ExecToString(flags, args) } diff --git a/cmd/plugin/util/util.go b/cmd/plugin/util/util.go index cc9882009..e1910140d 100644 --- a/cmd/plugin/util/util.go +++ b/cmd/plugin/util/util.go @@ -31,6 +31,7 @@ import ( const ( DefaultIngressDeploymentName = "ingress-nginx-controller" DefaultIngressServiceName = "ingress-nginx-controller" + DefaultIngressContainerName = "controller" ) // IssuePrefix is the github url that we can append an issue number to to link to it @@ -127,6 +128,13 @@ func AddSelectorFlag(cmd *cobra.Command) *string { return &v } +// AddContainerFlag adds a --container flag to a cobra command +func AddContainerFlag(cmd *cobra.Command) *string { + v := "" + cmd.Flags().StringVar(&v, "container", DefaultIngressContainerName, "The name of the ingress-nginx controller container") + return &v +} + // GetNamespace takes a set of kubectl flag values and returns the namespace we should be operating in func GetNamespace(flags *genericclioptions.ConfigFlags) string { namespace, _, err := flags.ToRawKubeConfigLoader().Namespace() diff --git a/deploy/grafana/dashboards/README.md b/deploy/grafana/dashboards/README.md index 26195583b..e16180c3b 100644 --- a/deploy/grafana/dashboards/README.md +++ b/deploy/grafana/dashboards/README.md @@ -4,7 +4,7 @@ Ingress-nginx supports a rich collection of prometheus metrics. If you have pro This folder contains two dashboards that you can import. -## 1. NGINX Ingress Controller +## 1. Ingress-Nginx Controller ![Dashboard](screenshot.png) diff --git a/deploy/grafana/dashboards/nginx.json b/deploy/grafana/dashboards/nginx.json index 85f93c9eb..3c3205b4a 100644 --- a/deploy/grafana/dashboards/nginx.json +++ b/deploy/grafana/dashboards/nginx.json @@ -1312,7 +1312,7 @@ "targets": [ { "exemplar": true, - "expr": "histogram_quantile(0.80, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\",exported_namespace=\"uat\"}[2m])) by (le))", + "expr": "histogram_quantile(0.80, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le))", "format": "time_series", "hide": false, "instant": false, @@ -1323,7 +1323,7 @@ }, { "exemplar": true, - "expr": "histogram_quantile(0.90, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\",exported_namespace=\"uat\"}[2m])) by (le))", + "expr": "histogram_quantile(0.90, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le))", "format": "time_series", "hide": false, "instant": false, @@ -1335,7 +1335,7 @@ { "editorMode": "code", "exemplar": true, - "expr": "histogram_quantile(0.99, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\",exported_namespace=\"uat\"}[2m])) by (le))", + "expr": "histogram_quantile(0.99, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le))", "format": "time_series", "hide": false, "instant": false, @@ -1377,7 +1377,7 @@ "targets": [ { "exemplar": true, - "expr": "sum(increase(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\",exported_namespace=\"uat\"}[2m])) by (le)", + "expr": "sum(increase(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le)", "format": "heatmap", "interval": "", "legendFormat": "{{le}}", diff --git a/deploy/static/provider/aws/deploy.yaml b/deploy/static/provider/aws/deploy.yaml index fbdf9486a..41006c016 100644 --- a/deploy/static/provider/aws/deploy.yaml +++ b/deploy/static/provider/aws/deploy.yaml @@ -15,7 +15,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx --- @@ -27,7 +27,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx --- @@ -39,7 +39,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx rules: @@ -90,21 +90,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resourceNames: - - ingress-nginx-leader - resources: - - configmaps - verbs: - - get - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - apiGroups: - coordination.k8s.io resourceNames: @@ -144,7 +129,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx rules: @@ -163,7 +148,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx rules: - apiGroups: @@ -245,7 +230,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission rules: - apiGroups: @@ -264,7 +249,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx roleRef: @@ -284,7 +269,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx roleRef: @@ -303,7 +288,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io @@ -322,7 +307,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission roleRef: apiGroup: rbac.authorization.k8s.io @@ -343,7 +328,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx --- @@ -359,7 +344,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -392,7 +377,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller-admission namespace: ingress-nginx spec: @@ -415,7 +400,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -432,6 +417,8 @@ spec: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.7.1 spec: containers: - args: @@ -455,7 +442,7 @@ spec: fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so - image: registry.k8s.io/ingress-nginx/controller:v1.5.1@sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629 + image: registry.k8s.io/ingress-nginx/controller:v1.7.1@sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407 imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -527,7 +514,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create namespace: ingress-nginx spec: @@ -538,7 +525,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create spec: containers: @@ -552,7 +539,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: create securityContext: @@ -574,7 +561,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch namespace: ingress-nginx spec: @@ -585,7 +572,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch spec: containers: @@ -601,7 +588,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: patch securityContext: @@ -623,7 +610,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: nginx spec: controller: k8s.io/ingress-nginx @@ -636,7 +623,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission webhooks: - admissionReviewVersions: diff --git a/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml b/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml index 73ec24286..4e4f9ca9b 100644 --- a/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml +++ b/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml @@ -15,7 +15,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx --- @@ -27,7 +27,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx --- @@ -39,7 +39,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx rules: @@ -90,21 +90,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resourceNames: - - ingress-nginx-leader - resources: - - configmaps - verbs: - - get - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - apiGroups: - coordination.k8s.io resourceNames: @@ -144,7 +129,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx rules: @@ -163,7 +148,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx rules: - apiGroups: @@ -245,7 +230,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission rules: - apiGroups: @@ -264,7 +249,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx roleRef: @@ -284,7 +269,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx roleRef: @@ -303,7 +288,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io @@ -322,7 +307,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission roleRef: apiGroup: rbac.authorization.k8s.io @@ -350,7 +335,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx --- @@ -368,7 +353,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -401,7 +386,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller-admission namespace: ingress-nginx spec: @@ -424,7 +409,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -441,6 +426,8 @@ spec: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.7.1 spec: containers: - args: @@ -464,7 +451,7 @@ spec: fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so - image: registry.k8s.io/ingress-nginx/controller:v1.5.1@sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629 + image: registry.k8s.io/ingress-nginx/controller:v1.7.1@sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407 imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -539,7 +526,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create namespace: ingress-nginx spec: @@ -550,7 +537,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create spec: containers: @@ -564,7 +551,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: create securityContext: @@ -586,7 +573,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch namespace: ingress-nginx spec: @@ -597,7 +584,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch spec: containers: @@ -613,7 +600,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: patch securityContext: @@ -635,7 +622,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: nginx spec: controller: k8s.io/ingress-nginx @@ -648,7 +635,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission webhooks: - admissionReviewVersions: diff --git a/deploy/static/provider/baremetal/deploy.yaml b/deploy/static/provider/baremetal/deploy.yaml index 9e6e905bb..3f015f001 100644 --- a/deploy/static/provider/baremetal/deploy.yaml +++ b/deploy/static/provider/baremetal/deploy.yaml @@ -15,7 +15,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx --- @@ -27,7 +27,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx --- @@ -39,7 +39,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx rules: @@ -90,21 +90,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resourceNames: - - ingress-nginx-leader - resources: - - configmaps - verbs: - - get - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - apiGroups: - coordination.k8s.io resourceNames: @@ -144,7 +129,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx rules: @@ -163,7 +148,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx rules: - apiGroups: @@ -245,7 +230,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission rules: - apiGroups: @@ -264,7 +249,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx roleRef: @@ -284,7 +269,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx roleRef: @@ -303,7 +288,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io @@ -322,7 +307,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission roleRef: apiGroup: rbac.authorization.k8s.io @@ -343,7 +328,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx --- @@ -355,7 +340,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -387,7 +372,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller-admission namespace: ingress-nginx spec: @@ -410,7 +395,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -427,6 +412,8 @@ spec: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.7.1 spec: containers: - args: @@ -449,7 +436,7 @@ spec: fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so - image: registry.k8s.io/ingress-nginx/controller:v1.5.1@sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629 + image: registry.k8s.io/ingress-nginx/controller:v1.7.1@sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407 imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -521,7 +508,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create namespace: ingress-nginx spec: @@ -532,7 +519,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create spec: containers: @@ -546,7 +533,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: create securityContext: @@ -568,7 +555,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch namespace: ingress-nginx spec: @@ -579,7 +566,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch spec: containers: @@ -595,7 +582,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: patch securityContext: @@ -617,7 +604,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: nginx spec: controller: k8s.io/ingress-nginx @@ -630,7 +617,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission webhooks: - admissionReviewVersions: diff --git a/deploy/static/provider/cloud/deploy.yaml b/deploy/static/provider/cloud/deploy.yaml index dd986a55d..a914aca5e 100644 --- a/deploy/static/provider/cloud/deploy.yaml +++ b/deploy/static/provider/cloud/deploy.yaml @@ -15,7 +15,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx --- @@ -27,7 +27,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx --- @@ -39,7 +39,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx rules: @@ -90,21 +90,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resourceNames: - - ingress-nginx-leader - resources: - - configmaps - verbs: - - get - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - apiGroups: - coordination.k8s.io resourceNames: @@ -144,7 +129,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx rules: @@ -163,7 +148,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx rules: - apiGroups: @@ -245,7 +230,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission rules: - apiGroups: @@ -264,7 +249,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx roleRef: @@ -284,7 +269,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx roleRef: @@ -303,7 +288,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io @@ -322,7 +307,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission roleRef: apiGroup: rbac.authorization.k8s.io @@ -343,7 +328,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx --- @@ -355,7 +340,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -388,7 +373,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller-admission namespace: ingress-nginx spec: @@ -411,7 +396,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -428,6 +413,8 @@ spec: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.7.1 spec: containers: - args: @@ -451,7 +438,7 @@ spec: fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so - image: registry.k8s.io/ingress-nginx/controller:v1.5.1@sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629 + image: registry.k8s.io/ingress-nginx/controller:v1.7.1@sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407 imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -523,7 +510,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create namespace: ingress-nginx spec: @@ -534,7 +521,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create spec: containers: @@ -548,7 +535,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: create securityContext: @@ -570,7 +557,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch namespace: ingress-nginx spec: @@ -581,7 +568,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch spec: containers: @@ -597,7 +584,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: patch securityContext: @@ -619,7 +606,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: nginx spec: controller: k8s.io/ingress-nginx @@ -632,7 +619,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission webhooks: - admissionReviewVersions: diff --git a/deploy/static/provider/do/deploy.yaml b/deploy/static/provider/do/deploy.yaml index 64e0366b4..676ae1229 100644 --- a/deploy/static/provider/do/deploy.yaml +++ b/deploy/static/provider/do/deploy.yaml @@ -15,7 +15,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx --- @@ -27,7 +27,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx --- @@ -39,7 +39,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx rules: @@ -90,21 +90,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resourceNames: - - ingress-nginx-leader - resources: - - configmaps - verbs: - - get - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - apiGroups: - coordination.k8s.io resourceNames: @@ -144,7 +129,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx rules: @@ -163,7 +148,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx rules: - apiGroups: @@ -245,7 +230,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission rules: - apiGroups: @@ -264,7 +249,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx roleRef: @@ -284,7 +269,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx roleRef: @@ -303,7 +288,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io @@ -322,7 +307,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission roleRef: apiGroup: rbac.authorization.k8s.io @@ -344,7 +329,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx --- @@ -358,7 +343,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -391,7 +376,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller-admission namespace: ingress-nginx spec: @@ -414,7 +399,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -431,6 +416,8 @@ spec: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.7.1 spec: containers: - args: @@ -454,7 +441,7 @@ spec: fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so - image: registry.k8s.io/ingress-nginx/controller:v1.5.1@sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629 + image: registry.k8s.io/ingress-nginx/controller:v1.7.1@sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407 imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -526,7 +513,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create namespace: ingress-nginx spec: @@ -537,7 +524,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create spec: containers: @@ -551,7 +538,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: create securityContext: @@ -573,7 +560,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch namespace: ingress-nginx spec: @@ -584,7 +571,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch spec: containers: @@ -600,7 +587,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: patch securityContext: @@ -622,7 +609,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: nginx spec: controller: k8s.io/ingress-nginx @@ -635,7 +622,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission webhooks: - admissionReviewVersions: diff --git a/deploy/static/provider/exoscale/deploy.yaml b/deploy/static/provider/exoscale/deploy.yaml index d6a40aed9..e9d3522f0 100644 --- a/deploy/static/provider/exoscale/deploy.yaml +++ b/deploy/static/provider/exoscale/deploy.yaml @@ -15,7 +15,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx --- @@ -27,7 +27,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx --- @@ -39,7 +39,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx rules: @@ -90,21 +90,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resourceNames: - - ingress-nginx-leader - resources: - - configmaps - verbs: - - get - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - apiGroups: - coordination.k8s.io resourceNames: @@ -144,7 +129,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx rules: @@ -163,7 +148,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx rules: - apiGroups: @@ -245,7 +230,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission rules: - apiGroups: @@ -264,7 +249,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx roleRef: @@ -284,7 +269,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx roleRef: @@ -303,7 +288,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io @@ -322,7 +307,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission roleRef: apiGroup: rbac.authorization.k8s.io @@ -343,7 +328,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx --- @@ -364,7 +349,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -397,7 +382,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller-admission namespace: ingress-nginx spec: @@ -420,7 +405,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -437,6 +422,8 @@ spec: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.7.1 spec: containers: - args: @@ -460,7 +447,7 @@ spec: fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so - image: registry.k8s.io/ingress-nginx/controller:v1.5.1@sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629 + image: registry.k8s.io/ingress-nginx/controller:v1.7.1@sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407 imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -532,7 +519,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create namespace: ingress-nginx spec: @@ -543,7 +530,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create spec: containers: @@ -557,7 +544,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: create securityContext: @@ -579,7 +566,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch namespace: ingress-nginx spec: @@ -590,7 +577,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch spec: containers: @@ -606,7 +593,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: patch securityContext: @@ -628,7 +615,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: nginx spec: controller: k8s.io/ingress-nginx @@ -641,7 +628,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission webhooks: - admissionReviewVersions: diff --git a/deploy/static/provider/kind/deploy.yaml b/deploy/static/provider/kind/deploy.yaml index 62ead9e34..6a327b97f 100644 --- a/deploy/static/provider/kind/deploy.yaml +++ b/deploy/static/provider/kind/deploy.yaml @@ -15,7 +15,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx --- @@ -27,7 +27,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx --- @@ -39,7 +39,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx rules: @@ -90,21 +90,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resourceNames: - - ingress-nginx-leader - resources: - - configmaps - verbs: - - get - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - apiGroups: - coordination.k8s.io resourceNames: @@ -144,7 +129,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx rules: @@ -163,7 +148,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx rules: - apiGroups: @@ -245,7 +230,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission rules: - apiGroups: @@ -264,7 +249,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx roleRef: @@ -284,7 +269,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx roleRef: @@ -303,7 +288,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io @@ -322,7 +307,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission roleRef: apiGroup: rbac.authorization.k8s.io @@ -343,7 +328,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx --- @@ -355,7 +340,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -387,7 +372,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller-admission namespace: ingress-nginx spec: @@ -410,7 +395,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -431,6 +416,8 @@ spec: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.7.1 spec: containers: - args: @@ -455,7 +442,7 @@ spec: fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so - image: registry.k8s.io/ingress-nginx/controller:v1.5.1@sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629 + image: registry.k8s.io/ingress-nginx/controller:v1.7.1@sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407 imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -537,7 +524,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create namespace: ingress-nginx spec: @@ -548,7 +535,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create spec: containers: @@ -562,7 +549,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: create securityContext: @@ -584,7 +571,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch namespace: ingress-nginx spec: @@ -595,7 +582,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch spec: containers: @@ -611,7 +598,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: patch securityContext: @@ -633,7 +620,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: nginx spec: controller: k8s.io/ingress-nginx @@ -646,7 +633,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission webhooks: - admissionReviewVersions: diff --git a/deploy/static/provider/scw/deploy.yaml b/deploy/static/provider/scw/deploy.yaml index d52f01489..389e2a920 100644 --- a/deploy/static/provider/scw/deploy.yaml +++ b/deploy/static/provider/scw/deploy.yaml @@ -15,7 +15,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx --- @@ -27,7 +27,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx --- @@ -39,7 +39,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx rules: @@ -90,21 +90,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resourceNames: - - ingress-nginx-leader - resources: - - configmaps - verbs: - - get - - update -- apiGroups: - - "" - resources: - - configmaps - verbs: - - create - apiGroups: - coordination.k8s.io resourceNames: @@ -144,7 +129,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx rules: @@ -163,7 +148,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx rules: - apiGroups: @@ -245,7 +230,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission rules: - apiGroups: @@ -264,7 +249,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx namespace: ingress-nginx roleRef: @@ -284,7 +269,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission namespace: ingress-nginx roleRef: @@ -303,7 +288,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io @@ -322,7 +307,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission roleRef: apiGroup: rbac.authorization.k8s.io @@ -344,7 +329,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx --- @@ -358,7 +343,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -391,7 +376,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller-admission namespace: ingress-nginx spec: @@ -414,7 +399,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-controller namespace: ingress-nginx spec: @@ -431,6 +416,8 @@ spec: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.7.1 spec: containers: - args: @@ -454,7 +441,7 @@ spec: fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so - image: registry.k8s.io/ingress-nginx/controller:v1.5.1@sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629 + image: registry.k8s.io/ingress-nginx/controller:v1.7.1@sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407 imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -526,7 +513,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create namespace: ingress-nginx spec: @@ -537,7 +524,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-create spec: containers: @@ -551,7 +538,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: create securityContext: @@ -573,7 +560,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch namespace: ingress-nginx spec: @@ -584,7 +571,7 @@ spec: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission-patch spec: containers: @@ -600,7 +587,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f imagePullPolicy: IfNotPresent name: patch securityContext: @@ -622,7 +609,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: nginx spec: controller: k8s.io/ingress-nginx @@ -635,7 +622,7 @@ metadata: app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx - app.kubernetes.io/version: 1.5.1 + app.kubernetes.io/version: 1.7.1 name: ingress-nginx-admission webhooks: - admissionReviewVersions: diff --git a/docs/deploy/baremetal.md b/docs/deploy/baremetal.md index 7d8076147..f5ff54174 100644 --- a/docs/deploy/baremetal.md +++ b/docs/deploy/baremetal.md @@ -1,14 +1,14 @@ # Bare-metal considerations In traditional *cloud* environments, where network load balancers are available on-demand, a single Kubernetes manifest -suffices to provide a single point of contact to the NGINX Ingress controller to external clients and, indirectly, to +suffices to provide a single point of contact to the Ingress-Nginx Controller to external clients and, indirectly, to any application running inside the cluster. *Bare-metal* environments lack this commodity, requiring a slightly different setup to offer the same kind of access to external consumers. ![Cloud environment](../images/baremetal/cloud_overview.jpg) ![Bare-metal environment](../images/baremetal/baremetal_overview.jpg) -The rest of this document describes a few recommended approaches to deploying the NGINX Ingress controller inside a +The rest of this document describes a few recommended approaches to deploying the Ingress-Nginx Controller inside a Kubernetes cluster running on bare-metal. ## A pure software solution: MetalLB @@ -30,7 +30,7 @@ the traffic for the `ingress-nginx` Service IP. See [Traffic policies][metallb-t yourself by reading the official documentation thoroughly. MetalLB can be deployed either with a simple Kubernetes manifest or with Helm. The rest of this example assumes MetalLB -was deployed following the [Installation][metallb-install] instructions, and that the NGINX Ingress controller was installed +was deployed following the [Installation][metallb-install] instructions, and that the Ingress-Nginx Controller was installed using the steps described in the [quickstart section of the installation guide][install-quickstart]. MetalLB requires a pool of IP addresses in order to be able to take ownership of the `ingress-nginx` Service. This pool @@ -164,7 +164,7 @@ field of the `ingress-nginx` Service spec to `Local` ([example][preserve-ip]). !!! warning This setting effectively **drops packets** sent to Kubernetes nodes which are not running any instance of the NGINX Ingress controller. Consider [assigning NGINX Pods to specific nodes][pod-assign] in order to control on what nodes - the NGINX Ingress controller should be scheduled or not scheduled. + the Ingress-Nginx Controller should be scheduled or not scheduled. !!! example In a Kubernetes cluster composed of 3 nodes (the external IP is added as an example, in most bare-metal environments @@ -193,7 +193,7 @@ field of the `ingress-nginx` Service spec to `Local` ([example][preserve-ip]). * **Ingress status** -Because NodePort Services do not get a LoadBalancerIP assigned by definition, the NGINX Ingress controller **does not +Because NodePort Services do not get a LoadBalancerIP assigned by definition, the Ingress-Nginx Controller **does not update the status of Ingress objects it manages**. ```console @@ -202,12 +202,12 @@ NAME HOSTS ADDRESS PORTS test-ingress myapp.example.com 80 ``` -Despite the fact there is no load balancer providing a public IP address to the NGINX Ingress controller, it is possible +Despite the fact there is no load balancer providing a public IP address to the Ingress-Nginx Controller, it is possible to force the status update of all managed Ingress objects by setting the `externalIPs` field of the `ingress-nginx` Service. !!! warning - There is more to setting `externalIPs` than just enabling the NGINX Ingress controller to update the status of + There is more to setting `externalIPs` than just enabling the Ingress-Nginx Controller to update the status of Ingress objects. Please read about this option in the [Services][external-ips] page of official Kubernetes documentation as well as the section about [External IPs](#external-ips) in this document for more information. @@ -268,11 +268,11 @@ for generating redirect URLs that take into account the URL used by external cli In a setup where there is no external load balancer available but using NodePorts is not an option, one can configure `ingress-nginx` Pods to use the network of the host they run on instead of a dedicated network namespace. The benefit of -this approach is that the NGINX Ingress controller can bind ports 80 and 443 directly to Kubernetes nodes' network +this approach is that the Ingress-Nginx Controller can bind ports 80 and 443 directly to Kubernetes nodes' network interfaces, without the extra network translation imposed by NodePort Services. !!! note - This approach does not leverage any Service object to expose the NGINX Ingress controller. If the `ingress-nginx` + This approach does not leverage any Service object to expose the Ingress-Nginx Controller. If the `ingress-nginx` Service exists in the target cluster, it is **recommended to delete it**. This can be achieved by enabling the `hostNetwork` option in the Pods' spec. @@ -284,7 +284,7 @@ template: ``` !!! danger "Security considerations" - Enabling this option **exposes every system daemon to the NGINX Ingress controller** on any network interface, + Enabling this option **exposes every system daemon to the Ingress-Nginx Controller** on any network interface, including the host's loopback. Please evaluate the impact this may have on the security of your system carefully. !!! example @@ -299,7 +299,7 @@ template: ingress-nginx-controller-5b4cf5fc6-lzrls 1/1 Running 203.0.113.2 host-2 ``` -One major limitation of this deployment approach is that only **a single NGINX Ingress controller Pod** may be scheduled +One major limitation of this deployment approach is that only **a single Ingress-Nginx Controller Pod** may be scheduled on each cluster node, because binding the same port multiple times on the same network interface is technically impossible. Pods that are unschedulable due to such situation fail with the following event: @@ -312,7 +312,7 @@ Events: Warning FailedScheduling default-scheduler 0/3 nodes are available: 3 node(s) didn't have free ports for the requested pod ports. ``` -One way to ensure only schedulable Pods are created is to deploy the NGINX Ingress controller as a *DaemonSet* instead +One way to ensure only schedulable Pods are created is to deploy the Ingress-Nginx Controller as a *DaemonSet* instead of a traditional Deployment. !!! info @@ -334,7 +334,7 @@ expected to resolve internal names for any reason. * **Ingress status** -Because there is no Service exposing the NGINX Ingress controller in a configuration using the host network, the default +Because there is no Service exposing the Ingress-Nginx Controller in a configuration using the host network, the default `--publish-service` flag used in standard cloud setups **does not apply** and the status of all Ingress objects remains blank. @@ -346,7 +346,7 @@ test-ingress myapp.example.com 80 Instead, and because bare-metal nodes usually don't have an ExternalIP, one has to enable the [`--report-node-internal-ip-address`][cli-args] flag, which sets the status of all Ingress objects to the internal IP -address of all nodes running the NGINX Ingress controller. +address of all nodes running the Ingress-Nginx Controller. !!! example Given a `ingress-nginx-controller` DaemonSet composed of 2 replicas diff --git a/docs/deploy/hardening-guide.md b/docs/deploy/hardening-guide.md index d428bc3aa..cfbdb1466 100644 --- a/docs/deploy/hardening-guide.md +++ b/docs/deploy/hardening-guide.md @@ -94,7 +94,7 @@ This guide refers to chapters in the CIS Benchmark. For full explanation you sho | __5 Request Filtering and Restrictions__||| | | ||| | | __5.1 Access Control__||| | -| 5.1.1 Ensure allow and deny filters limit access to specific IP addresses (Not Scored)| OK/ACTION NEEDED | Depends on use case, geo ip module is compiled into nginx ingress controller, there are several ways to use it | If needed set IP restrictions via annotations or work with config snippets (be careful with lets-encrypt-http-challenge!) | +| 5.1.1 Ensure allow and deny filters limit access to specific IP addresses (Not Scored)| OK/ACTION NEEDED | Depends on use case, geo ip module is compiled into Ingress-Nginx Controller, there are several ways to use it | If needed set IP restrictions via annotations or work with config snippets (be careful with lets-encrypt-http-challenge!) | | 5.1.2 Ensure only whitelisted HTTP methods are allowed (Not Scored) | OK/ACTION NEEDED | Depends on use case| If required it can be set via config snippet| | ||| | | __5.2 Request Limits__||| | diff --git a/docs/deploy/index.md b/docs/deploy/index.md index 29495b5c0..e33ee5dbe 100644 --- a/docs/deploy/index.md +++ b/docs/deploy/index.md @@ -1,6 +1,6 @@ # Installation Guide -There are multiple ways to install the NGINX ingress controller: +There are multiple ways to install the Ingress-Nginx Controller: - with [Helm](https://helm.sh), using the project repository chart; - with `kubectl apply`, using YAML manifests; @@ -62,7 +62,7 @@ It will install the controller in the `ingress-nginx` namespace, creating that n **If you don't have Helm** or if you prefer to use a YAML manifest, you can run the following command instead: ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/cloud/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/cloud/deploy.yaml ``` !!! info @@ -192,9 +192,9 @@ doesn't work, you might have to fall back to the `kubectl port-forward` method d Rancher Desktop provides Kubernetes and Container Management on the desktop. Kubernetes is enabled by default in Rancher Desktop. -Rancher Desktop uses K3s under the hood, which in turn uses Traefik as the default ingress controller for the Kubernetes cluster. To use NGINX ingress controller in place of the default Traefik, disable Traefik from Preference > Kubernetes menu. +Rancher Desktop uses K3s under the hood, which in turn uses Traefik as the default ingress controller for the Kubernetes cluster. To use Ingress-Nginx Controller in place of the default Traefik, disable Traefik from Preference > Kubernetes menu. -Once traefik is disabled, the NGINX ingress controller can be installed on Rancher Desktop using the default [quick start](#quick-start) instructions. Follow the instructions described in the [local testing section](#local-testing) to try a sample. +Once traefik is disabled, the Ingress-Nginx Controller can be installed on Rancher Desktop using the default [quick start](#quick-start) instructions. Follow the instructions described in the [local testing section](#local-testing) to try a sample. ### Cloud deployments @@ -214,7 +214,7 @@ options of various cloud providers. #### AWS -In AWS, we use a Network load balancer (NLB) to expose the NGINX Ingress controller behind a Service of `Type=LoadBalancer`. +In AWS, we use a Network load balancer (NLB) to expose the Ingress-Nginx Controller behind a Service of `Type=LoadBalancer`. !!! info The provided templates illustrate the setup for legacy in-tree service load balancer for AWS NLB. @@ -225,7 +225,7 @@ In AWS, we use a Network load balancer (NLB) to expose the NGINX Ingress control ##### Network Load Balancer (NLB) ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/aws/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/aws/deploy.yaml ``` ##### TLS termination in AWS Load Balancer (NLB) @@ -233,10 +233,10 @@ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/cont By default, TLS is terminated in the ingress controller. But it is also possible to terminate TLS in the Load Balancer. This section explains how to do that on AWS using an NLB. -1. Download the [deploy.yaml](https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml) template +1. Download the [deploy.yaml](https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml) template ```console - wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml + wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/aws/nlb-with-tls-termination/deploy.yaml ``` 2. Edit the file and change the VPC CIDR in use for the Kubernetes cluster: @@ -282,7 +282,7 @@ Then, the ingress controller can be installed like this: ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/cloud/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/cloud/deploy.yaml ``` !!! warning @@ -299,7 +299,7 @@ Proxy-protocol is supported in GCE check the [Official Documentations on how to #### Azure ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/cloud/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/cloud/deploy.yaml ``` More information with regard to Azure annotations for ingress controller can be found in the [official AKS documentation](https://docs.microsoft.com/en-us/azure/aks/ingress-internal-ip#create-an-ingress-controller). @@ -307,7 +307,7 @@ More information with regard to Azure annotations for ingress controller can be #### Digital Ocean ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/do/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/do/deploy.yaml ``` - By default the service object of the ingress-nginx-controller for Digital-Ocean, only configures one annotation. Its this one `service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: "true"`. While this makes the service functional, it was reported that the Digital-Ocean LoadBalancer graphs shows `no data`, unless a few other annotations are also configured. Some of these other annotations require values that can not be generic and hence not forced in a out-of-the-box installation. These annotations and a discussion on them is well documented in [this issue](https://github.com/kubernetes/ingress-nginx/issues/8965). Please refer to the issue to add annotations, with values specific to user, to get graphs of the DO-LB populated with data. @@ -315,7 +315,7 @@ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/cont #### Scaleway ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/scw/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/scw/deploy.yaml ``` #### Exoscale @@ -330,7 +330,7 @@ The full list of annotations supported by Exoscale is available in the Exoscale #### Oracle Cloud Infrastructure ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/cloud/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/cloud/deploy.yaml ``` A @@ -357,7 +357,7 @@ For quick testing, you can use a This should work on almost every cluster, but it will typically use a port in the range 30000-32767. ```console -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/baremetal/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.1/deploy/static/provider/baremetal/deploy.yaml ``` For more information about bare metal deployments (and how to use port 80 instead of a random port in the 30000-32767 range), @@ -419,14 +419,14 @@ Here is how these Ingress versions are supported in Kubernetes: - from Kubernetes 1.19 to 1.21, both `v1beta1` and `v1` Ingress resources are supported - in Kubernetes 1.22 and above, only `v1` Ingress resources are supported -And here is how these Ingress versions are supported in NGINX Ingress Controller: +And here is how these Ingress versions are supported in Ingress-Nginx Controller: - before version 1.0, only `v1beta1` Ingress resources are supported - in version 1.0 and above, only `v1` Ingress resources are As a result, if you're running Kubernetes 1.19 or later, you should be able to use the latest version of the NGINX Ingress Controller; but if you're using an old version of Kubernetes (1.18 or earlier) you will have to use version 0.X -of the NGINX Ingress Controller (e.g. version 0.49). +of the Ingress-Nginx Controller (e.g. version 0.49). -The Helm chart of the NGINX Ingress Controller switched to version 1 in version 4 of the chart. In other words, if +The Helm chart of the Ingress-Nginx Controller switched to version 1 in version 4 of the chart. In other words, if you're running Kubernetes 1.19 or earlier, you should use version 3.X of the chart (this can be done by adding -`--version='<4'` to the `helm install` command). +`--version='<4'` to the `helm install` command ). diff --git a/docs/developer-guide/code-overview.md b/docs/developer-guide/code-overview.md index c55fb69f9..8e872211d 100644 --- a/docs/developer-guide/code-overview.md +++ b/docs/developer-guide/code-overview.md @@ -53,7 +53,7 @@ This code can be found in [internal/file](https://github.com/kubernetes/ingress- #### Ingress functions -Contains all the logics from NGINX Ingress Controller, with some examples being: +Contains all the logics from Ingress-Nginx Controller, with some examples being: * Expected Golang structures that will be used in templates and other parts of the code - [internal/ingress/types.go](https://github.com/kubernetes/ingress-nginx/blob/main/internal/ingress/types.go). * supported annotations and its parsing logics - [internal/ingress/annotations](https://github.com/kubernetes/ingress-nginx/tree/main/internal/ingress/annotations). @@ -104,7 +104,7 @@ Describe here `kubectl plugin`, `dbg`, `waitshutdown` and cover the hack scripts ### kubectl plugin -It containes kubectl plugin for inspecting your ingress-nginx deployments. +It contains kubectl plugin for inspecting your ingress-nginx deployments. This part of code can be found in [cmd/plugin](https://github.com/kubernetes/ingress-nginx/tree/main/cmd/plugin) directory Detail functions flow and available flow can be found in [kubectl-plugin](https://github.com/kubernetes/ingress-nginx/blob/main/docs/kubectl-plugin.md) diff --git a/docs/developer-guide/getting-started.md b/docs/developer-guide/getting-started.md index 9f4be8fcc..4b7ed46f0 100644 --- a/docs/developer-guide/getting-started.md +++ b/docs/developer-guide/getting-started.md @@ -1,6 +1,6 @@ - Developing for NGINX Ingress Controller + Developing for Ingress-Nginx Controller -This document explains how to get started with developing for NGINX Ingress controller. +This document explains how to get started with developing for Ingress-Nginx Controller. For the really new contributors, who want to contribute to the INGRESS-NGINX project, but need help with understanding some basic concepts, that are needed to work with the Kubernetes ingress resource, here is a link to the [New Contributors Guide](https://github.com/kubernetes/ingress-nginx/blob/main/NEW_CONTRIBUTOR.md). diff --git a/docs/e2e-tests.md b/docs/e2e-tests.md index d5aa6cc16..9b3c5f2ff 100644 --- a/docs/e2e-tests.md +++ b/docs/e2e-tests.md @@ -7,11 +7,636 @@ Do not try to edit it manually. +### [[Admission] admission controller](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L35) + +- [reject ingress with global-rate-limit annotations when memcached is not configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L43) +- [should not allow overlaps of host and paths without canary annotations](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L70) +- [should allow overlaps of host and paths with canary annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L87) +- [should block ingress with invalid path](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L108) +- [should return an error if there is an error validating the ingress definition](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L125) +- [should return an error if there is an invalid value in some annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L136) +- [should return an error if there is a forbidden value in some annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L150) +- [should not return an error if the Ingress V1 definition is valid with Ingress Class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L164) +- [should not return an error if the Ingress V1 definition is valid with IngressClass annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L180) +- [should return an error if the Ingress V1 definition contains invalid annotations](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L196) +- [should not return an error for an invalid Ingress when it has unknown class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/admission/admission.go#L207) + +### [affinitymode](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinitymode.go#L31) + +- [Balanced affinity mode should balance](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinitymode.go#L34) +- [Check persistent affinity mode](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinitymode.go#L67) + +### [server-alias](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/alias.go#L29) + +- [should return status code 200 for host 'foo' and 404 for 'bar'](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/alias.go#L36) +- [should return status code 200 for host 'foo' and 'bar'](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/alias.go#L62) +- [should return status code 200 for hosts defined in two ingresses, different path with one alias](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/alias.go#L87) + +### [app-root](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/approot.go#L28) + +- [should redirect to /foo](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/approot.go#L35) + +### [auth-tls-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L29) + +- [should set sslClientCertificate, sslVerifyClient and sslVerifyDepth with auth-tls-secret](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L36) +- [should set valid auth-tls-secret, sslVerify to off, and sslVerifyDepth to 2](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L84) +- [should 302 redirect to error page instead of 400 when auth-tls-error-page is set](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L114) +- [should pass URL-encoded certificate to upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L161) +- [should validate auth-tls-verify-client](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L206) +- [should return 403 using auth-tls-match-cn with no matching CN from client](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L266) +- [should return 200 using auth-tls-match-cn with matching CN from client](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L295) +- [should return 200 using auth-tls-match-cn where atleast one of the regex options matches CN from client](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/authtls.go#L324) + +### [backend-protocol](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L27) + +- [should set backend protocol to https:// and use proxy_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L34) +- [should set backend protocol to $scheme:// and use proxy_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L49) +- [should set backend protocol to grpc:// and use grpc_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L64) +- [should set backend protocol to grpcs:// and use grpc_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L79) +- [should set backend protocol to '' and use fastcgi_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L94) +- [should set backend protocol to '' and use ajp_pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/backendprotocol.go#L109) + +### [client-body-buffer-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L28) + +- [should set client_body_buffer_size to 1000](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L35) +- [should set client_body_buffer_size to 1K](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L57) +- [should set client_body_buffer_size to 1k](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L79) +- [should set client_body_buffer_size to 1m](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L101) +- [should set client_body_buffer_size to 1M](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L123) +- [should not set client_body_buffer_size to invalid 1b](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/clientbodybuffersize.go#L145) + +### [connection-proxy-header](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/connection.go#L29) + +- [set connection header to keep-alive](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/connection.go#L36) + +### [cors-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L28) + +- [should enable cors](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L35) +- [should set cors methods to only allow POST, GET](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L62) +- [should set cors max-age](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L78) +- [should disable cors allow credentials](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L94) +- [should allow origin for cors](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L110) +- [should allow headers for cors](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L137) +- [should expose headers for cors](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L153) +- [should allow - single origin for multiple cors values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L169) +- [should not allow - single origin for multiple cors values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L196) +- [should allow correct origins - single origin for multiple cors values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L216) +- [should not break functionality](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L267) +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L291) +- [should not break functionality with extra domain](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L314) +- [should not match](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L338) +- [should allow - single origin with required port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L358) +- [should not allow - single origin with port and origin without port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L386) +- [should not allow - single origin without port and origin with required port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L405) +- [should allow - matching origin with wildcard origin (2 subdomains)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L425) +- [should not allow - unmatching origin with wildcard origin (2 subdomains)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L468) +- [should allow - matching origin+port with wildcard origin](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L488) +- [should not allow - portless origin with wildcard origin](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L515) +- [should allow correct origins - missing subdomain + origin with wildcard origin and correct origin](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L535) +- [should allow - missing origins (should allow all origins)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/cors.go#L571) + +### [custom-http-errors](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/customhttperrors.go#L34) + +- [configures Nginx correctly](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/customhttperrors.go#L41) + +### [default-backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/default_backend.go#L29) + +- [should use a custom default backend as upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/default_backend.go#L37) + +### [disable-access-log disable-http-access-log disable-stream-access-log](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/disableaccesslog.go#L28) + +- [disable-access-log set access_log off](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/disableaccesslog.go#L35) +- [disable-http-access-log set access_log off](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/disableaccesslog.go#L53) +- [disable-stream-access-log set access_log off](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/disableaccesslog.go#L71) + +### [force-ssl-redirect](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/forcesslredirect.go#L27) + +- [should redirect to https](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/forcesslredirect.go#L34) + +### [from-to-www-redirect](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fromtowwwredirect.go#L31) + +- [should redirect from www HTTP to HTTP](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fromtowwwredirect.go#L38) +- [should redirect from www HTTPS to HTTPS](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fromtowwwredirect.go#L64) + +### [annotation-global-rate-limit](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/globalratelimit.go#L30) + +- [generates correct configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/globalratelimit.go#L38) + +### [backend-protocol - GRPC](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/grpc.go#L40) + +- [should use grpc_pass in the configuration file](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/grpc.go#L43) +- [should return OK for service with backend protocol GRPC](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/grpc.go#L68) +- [authorization metadata should be overwritten by external auth response headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/grpc.go#L126) +- [should return OK for service with backend protocol GRPCS](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/grpc.go#L199) + +### [http2-push-preload](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/http2pushpreload.go#L27) + +- [enable the http2-push-preload directive](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/http2pushpreload.go#L34) + +### [whitelist-source-range](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/ipwhitelist.go#L27) + +- [should set valid ip whitelist range](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/ipwhitelist.go#L34) + +### [Annotation - limit-connections](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/limitconnections.go#L31) + +- [should limit-connections](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/limitconnections.go#L38) + +### [limit-rate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/limitrate.go#L29) + +- [Check limit-rate annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/limitrate.go#L37) + +### [enable-access-log enable-rewrite-log](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/log.go#L27) + +- [set access_log off](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/log.go#L34) +- [set rewrite_log on](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/log.go#L49) + +### [mirror-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/mirror.go#L28) + +- [should set mirror-target to http://localhost/mirror](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/mirror.go#L36) +- [should set mirror-target to https://test.env.com/$request_uri](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/mirror.go#L51) +- [should disable mirror-request-body](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/mirror.go#L67) + +### [modsecurity owasp](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L28) + +- [should enable modsecurity](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L35) +- [should enable modsecurity with transaction ID and OWASP rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L53) +- [should disable modsecurity](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L74) +- [should enable modsecurity with snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L91) +- [should enable modsecurity without using 'modsecurity on;'](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L110) +- [should disable modsecurity using 'modsecurity off;'](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L132) +- [should enable modsecurity with snippet and block requests](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L153) +- [should enable modsecurity globally and with modsecurity-snippet block requests](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L189) +- [should enable modsecurity when enable-owasp-modsecurity-crs is set to true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L225) +- [should enable modsecurity through the config map](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L264) +- [should enable modsecurity through the config map but ignore snippet as disabled by admin](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L305) +- [should disable default modsecurity conf setting when modsecurity-snippet is specified](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/modsecurity/modsecurity.go#L347) + +### [preserve-trailing-slash](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/preservetrailingslash.go#L27) + +- [should allow preservation of trailing slashes](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/preservetrailingslash.go#L34) + +### [proxy-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L28) + +- [should set proxy_redirect to off](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L36) +- [should set proxy_redirect to default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L52) +- [should set proxy_redirect to hello.com goodbye.com](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L68) +- [should set proxy client-max-body-size to 8m](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L85) +- [should not set proxy client-max-body-size to incorrect value](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L100) +- [should set valid proxy timeouts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L115) +- [should not set invalid proxy timeouts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L136) +- [should turn on proxy-buffering](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L157) +- [should turn off proxy-request-buffering](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L179) +- [should build proxy next upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L194) +- [should setup proxy cookies](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L215) +- [should change the default proxy HTTP version](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxy.go#L233) + +### [proxy-ssl-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L30) + +- [should set valid proxy-ssl-secret](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L37) +- [should set valid proxy-ssl-secret, proxy-ssl-verify to on, proxy-ssl-verify-depth to 2, and proxy-ssl-server-name to on](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L64) +- [should set valid proxy-ssl-secret, proxy-ssl-ciphers to HIGH:!AES](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L94) +- [should set valid proxy-ssl-secret, proxy-ssl-protocols](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L122) +- [proxy-ssl-location-only flag should change the nginx config server part](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/proxyssl.go#L150) + +### [permanent-redirect permanent-redirect-code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/redirect.go#L30) + +- [should respond with a standard redirect code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/redirect.go#L33) +- [should respond with a custom redirect code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/redirect.go#L61) + +### [satisfy](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/satisfy.go#L35) + +- [should configure satisfy directive correctly](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/satisfy.go#L42) +- [should allow multiple auth with satisfy any](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/satisfy.go#L84) + +### [server-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/serversnippet.go#L28) + +- [add valid directives to server via server snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/serversnippet.go#L35) +- [drops server snippet if disabled by the administrator](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/serversnippet.go#L61) + +### [service-upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/serviceupstream.go#L32) + +- [should use the Service Cluster IP and Port ](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/serviceupstream.go#L41) +- [should use the Service Cluster IP and Port ](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/serviceupstream.go#L70) +- [should not use the Service Cluster IP and Port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/serviceupstream.go#L99) + +### [configuration-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/snippet.go#L28) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/snippet.go#L35) +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/snippet.go#L58) + +### [ssl-ciphers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/sslciphers.go#L28) + +- [should change ssl ciphers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/sslciphers.go#L35) + +### [stream-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/streamsnippet.go#L34) + +- [should add value of stream-snippet to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/streamsnippet.go#L41) +- [should add stream-snippet and drop annotations per admin config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/streamsnippet.go#L85) + +### [upstream-hash-by-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/upstreamhashby.go#L76) + +- [should connect to the same pod](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/upstreamhashby.go#L83) +- [should connect to the same subset of pods](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/upstreamhashby.go#L92) + +### [upstream-vhost](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/upstreamvhost.go#L27) + +- [set host to upstreamvhost.bar.com](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/upstreamvhost.go#L34) + +### [x-forwarded-prefix](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/xforwardedprefix.go#L28) + +- [should set the X-Forwarded-Prefix to the annotation value](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/xforwardedprefix.go#L35) +- [should not add X-Forwarded-Prefix if the annotation value is empty](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/xforwardedprefix.go#L57) + +### [denylist-source-range](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/ipdenylist.go#L28) + +- [only deny explicitly denied IPs, allow all others](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/ipdenylist.go#L35) +- [only allow explicitly allowed IPs, deny all others](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/ipdenylist.go#L86) + +### [affinity session-cookie-name](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L35) + +- [should set sticky cookie SERVERID](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L42) +- [should change cookie name on ingress definition change](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L64) +- [should set the path to /something on the generated cookie](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L99) +- [does not set the path to / on the generated cookie if there's more than one rule referring to the same backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L121) +- [should set cookie with expires](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L194) +- [should set cookie with domain](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L225) +- [should not set cookie without domain annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L248) +- [should work with use-regex annotation and session-cookie-path](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L270) +- [should warn user when use-regex is true and session-cookie-path is not set](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L294) +- [should not set affinity across all server locations when using separate ingresses](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L320) +- [should set sticky cookie without host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L352) +- [should work with server-alias annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L372) +- [should set secure in cookie with provided true annotation on http](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L412) +- [should not set secure in cookie with provided false annotation on http](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L435) +- [should set secure in cookie with provided false annotation on https](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/affinity.go#L458) + +### [rewrite-target use-regex enable-rewrite-log](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L30) + +- [should write rewrite logs](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L37) +- [should use correct longest path match](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L66) +- [should use ~* location modifier if regex annotation is present](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L111) +- [should fail to use longest match for documented warning](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L158) +- [should allow for custom rewrite parameters](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/rewrite.go#L190) + +### [backend-protocol - FastCGI](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fastcgi.go#L30) + +- [should use fastcgi_pass in the configuration file](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fastcgi.go#L37) +- [should add fastcgi_index in the configuration file](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fastcgi.go#L54) +- [should add fastcgi_param in the configuration file](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fastcgi.go#L71) +- [should return OK for service with backend protocol FastCGI](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/fastcgi.go#L102) + +### [auth-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L39) + +- [should return status code 200 when no authentication is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L46) +- [should return status code 503 when authentication is configured with an invalid secret](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L65) +- [should return status code 401 when authentication is configured but Authorization header is not configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L89) +- [should return status code 401 when authentication is configured and Authorization header is sent with invalid credentials](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L116) +- [should return status code 401 and cors headers when authentication and cors is configured but Authorization header is not configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L144) +- [should return status code 200 when authentication is configured and Authorization header is sent](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L172) +- [should return status code 200 when authentication is configured with a map and Authorization header is sent](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L199) +- [should return status code 401 when authentication is configured with invalid content and Authorization header is sent](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L227) +- [ when external auth is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L266) +- [ when external auth is not configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L284) +- [ when auth-headers are set](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L301) +- [should set cache_key when external auth cache is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L322) +- [user retains cookie by default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L411) +- [user does not retain cookie if upstream returns error status code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L422) +- [user with annotated ingress retains cookie if upstream returns error status code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L433) +- [should return status code 200 when signed in](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L485) +- [should redirect to signin url when not signed in](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L494) +- [keeps processing new ingresses even if one of the existing ingresses is misconfigured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L505) +- [should overwrite Foo header with auth response](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L529) +- [should not create additional upstream block when auth-keepalive is not set](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L552) +- [should not create additional upstream block when host part of auth-url contains a variable](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L570) +- [should not create additional upstream block when auth-keepalive is negative](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L590) +- [should not create additional upstream block when auth-keepalive is set with HTTP/2](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L609) +- [should create additional upstream block when auth-keepalive is set with HTTP/1.x](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L623) +- [should return status code 200 when signed in](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L678) +- [should redirect to signin url when not signed in](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L687) +- [keeps processing new ingresses even if one of the existing ingresses is misconfigured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L698) +- [should return status code 200 when signed in after auth backend is deleted ](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L772) +- [should deny login for different location on same server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L792) +- [should deny login for different servers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L820) +- [should redirect to signin url when not signed in](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L849) +- [should return 503 (location was denied)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L879) +- [should add error to the config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/auth.go#L887) + +### [canary-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L36) + +- [should response with a 200 status from the mainline upstream when requests are made to the mainline ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L48) +- [should return 404 status for requests to the canary if no matching ingress is found](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L80) +- [should return the correct status codes when endpoints are unavailable](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L107) +- [should route requests to the correct upstream if mainline ingress is created before the canary ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L161) +- [should route requests to the correct upstream if mainline ingress is created after the canary ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L206) +- [should route requests to the correct upstream if the mainline ingress is modified](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L250) +- [should route requests to the correct upstream if the canary ingress is modified](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L307) +- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L372) +- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L426) +- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L490) +- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L532) +- [should routes to mainline upstream when the given Regex causes error](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L566) +- [should route requests to the correct upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L604) +- [respects always and never values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L643) +- [should route requests only to mainline if canary weight is 0](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L705) +- [should route requests only to canary if canary weight is 100](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L743) +- [should route requests only to canary if canary weight is equal to canary weight total](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L775) +- [should route requests split between mainline and canary if canary weight is 50](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L808) +- [should route requests split between mainline and canary if canary weight is 100 and weight total is 200](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L834) +- [should not use canary as a catch-all server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L863) +- [should not use canary with domain as a server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L891) +- [does not crash when canary ingress has multiple paths to the same non-matching backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L915) +- [always routes traffic to canary if first request was affinitized to canary (default behavior)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L943) +- [always routes traffic to canary if first request was affinitized to canary (explicit sticky behavior)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L1000) +- [routes traffic to either mainline or canary backend (legacy behavior)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/annotations/canary.go#L1058) + +### [Debug CLI](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/dbg/main.go#L29) + +- [should list the backend servers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/dbg/main.go#L37) +- [should get information for a specific backend server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/dbg/main.go#L56) +- [should produce valid JSON for /dbg general](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/dbg/main.go#L85) + +### [[Default Backend] custom service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/custom_default_backend.go#L33) + +- [uses custom default backend that returns 200 as status code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/custom_default_backend.go#L36) + +### [[Default Backend]](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/default_backend.go#L30) + +- [should return 404 sending requests when only a default backend is running](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/default_backend.go#L33) +- [enables access logging for default backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/default_backend.go#L88) +- [disables access logging for default backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/default_backend.go#L105) + +### [[Default Backend] SSL](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/ssl.go#L26) + +- [should return a self generated SSL certificate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/ssl.go#L29) + +### [[Default Backend] change default settings](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/with_hosts.go#L30) + +- [should apply the annotation to the default backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/defaultbackend/with_hosts.go#L38) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/e2e_test.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/e2e_test.go#L) + +### [[Endpointslices] long service name](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/endpointslices/longname.go#L29) + +- [should return 200 when service name has max allowed number of characters 63](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/endpointslices/longname.go#L38) + +### [[TopologyHints] topology aware routing](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/endpointslices/topology.go#L35) + +- [should return 200 when service has topology hints](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/endpointslices/topology.go#L43) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/grpc_fortune_teller.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/grpc_fortune_teller.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/array.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/array.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/chain.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/chain.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/cookie.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/cookie.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/match.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/match.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/object.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/object.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/reporter.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/reporter.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/response.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/response.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/string.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/string.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/value.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/value.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/request.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/httpexpect/request.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/logs.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/logs.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/ssl.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/ssl.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/test_context.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/test_context.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/util.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/util.go#L) + +### [[Setting] ](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/framework.go#L194) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/framework.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/healthz.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/healthz.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/k8s.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/k8s.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/metrics.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/metrics.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/deployment.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/deployment.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/exec.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/exec.go#L) + +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/fastcgi_helloserver.go#L) + +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/framework/fastcgi_helloserver.go#L) + +### [[Shutdown] Grace period shutdown](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/grace_period.go#L32) + +- [/healthz should return status code 500 during shutdown grace period](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/grace_period.go#L35) + +### [[Shutdown] ingress controller](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/shutdown.go#L30) + +- [should shutdown in less than 60 secons without pending connections](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/shutdown.go#L40) +- [should shutdown after waiting 60 seconds for pending connections to be closed](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/shutdown.go#L61) +- [should shutdown after waiting 150 seconds for pending connections to be closed](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/shutdown.go#L106) + +### [[Shutdown] Graceful shutdown with pending request](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/slow_requests.go#L25) + +- [should let slow requests finish before shutting down](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/gracefulshutdown/slow_requests.go#L33) + +### [[Ingress] DeepInspection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/deep_inspection.go#L27) + +- [should drop whole ingress if one path matches invalid regex](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/deep_inspection.go#L34) + +### [single ingress - multiple hosts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/multiple_rules.go#L30) + +- [should set the correct $service_name NGINX variable](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/multiple_rules.go#L38) + +### [[Ingress] [PathType] exact](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_exact.go#L30) + +- [should choose exact location for /exact](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_exact.go#L37) + +### [[Ingress] [PathType] mix Exact and Prefix paths](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_mixed.go#L30) + +- [should choose the correct location](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_mixed.go#L39) + +### [[Ingress] [PathType] prefix checks](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_prefix.go#L28) + +- [should return 404 when prefix /aaa does not match request /aaaccc](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/pathtype_prefix.go#L35) + +### [[Ingress] definition without host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/without_host.go#L31) + +- [should set ingress details variables for ingresses without a host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/without_host.go#L34) +- [should set ingress details variables for ingresses with host without IngressRuleValue, only Backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ingress/without_host.go#L55) + +### [[Memory Leak] Dynamic Certificates](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/leaks/lua_ssl.go#L35) + +- [should not leak memory from ingress SSL certificates or configuration updates](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/leaks/lua_ssl.go#L42) + +### [[Load Balancer] load-balance](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/configmap.go#L28) + +- [should apply the configmap load-balance setting](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/configmap.go#L35) + +### [[Load Balancer] EWMA](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/ewma.go#L31) + +- [does not fail requests](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/ewma.go#L42) + +### [[Load Balancer] round-robin](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/round_robin.go#L31) + +- [should evenly distribute requests with round-robin (default algorithm)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/round_robin.go#L39) + +### [[Lua] dynamic certificates](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_certificates.go#L37) + +- [picks up the certificate when we add TLS spec to existing ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_certificates.go#L45) +- [picks up the previously missing secret for a given ingress without reloading](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_certificates.go#L70) +- [supports requests with domain with trailing dot](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_certificates.go#L145) +- [picks up the updated certificate without reloading](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_certificates.go#L149) +- [falls back to using default certificate when secret gets deleted without reloading](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_certificates.go#L185) +- [picks up a non-certificate only change](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_certificates.go#L218) +- [removes HTTPS configuration when we delete TLS spec](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_certificates.go#L233) + +### [[Lua] dynamic configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_configuration.go#L42) + +- [configures balancer Lua middleware correctly](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_configuration.go#L50) +- [handles endpoints only changes](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_configuration.go#L62) +- [handles endpoints only changes (down scaling of replicas)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_configuration.go#L87) +- [handles endpoints only changes consistently (down scaling of replicas vs. empty service)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_configuration.go#L125) +- [handles an annotation change](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/lua/dynamic_configuration.go#L171) + +### [nginx-configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/nginx/nginx.go#L99) + +- [start nginx with default configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/nginx/nginx.go#L102) +- [fails when using alias directive](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/nginx/nginx.go#L115) +- [fails when using root directive](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/nginx/nginx.go#L124) + +### [[Security] request smuggling](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/security/request_smuggling.go#L32) + +- [should not return body content from error_page](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/security/request_smuggling.go#L39) + +### [[Service] backend status code 503](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L33) + +- [should return 503 when backend service does not exist](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L36) +- [should return 503 when all backend service endpoints are unavailable](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L54) + +### [[Service] Type ExternalName](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L59) + +- [works with external name set to incomplete fqdn](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L62) +- [should return 200 for service type=ExternalName without a port defined](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L95) +- [should return 200 for service type=ExternalName with a port defined](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L129) +- [should return status 502 for service type=ExternalName with an invalid host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L153) +- [should return 200 for service type=ExternalName using a port name](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L184) +- [should return 200 for service type=ExternalName using FQDN with trailing dot](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L217) +- [should update the external name after a service update](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L248) +- [should sync ingress on external name service addition/deletion](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L311) + +### [[Service] Nil Service Backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_nil_backend.go#L31) + +- [should return 404 when backend service is nil](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_nil_backend.go#L38) + +### [access-log](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L27) + +- [use the default configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L32) +- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L42) +- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L54) +- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L67) +- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L80) + +### [Bad annotation values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L29) + +- [[BAD_ANNOTATIONS] should drop an ingress if there is an invalid character in some annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L36) +- [[BAD_ANNOTATIONS] should drop an ingress if there is a forbidden word in some annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L67) +- [[BAD_ANNOTATIONS] should allow an ingress if there is a default blocklist config in place](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L102) +- [[BAD_ANNOTATIONS] should drop an ingress if there is a custom blocklist config in place and allow others to pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L133) + +### [brotli](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/brotli.go#L30) + +- [ condition](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/brotli.go#L39) + +### [add-headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L30) + +- [Add a custom header](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L40) +- [Add multiple custom headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L65) + +### [[SSL] [Flag] default-ssl-certificate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L33) + +- [uses default ssl certificate for catch-all ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L64) +- [uses default ssl certificate for host based ingress when configured certificate does not match host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L80) + +### [[Flag] disable-catch-all](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L33) + +- [should ignore catch all Ingress with backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L50) +- [should ignore catch all Ingress with backend and rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L69) +- [should delete Ingress updated to catch-all](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L81) +- [should allow Ingress with rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L123) + +### [[Flag] disable-service-external-name](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_service_external_name.go#L35) + +- [should ignore services of external-name type](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_service_external_name.go#L52) + +### [enable-real-ip](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L30) + +- [trusts X-Forwarded-For header only when setting is true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L40) +- [should not trust X-Forwarded-For header when setting is false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L78) + +### [use-forwarded-headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L30) + +- [should trust X-Forwarded headers when setting is true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L40) +- [should not trust X-Forwarded headers when setting is false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L92) + ### [Geoip2](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/geoip2.go#L37) - [should include geoip2 line in config when enabled and db file exists](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/geoip2.go#L46) - [should only allow requests from specific countries](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/geoip2.go#L70) +### [[Security] block-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L28) + +- [should block CIDRs defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L38) +- [should block User-Agents defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L55) +- [should block Referers defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L88) + ### [[Security] global-auth-url](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L34) - [should return status code 401 when request any protected service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L85) @@ -27,59 +652,39 @@ Do not try to edit it manually. - [user does not retain cookie if upstream returns error status code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L337) - [user with global-auth-always-set-cookie key in configmap retains cookie if upstream returns error status code](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_external_auth.go#L348) -### [[Security] Pod Security Policies](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy.go#L40) +### [global-options](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_options.go#L28) -- [should be running with a Pod Security Policy](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy.go#L43) +- [should have worker_rlimit_nofile option](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_options.go#L31) +- [should have worker_rlimit_nofile option and be independent on amount of worker processes](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_options.go#L38) -### [log-format-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L28) +### [settings-global-rate-limit](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/globalratelimit.go#L30) -- [should disable the log-format-escape-json by default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L40) -- [should enable the log-format-escape-json](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L47) -- [should disable the log-format-escape-json](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L55) -- [log-format-escape-json enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L66) -- [log-format-escape-json disabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L89) +- [generates correct NGINX configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/globalratelimit.go#L38) -### [server-tokens](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L29) +### [hash size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L27) -- [should not exists Server header in the response](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L38) -- [should exists Server header in the response when is enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L50) +- [should set server_names_hash_bucket_size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L40) +- [should set server_names_hash_max_size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L48) +- [should set proxy-headers-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L60) +- [should set proxy-headers-hash-max-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L68) +- [should set variables-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L80) +- [should set variables-hash-max-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L88) +- [should set vmap-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L100) -### [proxy-connect-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L28) +### [[Flag] ingress-class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L39) -- [should set valid proxy timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L36) -- [should not set invalid proxy timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L52) - -### [ssl-ciphers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ssl_ciphers.go#L28) - -- [Add ssl ciphers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ssl_ciphers.go#L31) - -### [use-proxy-protocol](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L36) - -- [should respect port passed by the PROXY Protocol](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L46) -- [should respect proto passed by the PROXY Protocol server port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L79) -- [should enable PROXY Protocol for HTTPS](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L112) -- [should enable PROXY Protocol for TCP](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L155) - -### [plugins](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/plugins.go#L28) - -- [should exist a x-hello-world header](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/plugins.go#L35) - -### [configmap server-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_snippet.go#L28) - -- [should add value of server-snippet setting to all ingress config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_snippet.go#L35) -- [should add global server-snippet and drop annotations per admin config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_snippet.go#L92) - -### [[Flag] disable-catch-all](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L33) - -- [should ignore catch all Ingress with backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L50) -- [should ignore catch all Ingress with backend and rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L69) -- [should delete Ingress updated to catch-all](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L81) -- [should allow Ingress with rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_catch_all.go#L123) - -### [enable-real-ip](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L30) - -- [trusts X-Forwarded-For header only when setting is true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L40) -- [should not trust X-Forwarded-For header when setting is false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/enable_real_ip.go#L78) +- [should ignore Ingress with a different class annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L68) +- [should ignore Ingress with different controller class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L104) +- [should accept both Ingresses with default IngressClassName and IngressClass annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L132) +- [should ignore Ingress without IngressClass configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L164) +- [should delete Ingress when class is removed](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L192) +- [should serve Ingress when class is added](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L257) +- [should serve Ingress when class is updated between annotation and ingressClassName](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L323) +- [should ignore Ingress with no class and accept the correctly configured Ingresses](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L413) +- [should watch Ingress with no class and ignore ingress with a different class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L482) +- [should watch Ingress that uses the class name even if spec is different](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L539) +- [should watch Ingress with correct annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L631) +- [should ignore Ingress with only IngressClassName](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L652) ### [keep-alive keep-alive-requests](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/keep-alive.go#L28) @@ -87,7 +692,41 @@ Do not try to edit it manually. - [should set keepalive_requests](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/keep-alive.go#L48) - [should set keepalive connection to upstream server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/keep-alive.go#L59) - [should set keep alive connection timeout to upstream server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/keep-alive.go#L68) -- [should set the request count to upstream server through one keep alive connection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/keep-alive.go#L77) +- [should set keepalive time to upstream server](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/keep-alive.go#L77) +- [should set the request count to upstream server through one keep alive connection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/keep-alive.go#L86) + +### [Configmap - limit-rate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/limit_rate.go#L28) + +- [Check limit-rate config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/limit_rate.go#L36) + +### [[Flag] custom HTTP and HTTPS ports](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L32) + +- [should set X-Forwarded-Port headers accordingly when listening on a non-default HTTP port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L48) +- [should set X-Forwarded-Port header to 443](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L70) +- [should set the X-Forwarded-Port header to 443](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L100) + +### [log-format-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L28) + +- [should not configure log-format escape by default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L40) +- [should enable the log-format-escape-json](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L47) +- [should disable the log-format-escape-json](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L55) +- [should enable the log-format-escape-none](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L63) +- [should disable the log-format-escape-none](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L71) +- [log-format-escape-json enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L82) +- [log-format default escape](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L105) +- [log-format-escape-none enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/log-format.go#L128) + +### [[Lua] lua-shared-dicts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/lua_shared_dicts.go#L26) + +- [configures lua shared dicts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/lua_shared_dicts.go#L29) + +### [main-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/main_snippet.go#L27) + +- [should add value of main-snippet setting to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/main_snippet.go#L31) + +### [[Security] modsecurity-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/modsecurity/modsecurity_snippet.go#L27) + +- [should add value of modsecurity-snippet setting to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/modsecurity/modsecurity_snippet.go#L30) ### [enable-multi-accept](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L27) @@ -95,13 +734,13 @@ Do not try to edit it manually. - [should be enabled when set to true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L39) - [should be disabled when set to false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/multi_accept.go#L49) -### [[Flag] watch namespace selector](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/namespace_selector.go#L30) +### [Add no tls redirect locations](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_tls_redirect_locations.go#L28) -- [should ingore Ingress of namespace without label foo=bar and accept those of namespace with label foo=bar](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/namespace_selector.go#L70) +- [Check no tls redirect locations config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_tls_redirect_locations.go#L31) -### [[Flag] disable-service-external-name](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_service_external_name.go#L34) +### [OCSP](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ocsp/ocsp.go#L42) -- [should ignore services of external-name type](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_service_external_name.go#L51) +- [should enable OCSP and contain stapling information in the connection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ocsp/ocsp.go#L49) ### [Configure OpenTracing](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L48) @@ -119,41 +758,48 @@ Do not try to edit it manually. - [should enable opentracing using jaeger with an HTTP endpoint](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L228) - [should enable opentracing using datadog](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentracing.go#L241) -### [Configmap change](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/configmap_change.go#L29) +### [plugins](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/plugins.go#L28) -- [should reload after an update in the configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/configmap_change.go#L36) +- [should exist a x-hello-world header](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/plugins.go#L35) -### [Configmap - limit-rate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/limit_rate.go#L28) +### [[Security] Pod Security Policies](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy.go#L41) -- [Check limit-rate config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/limit_rate.go#L36) +- [should be running with a Pod Security Policy](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy.go#L44) -### [access-log](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L26) +### [[Security] Pod Security Policies with volumes](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy_volumes.go#L37) -- [use the default configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L31) -- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L41) -- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L53) -- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L66) -- [use the specified configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/access_log.go#L79) +- [should be running with a Pod Security Policy](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy_volumes.go#L40) -### [global-options](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_options.go#L28) +### [proxy-connect-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L28) -- [should have worker_rlimit_nofile option](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_options.go#L31) -- [should have worker_rlimit_nofile option and be independent on amount of worker processes](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_options.go#L38) +- [should set valid proxy timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L36) +- [should not set invalid proxy timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_connect_timeout.go#L52) -### [[Flag] ingress-class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L39) +### [Dynamic $proxy_host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L28) -- [should ignore Ingress with a different class annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L68) -- [should ignore Ingress with different controller class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L104) -- [should accept both Ingresses with default IngressClassName and IngressClass annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L132) -- [should ignore Ingress without IngressClass configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L164) -- [should delete Ingress when class is removed](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L192) -- [should serve Ingress when class is added](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L257) -- [should serve Ingress when class is updated between annotation and ingressClassName](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L323) -- [should ignore Ingress with no class and accept the correctly configured Ingresses](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L413) -- [should watch Ingress with no class and ignore ingress with a different class](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L482) -- [should watch Ingress that uses the class name even if spec is different](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L539) -- [should watch Ingress with correct annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L631) -- [should ignore Ingress with only IngressClassName](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ingress_class.go#L652) +- [should exist a proxy_host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L36) +- [should exist a proxy_host using the upstream-vhost annotation value](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L57) + +### [proxy-next-upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_next_upstream.go#L28) + +- [should build proxy next upstream using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_next_upstream.go#L36) + +### [use-proxy-protocol](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L36) + +- [should respect port passed by the PROXY Protocol](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L46) +- [should respect proto passed by the PROXY Protocol server port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L79) +- [should enable PROXY Protocol for HTTPS](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L112) +- [should enable PROXY Protocol for TCP](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_protocol.go#L155) + +### [proxy-read-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_read_timeout.go#L28) + +- [should set valid proxy read timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_read_timeout.go#L36) +- [should not set invalid proxy read timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_read_timeout.go#L52) + +### [proxy-send-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L28) + +- [should set valid proxy send timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L36) +- [should not set invalid proxy send timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L52) ### [reuse-port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L27) @@ -161,99 +807,61 @@ Do not try to edit it manually. - [reuse port should be disabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L44) - [reuse port should be enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/reuse-port.go#L52) -### [proxy-send-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L28) +### [configmap server-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_snippet.go#L28) -- [should set valid proxy send timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L36) -- [should not set invalid proxy send timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_send_timeout.go#L52) +- [should add value of server-snippet setting to all ingress config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_snippet.go#L35) +- [should add global server-snippet and drop annotations per admin config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_snippet.go#L92) -### [[SSL] [Flag] default-ssl-certificate](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L33) +### [server-tokens](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L29) -- [uses default ssl certificate for catch-all ingress](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L64) -- [uses default ssl certificate for host based ingress when configured certificate does not match host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/default_ssl_certificate.go#L80) +- [should not exists Server header in the response](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L38) +- [should exists Server header in the response when is enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/server_tokens.go#L50) -### [brotli](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/brotli.go#L30) +### [ssl-ciphers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ssl_ciphers.go#L28) -- [ condition](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/brotli.go#L39) +- [Add ssl ciphers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ssl_ciphers.go#L31) -### [[Security] Pod Security Policies with volumes](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy_volumes.go#L36) +### [configmap stream-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/stream_snippet.go#L35) -- [should be running with a Pod Security Policy](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/pod_security_policy_volumes.go#L39) - -### [Dynamic $proxy_host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L28) - -- [should exist a proxy_host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L36) -- [should exist a proxy_host using the upstream-vhost annotation value](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_host.go#L57) - -### [[Security] block-*](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L28) - -- [should block CIDRs defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L38) -- [should block User-Agents defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L55) -- [should block Referers defined in the ConfigMap](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/global_access_block.go#L88) - -### [settings-global-rate-limit](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/globalratelimit.go#L30) - -- [generates correct NGINX configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/globalratelimit.go#L38) - -### [Add no tls redirect locations](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_tls_redirect_locations.go#L28) - -- [Check no tls redirect locations config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_tls_redirect_locations.go#L31) - -### [main-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/main_snippet.go#L27) - -- [should add value of main-snippet setting to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/main_snippet.go#L31) - -### [[Lua] lua-shared-dicts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/lua_shared_dicts.go#L26) - -- [configures lua shared dicts](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/lua_shared_dicts.go#L29) - -### [Bad annotation values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L29) - -- [[BAD_ANNOTATIONS] should drop an ingress if there is an invalid character in some annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L36) -- [[BAD_ANNOTATIONS] should drop an ingress if there is a forbidden word in some annotation](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L67) -- [[BAD_ANNOTATIONS] should allow an ingress if there is a default blocklist config in place](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L102) -- [[BAD_ANNOTATIONS] should drop an ingress if there is a custom blocklist config in place and allow others to pass](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/badannotationvalues.go#L133) +- [should add value of stream-snippet via config map to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/stream_snippet.go#L42) ### [[SSL] TLS protocols, ciphers and headers)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L31) - [setting cipher suite](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L65) -- [enforcing TLS v1.0](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L87) -- [setting max-age parameter](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L133) -- [setting includeSubDomains parameter](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L149) -- [setting preload parameter](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L168) -- [overriding what's set from the upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L188) -- [should not use ports during the HTTP to HTTPS redirection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L209) -- [should not use ports or X-Forwarded-Host during the HTTP to HTTPS redirection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L227) +- [setting max-age parameter](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L111) +- [setting includeSubDomains parameter](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L127) +- [setting preload parameter](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L146) +- [overriding what's set from the upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L166) +- [should not use ports during the HTTP to HTTPS redirection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L187) +- [should not use ports or X-Forwarded-Host during the HTTP to HTTPS redirection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/tls.go#L205) -### [[Security] modsecurity-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/modsecurity/modsecurity_snippet.go#L27) +### [[Flag] disable-sync-events](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_sync_events.go#L32) -- [should add value of modsecurity-snippet setting to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/modsecurity/modsecurity_snippet.go#L30) +- [should create sync events (default)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_sync_events.go#L35) +- [should create sync events](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_sync_events.go#L53) +- [should not create sync events](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/disable_sync_events.go#L80) -### [OCSP](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ocsp/ocsp.go#L42) +### [gzip](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/gzip.go#L29) -- [should enable OCSP and contain stapling information in the connection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ocsp/ocsp.go#L49) +- [should be disabled by default](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/gzip.go#L32) +- [should be enabled with default settings](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/gzip.go#L39) +- [should set gzip_comp_level to 4](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/gzip.go#L56) +- [should set gzip_disable to msie6](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/gzip.go#L67) +- [should set gzip_min_length to 100](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/gzip.go#L78) +- [should set gzip_types to application/javascript](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/gzip.go#L89) -### [configmap stream-snippet](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/stream_snippet.go#L34) +### [Configmap change](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/configmap_change.go#L29) -- [should add value of stream-snippet via config map to nginx config](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/stream_snippet.go#L41) +- [should reload after an update in the configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/configmap_change.go#L36) -### [proxy-read-timeout](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_read_timeout.go#L28) +### [[Flag] watch namespace selector](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/namespace_selector.go#L30) -- [should set valid proxy read timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_read_timeout.go#L36) -- [should not set invalid proxy read timeouts using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_read_timeout.go#L52) +- [should ingore Ingress of namespace without label foo=bar and accept those of namespace with label foo=bar](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/namespace_selector.go#L63) -### [proxy-next-upstream](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_next_upstream.go#L28) +### [With enable-ssl-passthrough enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ssl_passthrough.go#L36) -- [should build proxy next upstream using configmap values](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/proxy_next_upstream.go#L36) - -### [hash size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L27) - -- [should set server_names_hash_bucket_size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L40) -- [should set server_names_hash_max_size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L48) -- [should set proxy-headers-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L60) -- [should set proxy-headers-hash-max-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L68) -- [should set variables-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L80) -- [should set variables-hash-max-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L88) -- [should set vmap-hash-bucket-size](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/hash-size.go#L100) +- [should enable ssl-passthrough-proxy-port on a different port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ssl_passthrough.go#L56) +- [should pass unknown traffic to default backend and handle known traffic](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/ssl_passthrough.go#L79) ### [[Security] no-auth-locations](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L33) @@ -261,33 +869,13 @@ Do not try to edit it manually. - [should return status code 200 when accessing '/' authentication](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L68) - [should return status code 200 when accessing '/noauth' unauthenticated](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/no_auth_locations.go#L82) -### [[Flag] custom HTTP and HTTPS ports](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L32) +### [Configure Opentelemetry](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentelemetry.go#L37) -- [should set X-Forwarded-Port headers accordingly when listening on a non-default HTTP port](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L48) -- [should set X-Forwarded-Port header to 443](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L70) -- [should set the X-Forwarded-Port header to 443](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/listen_nondefault_ports.go#L100) - -### [use-forwarded-headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L30) - -- [should trust X-Forwarded headers when setting is true](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L40) -- [should not trust X-Forwarded headers when setting is false](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/forwarded_headers.go#L92) - -### [add-headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L30) - -- [Add a custom header](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L40) -- [Add multiple custom headers](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/custom_header.go#L65) - -### [[Load Balancer] round-robin](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/round_robin.go#L31) - -- [should evenly distribute requests with round-robin (default algorithm)](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/round_robin.go#L39) - -### [[Load Balancer] EWMA](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/ewma.go#L31) - -- [does not fail requests](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/ewma.go#L42) - -### [[Load Balancer] load-balance](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/configmap.go#L28) - -- [should apply the configmap load-balance setting](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/loadbalance/configmap.go#L35) +- [should not exists opentelemetry directive](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentelemetry.go#L47) +- [should exists opentelemetry directive when is enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentelemetry.go#L60) +- [should include opentelemetry_trust_incoming_spans on directive when enabled](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentelemetry.go#L74) +- [should not exists opentelemetry_operation_name directive when is empty](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentelemetry.go#L89) +- [should exists opentelemetry_operation_name directive when is configured](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/settings/opentelemetry.go#L104) ### [[SSL] redirect to HTTPS](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ssl/http_redirect.go#L29) @@ -298,22 +886,21 @@ Do not try to edit it manually. - [should not appear references to secret updates not used in ingress rules](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ssl/secret_update.go#L40) - [should return the fake SSL certificate if the secret is invalid](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/ssl/secret_update.go#L82) -### [[Service] Type ExternalName](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L58) +### [[Status] status update](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/status/update.go#L38) -- [works with external name set to incomplete fqdn](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L61) -- [should return 200 for service type=ExternalName without a port defined](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L94) -- [should return 200 for service type=ExternalName with a port defined](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L128) -- [should return status 502 for service type=ExternalName with an invalid host](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L152) -- [should return 200 for service type=ExternalName using a port name](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L183) -- [should return 200 for service type=ExternalName using FQDN with trailing dot](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L216) -- [should update the external name after a service update](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L247) -- [should sync ingress on external name service addition/deletion](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_externalname.go#L310) +- [should update status field after client-go reconnection](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/status/update.go#L43) -### [[Service] Nil Service Backend](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_nil_backend.go#L31) +### [[TCP] tcp-services](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/tcpudp/tcp.go#L38) -- [should return 404 when backend service is nil](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_nil_backend.go#L38) +- [should expose a TCP service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/tcpudp/tcp.go#L46) +- [should expose an ExternalName TCP service](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/tcpudp/tcp.go#L80) +- [should reload after an update in the configuration](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/tcpudp/tcp.go#L169) -### [[Service] backend status code 503](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L33) +### [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/e2e.go#L) -- [should return 503 when backend service does not exist](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L36) -- [should return 503 when all backend service endpoints are unavailable](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/servicebackend/service_backend.go#L54) +- [](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/e2e.go#L) + +### [[metrics] exported prometheus metrics](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/metrics/metrics.go#L36) + +- [exclude socket request metrics are absent](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/metrics/metrics.go#L50) +- [exclude socket request metrics are present](https://github.com/kubernetes/ingress-nginx/tree/main/test/e2e/metrics/metrics.go#L72) \ No newline at end of file diff --git a/docs/examples/affinity/cookie/README.md b/docs/examples/affinity/cookie/README.md index 1920d132b..e66503dd7 100644 --- a/docs/examples/affinity/cookie/README.md +++ b/docs/examples/affinity/cookie/README.md @@ -67,7 +67,7 @@ Accept-Ranges: bytes ``` In the example above, you can see that the response contains a `Set-Cookie` header with the settings we have defined. -This cookie is created by the NGINX Ingress Controller, it contains a randomly generated key corresponding to the upstream used for that request (selected using [consistent hashing][consistent-hashing]) and has an `Expires` directive. +This cookie is created by the Ingress-Nginx Controller, it contains a randomly generated key corresponding to the upstream used for that request (selected using [consistent hashing][consistent-hashing]) and has an `Expires` directive. If a client sends a cookie that doesn't correspond to an upstream, NGINX selects an upstream and creates a corresponding cookie. If the backend pool grows NGINX will keep sending the requests through the same server of the first request, even if it's overloaded. diff --git a/docs/examples/customization/custom-errors/README.md b/docs/examples/customization/custom-errors/README.md index a137fd6dc..a7c9545b0 100644 --- a/docs/examples/customization/custom-errors/README.md +++ b/docs/examples/customization/custom-errors/README.md @@ -29,7 +29,7 @@ service/nginx-errors ClusterIP 10.0.0.12 80/TCP 10s ## Ingress controller configuration -If you do not already have an instance of the NGINX Ingress controller running, deploy it according to the +If you do not already have an instance of the Ingress-Nginx Controller running, deploy it according to the [deployment guide][deploy], then follow these steps: 1. Edit the `ingress-nginx-controller` Deployment and set the value of the `--default-backend-service` flag to the name of the @@ -37,7 +37,7 @@ If you do not already have an instance of the NGINX Ingress controller running, 2. Edit the `ingress-nginx-controller` ConfigMap and create the key `custom-http-errors` with a value of `404,503`. -3. Take note of the IP address assigned to the NGINX Ingress controller Service. +3. Take note of the IP address assigned to the Ingress-Nginx Controller Service. ``` $ kubectl get svc ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE diff --git a/docs/examples/customization/custom-errors/custom-default-backend.helm.values.yaml b/docs/examples/customization/custom-errors/custom-default-backend.helm.values.yaml index 670208559..807da71a4 100644 --- a/docs/examples/customization/custom-errors/custom-default-backend.helm.values.yaml +++ b/docs/examples/customization/custom-errors/custom-default-backend.helm.values.yaml @@ -6,7 +6,7 @@ defaultBackend: image: registry: registry.k8s.io image: ingress-nginx/nginx-errors - tag: "v20220916-gd32f8c343@sha256:09c421ac743bace19ab77979b82186941c5125c95e62cdb40bdf41293b5c275c" + tag: "v20230312-helm-chart-4.5.2-28-g66a760794@sha256:332be6ff8c4e93e8845963932f98839dfd52ae49829c29e06475368a3e4fbd9e" extraVolumes: - name: custom-error-pages configMap: diff --git a/docs/examples/customization/custom-errors/custom-default-backend.yaml b/docs/examples/customization/custom-errors/custom-default-backend.yaml index 072beab3b..2af64896f 100644 --- a/docs/examples/customization/custom-errors/custom-default-backend.yaml +++ b/docs/examples/customization/custom-errors/custom-default-backend.yaml @@ -36,7 +36,7 @@ spec: spec: containers: - name: nginx-error-server - image: registry.k8s.io/ingress-nginx/nginx-errors:v20220916-gd32f8c343@sha256:09c421ac743bace19ab77979b82186941c5125c95e62cdb40bdf41293b5c275c + image: registry.k8s.io/ingress-nginx/nginx-errors:v20230404-helm-chart-4.6.0-11-gc76179c04@sha256:aabd7a001f6a0a07ed6ea8f6da87e928bfa8f971eba2bef708f3e8504fc5cc9b ports: - containerPort: 8080 # Setting the environment variable DEBUG we can see the headers sent diff --git a/docs/examples/customization/custom-headers/README.md b/docs/examples/customization/custom-headers/README.md index 499bfc386..0da12582f 100644 --- a/docs/examples/customization/custom-headers/README.md +++ b/docs/examples/customization/custom-headers/README.md @@ -10,7 +10,7 @@ To work around this limitation, perform a rolling restart of the deployment. ## Example -This example demonstrates configuration of the nginx ingress controller via +This example demonstrates configuration of the Ingress-Nginx Controller via a ConfigMap to pass a custom list of headers to the upstream server. @@ -26,7 +26,7 @@ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/docs/examples/customization/custom-headers/configmap.yaml ``` -The nginx ingress controller will read the `ingress-nginx/ingress-nginx-controller` ConfigMap, find the `proxy-set-headers` key, read HTTP headers from the `ingress-nginx/custom-headers` ConfigMap, and include those HTTP headers in all requests flowing from nginx to the backends. +The Ingress-Nginx Controller will read the `ingress-nginx/ingress-nginx-controller` ConfigMap, find the `proxy-set-headers` key, read HTTP headers from the `ingress-nginx/custom-headers` ConfigMap, and include those HTTP headers in all requests flowing from nginx to the backends. The above example was for passing a custom list of headers to the upstream server. diff --git a/docs/examples/customization/external-auth-headers/echo-service.yaml b/docs/examples/customization/external-auth-headers/echo-service.yaml index 0fe37be56..57df4d628 100644 --- a/docs/examples/customization/external-auth-headers/echo-service.yaml +++ b/docs/examples/customization/external-auth-headers/echo-service.yaml @@ -18,7 +18,7 @@ spec: terminationGracePeriodSeconds: 60 containers: - name: echo-service - image: registry.k8s.io/ingress-nginx/e2e-test-echo:v20220819-ga98c63787@sha256:778ac6d1188c8de8ecabeddd3c37b72c8adc8c712bad2bd7a81fb23a3514934c + image: registry.k8s.io/ingress-nginx/e2e-test-echo:v20230318-helm-chart-4.5.2-44-gfec1dbe3a@sha256:4938d1d91a2b7d19454460a8c1b010b89f6ff92d2987fd889ac3e8fc3b70d91a ports: - containerPort: 8080 resources: diff --git a/docs/examples/customization/ssl-dh-param/README.md b/docs/examples/customization/ssl-dh-param/README.md index 2eae67ce2..fcd80757b 100644 --- a/docs/examples/customization/ssl-dh-param/README.md +++ b/docs/examples/customization/ssl-dh-param/README.md @@ -1,6 +1,6 @@ # Custom DH parameters for perfect forward secrecy -This example aims to demonstrate the deployment of an nginx ingress controller and +This example aims to demonstrate the deployment of an Ingress-Nginx Controller and use a ConfigMap to configure a custom Diffie-Hellman parameters file to help with "Perfect Forward Secrecy". diff --git a/docs/examples/rewrite/README.md b/docs/examples/rewrite/README.md index c529c34ef..5b42e1fc7 100644 --- a/docs/examples/rewrite/README.md +++ b/docs/examples/rewrite/README.md @@ -38,6 +38,7 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: + nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/rewrite-target: /$2 name: rewrite namespace: default diff --git a/docs/examples/tls-termination/README.md b/docs/examples/tls-termination/README.md index bd68ddc67..25139b381 100644 --- a/docs/examples/tls-termination/README.md +++ b/docs/examples/tls-termination/README.md @@ -1,6 +1,6 @@ # TLS termination -This example demonstrates how to terminate TLS through the nginx Ingress controller. +This example demonstrates how to terminate TLS through the Ingress-Nginx Controller. ## Prerequisites diff --git a/docs/how-it-works.md b/docs/how-it-works.md index 4ad824dc8..161803210 100644 --- a/docs/how-it-works.md +++ b/docs/how-it-works.md @@ -10,7 +10,7 @@ The goal of this Ingress controller is the assembly of a configuration file (ngi Usually, a Kubernetes Controller utilizes the [synchronization loop pattern][1] to check if the desired state in the controller is updated or a change is required. To this purpose, we need to build a model using different objects from the cluster, in particular (in no special order) Ingresses, Services, Endpoints, Secrets, and Configmaps to generate a point in time configuration file that reflects the state of the cluster. -To get this object from the cluster, we use [Kubernetes Informers][2], in particular, `FilteredSharedInformer`. This informers allows reacting to changes in using [callbacks][3] to individual changes when a new object is added, modified or removed. Unfortunately, there is no way to know if a particular change is going to affect the final configuration file. Therefore on every change, we have to rebuild a new model from scratch based on the state of cluster and compare it to the current model. If the new model equals to the current one, then we avoid generating a new NGINX configuration and triggering a reload. Otherwise, we check if the difference is only about Endpoints. If so we then send the new list of Endpoints to a Lua handler running inside Nginx using HTTP POST request and again avoid generating a new NGINX configuration and triggering a reload. If the difference between running and new model is about more than just Endpoints we create a new NGINX configuration based on the new model, replace the current model and trigger a reload. +To get this object from the cluster, we use [Kubernetes Informers][2], in particular, `FilteredSharedInformer`. These informers allow reacting to change in using [callbacks][3] to individual changes when a new object is added, modified or removed. Unfortunately, there is no way to know if a particular change is going to affect the final configuration file. Therefore on every change, we have to rebuild a new model from scratch based on the state of cluster and compare it to the current model. If the new model equals to the current one, then we avoid generating a new NGINX configuration and triggering a reload. Otherwise, we check if the difference is only about Endpoints. If so we then send the new list of Endpoints to a Lua handler running inside Nginx using HTTP POST request and again avoid generating a new NGINX configuration and triggering a reload. If the difference between running and new model is about more than just Endpoints we create a new NGINX configuration based on the new model, replace the current model and trigger a reload. One of the uses of the model is to avoid unnecessary reloads when there's no change in the state and to detect conflicts in definitions. @@ -60,7 +60,7 @@ In a relatively big cluster with frequently deploying apps this feature saves si Because the ingress controller works using the [synchronization loop pattern](https://coreos.com/kubernetes/docs/latest/replication-controller.html#the-reconciliation-loop-in-detail), it is applying the configuration for all matching objects. In case some Ingress objects have a broken configuration, for example a syntax error in the `nginx.ingress.kubernetes.io/configuration-snippet` annotation, the generated configuration becomes invalid, does not reload and hence no more ingresses will be taken into account. -To prevent this situation to happen, the nginx ingress controller optionally exposes a [validating admission webhook server][8] to ensure the validity of incoming ingress objects. +To prevent this situation to happen, the Ingress-Nginx Controller optionally exposes a [validating admission webhook server][8] to ensure the validity of incoming ingress objects. This webhook appends the incoming ingress objects to the list of ingresses, generates the configuration and calls nginx to ensure the configuration has no syntax errors. [0]: https://github.com/openresty/lua-nginx-module/pull/1259 diff --git a/docs/images/otel-grafana-demo.png b/docs/images/otel-grafana-demo.png new file mode 100644 index 000000000..61b50c861 Binary files /dev/null and b/docs/images/otel-grafana-demo.png differ diff --git a/docs/images/otel-jaeger-demo.png b/docs/images/otel-jaeger-demo.png new file mode 100644 index 000000000..006b23c34 Binary files /dev/null and b/docs/images/otel-jaeger-demo.png differ diff --git a/docs/images/otel-zipkin-demo.png b/docs/images/otel-zipkin-demo.png new file mode 100644 index 000000000..a3af04e46 Binary files /dev/null and b/docs/images/otel-zipkin-demo.png differ diff --git a/docs/index.md b/docs/index.md index fded1b2bc..bcf4a4018 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,233 +11,7 @@ You can learn more about using [Ingress](http://kubernetes.io/docs/user-guide/in See [Deployment](./deploy/) for a whirlwind tour that will get you started. -# FAQ - Migration to apiVersion `networking.k8s.io/v1` +# FAQ - Kubernetes 1.22 Migration -If you are using Ingress objects in your cluster (running Kubernetes older than v1.22), and you plan to upgrade to Kubernetes v1.22, this section is relevant to you. - -- Please read this [official blog on deprecated Ingress API versions](https://kubernetes.io/blog/2021/07/26/update-with-ingress-nginx/) - -- Please read this [official documentation on the IngressClass object](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) - -## What is an IngressClass and why is it important for users of Ingress-NGINX controller now ? - -IngressClass is a Kubernetes resource. See the description below. It's important because until now, a default install of the Ingress-NGINX controller did not require any IngressClass object. From version 1.0.0 of the Ingress-NGINX Controller, an IngressClass object is required. - -On clusters with more than one instance of the Ingress-NGINX controller, all instances of the controllers must be aware of which Ingress objects they serve. The `ingressClassName` field of an Ingress is the way to let the controller know about that. - -```console -kubectl explain ingressclass -``` -``` -KIND: IngressClass -VERSION: networking.k8s.io/v1 - -DESCRIPTION: - IngressClass represents the class of the Ingress, referenced by the Ingress - Spec. The `ingressclass.kubernetes.io/is-default-class` annotation can be - used to indicate that an IngressClass should be considered default. When a - single IngressClass resource has this annotation set to true, new Ingress - resources without a class specified will be assigned this default class. - -FIELDS: - apiVersion - APIVersion defines the versioned schema of this representation of an - object. Servers should convert recognized schemas to the latest internal - value, and may reject unrecognized values. More info: - https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - - kind - Kind is a string value representing the REST resource this object - represents. Servers may infer this from the endpoint the client submits - requests to. Cannot be updated. In CamelCase. More info: - https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - - metadata - Standard object's metadata. More info: - https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - - spec - Spec is the desired state of the IngressClass. More info: - https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status` - -``` - -## What has caused this change in behavior? - -There are 2 reasons primarily. - -### Reason #1 - -Until K8s version 1.21, it was possible to create an Ingress resource using deprecated versions of the Ingress API, such as: - - - `extensions/v1beta1` - - `networking.k8s.io/v1beta1` - -You would get a message about deprecation, but the Ingress resource would get created. - -From K8s version 1.22 onwards, you can **only** access the Ingress API via the stable, `networking.k8s.io/v1` API. The reason is explained in the [official blog on deprecated ingress API versions](https://kubernetes.io/blog/2021/07/26/update-with-ingress-nginx/). - -### Reason #2 - -If you are already using the Ingress-NGINX controller and then upgrade to K8s version v1.22 , there are several scenarios where your existing Ingress objects will not work how you expect. Read this FAQ to check which scenario matches your use case. - -## What is ingressClassName field ? - -`ingressClassName` is a field in the specs of an Ingress object. - -```shell -kubectl explain ingress.spec.ingressClassName -``` -```console -KIND: Ingress -VERSION: networking.k8s.io/v1 - -FIELD: ingressClassName - -DESCRIPTION: - IngressClassName is the name of the IngressClass cluster resource. The - associated IngressClass defines which controller will implement the - resource. This replaces the deprecated `kubernetes.io/ingress.class` - annotation. For backwards compatibility, when that annotation is set, it - must be given precedence over this field. The controller may emit a warning - if the field and annotation have different values. Implementations of this - API should ignore Ingresses without a class specified. An IngressClass - resource may be marked as default, which can be used to set a default value - for this field. For more information, refer to the IngressClass - documentation. -``` - -The `.spec.ingressClassName` behavior has precedence over the deprecated `kubernetes.io/ingress.class` annotation. - - -## I have only one ingress controller in my cluster. What should I do? - -If a single instance of the Ingress-NGINX controller is the sole Ingress controller running in your cluster, you should add the annotation "ingressclass.kubernetes.io/is-default-class" in your IngressClass, so any new Ingress objects will have this one as default IngressClass. - -When using Helm, you can enable this annotation by setting `.controller.ingressClassResource.default: true` in your Helm chart installation's values file. - -If you have any old Ingress objects remaining without an IngressClass set, you can do one or more of the following to make the Ingress-NGINX controller aware of the old objects: - -- You can manually set the [`.spec.ingressClassName`](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) field in the manifest of your own Ingress resources. -- You can re-create them after setting the `ingressclass.kubernetes.io/is-default-class` annotation to `true` on the IngressClass -- Alternatively you can make the Ingress-NGINX controller watch Ingress objects without the ingressClassName field set by starting your Ingress-NGINX with the flag [--watch-ingress-without-class=true](#what-is-the-flag-watch-ingress-without-class) . When using Helm, you can configure your Helm chart installation's values file with `.controller.watchIngressWithoutClass: true` - -You can configure your Helm chart installation's values file with `.controller.watchIngressWithoutClass: true`. - -We recommend that you create the IngressClass as shown below: -``` ---- -apiVersion: networking.k8s.io/v1 -kind: IngressClass -metadata: - labels: - app.kubernetes.io/component: controller - name: nginx - annotations: - ingressclass.kubernetes.io/is-default-class: "true" -spec: - controller: k8s.io/ingress-nginx -``` - -And add the value `spec.ingressClassName=nginx` in your Ingress objects. - - -## I have multiple ingress objects in my cluster. What should I do ? -- If you have lot of ingress objects without ingressClass configuration, you can run the ingress-controller with the flag `--watch-ingress-without-class=true`. - - -### What is the flag '--watch-ingress-without-class' ? -- Its a flag that is passed,as an argument, to the `nginx-ingress-controller` executable. In the configuration, it looks like this: -``` -... -... -args: - - /nginx-ingress-controller - - --watch-ingress-without-class=true - - --publish-service=$(POD_NAMESPACE)/ingress-nginx-dev-v1-test-controller - - --election-id=ingress-controller-leader - - --controller-class=k8s.io/ingress-nginx - - --configmap=$(POD_NAMESPACE)/ingress-nginx-dev-v1-test-controller - - --validating-webhook=:8443 - - --validating-webhook-certificate=/usr/local/certificates/cert - - --validating-webhook-key=/usr/local/certificates/key -... -... -``` - -## I have more than one controller in my cluster and already use the annotation ? - -No problem. This should still keep working, but we highly recommend you to test! - -Even though `kubernetes.io/ingress.class` is deprecated, the Ingress-NGINX controller still understands that annotation. -If you want to follow good practice, you should consider migrating to use IngressClass and `.spec.ingressClassName`. - -## I have more than one controller running in my cluster, and I want to use the new API ? - -In this scenario, you need to create multiple IngressClasses (see example one). But be aware that IngressClass works in a very specific way: you will need to change the `.spec.controller` value in your IngressClass and configure the controller to expect the exact same value. - -Let's see some example, supposing that you have three IngressClasses: - -- IngressClass `ingress-nginx-one`, with `.spec.controller` equal to `example.com/ingress-nginx1` -- IngressClass `ingress-nginx-two`, with `.spec.controller` equal to `example.com/ingress-nginx2` -- IngressClass `ingress-nginx-three`, with `.spec.controller` equal to `example.com/ingress-nginx1` - -(for private use, you can also use a controller name that doesn't contain a `/`; for example: `ingress-nginx1`) - -When deploying your ingress controllers, you will have to change the `--controller-class` field as follows: - -- Ingress-Nginx A, configured to use controller class name `example.com/ingress-nginx1` -- Ingress-Nginx B, configured to use controller class name `example.com/ingress-nginx2` - -Then, when you create an Ingress object with its `ingressClassName` set to `ingress-nginx-two`, only controllers looking for the `example.com/ingress-nginx2` controller class pay attention to the new object. Given that Ingress-Nginx B is set up that way, it will serve that object, whereas Ingress-Nginx A ignores the new Ingress. - -Bear in mind that, if you start Ingress-Nginx B with the command line argument `--watch-ingress-without-class=true`, then it will serve: - -1. Ingresses without any `ingressClassName` set -2. Ingresses where the deprecated annotation (`kubernetes.io/ingress.class`) matches the value set in the command line argument `--ingress-class` -3. Ingresses that refer to any IngressClass that has the same `spec.controller` as configured in `--controller-class` - -If you start Ingress-Nginx B with the command line argument `--watch-ingress-without-class=true` and you run Ingress-Nginx A with the command line argument `--watch-ingress-without-class=false` then this is a supported configuration. If you have two Ingress-NGINX controllers for the same cluster, both running with `--watch-ingress-without-class=true` then there is likely to be a conflict. - -## I am seeing this error message in the logs of the Ingress-NGINX controller: "ingress class annotation is not equal to the expected by Ingress Controller". Why ? - -- It is highly likely that you will also see the name of the ingress resource in the same error message. This error message has been observed on use the deprecated annotation (`kubernetes.io/ingress.class`) in a Ingress resource manifest. It is recommended to use the `.spec.ingressClassName` field of the Ingress resource, to specify the name of the IngressClass of the Ingress you are defining. - -## How to easily install multiple instances of the ingress-NGINX controller in the same cluster ? -- Create a new namespace - ``` - kubectl create namespace ingress-nginx-2 - ``` -- Use Helm to install the additional instance of the ingress controller -- Ensure you have Helm working (refer to the [Helm documentation](https://helm.sh/docs/)) -- We have to assume that you have the helm repo for the ingress-NGINX controller already added to your Helm config. But, if you have not added the helm repo then you can do this to add the repo to your helm config; - ``` - helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx - ``` -- Make sure you have updated the helm repo data; - ``` - helm repo update - ``` -- Now, install an additional instance of the ingress-NGINX controller like this: - ``` - helm install ingress-nginx-2 ingress-nginx/ingress-nginx \ - --namespace ingress-nginx-2 \ - --set controller.ingressClassResource.name=nginx-two \ - --set controller.ingressClass=nginx-two \ - --set controller.ingressClassResource.controllerValue="example.com/ingress-nginx-2" \ - --set controller.ingressClassResource.enabled=true \ - --set controller.ingressClassByName=true - ``` -- If you need to install yet another instance, then repeat the procedure to create a new namespace, change the values such as names & namespaces (for example from "-2" to "-3"), or anything else that meets your needs. -- If you need to install all instances in the same namespace, then you need to specify a different **election id**, like this: - ``` - helm install ingress-nginx-2 ingress-nginx/ingress-nginx \ - --namespace kube-system \ - --set controller.electionID=nginx-two-leader \ - --set controller.ingressClassResource.name=nginx-two \ - --set controller.ingressClass=nginx-two \ - --set controller.ingressClassResource.controllerValue="example.com/ingress-nginx-2" \ - --set controller.ingressClassResource.enabled=true \ - --set controller.ingressClassByName=true - ``` - - Note, controller.ingressClassResource.name and controller.ingressClass have to be set with the value of the new class as the first is to create the IngressClass object and the other is to modify the deployment of the actuall ingress controller pod. +If you are using Ingress objects in your cluster (running Kubernetes older than v1.22), +and you plan to upgrade to Kubernetes v1.22, please read [the migration guide here](./user-guide/k8s-122-migration.md). diff --git a/docs/kubectl-plugin.md b/docs/kubectl-plugin.md index 01be19f59..9e5a5dcc6 100644 --- a/docs/kubectl-plugin.md +++ b/docs/kubectl-plugin.md @@ -68,7 +68,7 @@ Use "ingress-nginx [command] --help" for more information about a command. ## Common Flags - Every subcommand supports the basic `kubectl` configuration flags like `--namespace`, `--context`, `--client-key` and so on. -- Subcommands that act on a particular `ingress-nginx` pod (`backends`, `certs`, `conf`, `exec`, `general`, `logs`, `ssh`), support the `--deployment ` and `--pod ` flags to select either a pod from a deployment with the given name, or a pod with the given name. The `--deployment` flag defaults to `ingress-nginx-controller`. +- Subcommands that act on a particular `ingress-nginx` pod (`backends`, `certs`, `conf`, `exec`, `general`, `logs`, `ssh`), support the `--deployment `, `--pod `, and `--container ` flags to select either a pod from a deployment with the given name, or a pod with the given name (and the given container name). The `--deployment` flag defaults to `ingress-nginx-controller`, and the `--container` flag defaults to `controller`. - Subcommands that inspect resources (`ingresses`, `lint`) support the `--all-namespaces` flag, which causes them to inspect resources in every namespace. ## Subcommands @@ -208,6 +208,7 @@ modsecurity modules nginx.conf opentracing.json +opentelemetry.toml owasp-modsecurity-crs template ``` diff --git a/docs/user-guide/cli-arguments.md b/docs/user-guide/cli-arguments.md index 4379d0b34..bc0894a52 100644 --- a/docs/user-guide/cli-arguments.md +++ b/docs/user-guide/cli-arguments.md @@ -24,6 +24,8 @@ They are set in the container spec of the `ingress-nginx-controller` Deployment | `--enable-metrics` | Enables the collection of NGINX metrics. (default true) | | `--enable-ssl-chain-completion` | Autocomplete SSL certificate chains with missing intermediate CA certificates. Certificates uploaded to Kubernetes must have the "Authority Information Access" X.509 v3 extension for this to succeed. (default false)| | `--enable-ssl-passthrough` | Enable SSL Passthrough. (default false) | +| `--enable-topology-aware-routing` | Enable topology aware hints feature, needs service object annotation service.kubernetes.io/topology-aware-hints sets to auto. (default false) | +| `--exclude-socket-metrics` | Set of socket request metrics to exclude which won't be exported nor being calculated. The possible socket request metrics to exclude are documented in the monitoring guide e.g. 'nginx_ingress_controller_request_duration_seconds,nginx_ingress_controller_response_size'| | `--health-check-path` | URL path of the health check endpoint. Configured inside the NGINX status server. All requests received on the port defined by the healthz-port parameter are forwarded internally to this path. (default "/healthz") | | `--health-check-timeout` | Time limit, in seconds, for a probe to health-check-path to succeed. (default 10) | | `--healthz-port` | Port to use for the healthz endpoint. (default 10254) | @@ -66,7 +68,7 @@ They are set in the container spec of the `ingress-nginx-controller` Deployment | `--validating-webhook` | The address to start an admission controller on to validate incoming ingresses. Takes the form ":port". If not provided, no admission controller is started. | | `--validating-webhook-certificate` | The path of the validating webhook certificate PEM. | | `--validating-webhook-key` | The path of the validating webhook key PEM. | -| `--version` | Show release information about the NGINX Ingress controller and exit. | +| `--version` | Show release information about the Ingress-Nginx Controller and exit. | | `--watch-ingress-without-class` | Define if Ingress Controller should also watch for Ingresses without an IngressClass or the annotation specified. (default false) | | `--watch-namespace` | Namespace the controller watches for updates to Kubernetes objects. This includes Ingresses, Services and all configuration resources. All namespaces are watched if this parameter is left empty. | | `--watch-namespace-selector` | The controller will watch namespaces whose labels match the given selector. This flag only takes effective when `--watch-namespace` is empty. | diff --git a/docs/user-guide/exposing-tcp-udp-services.md b/docs/user-guide/exposing-tcp-udp-services.md index 6b595ffae..63293f0e5 100644 --- a/docs/user-guide/exposing-tcp-udp-services.md +++ b/docs/user-guide/exposing-tcp-udp-services.md @@ -63,3 +63,9 @@ spec: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx ``` +Then, the configmap should be added into ingress controller's deployment args. +``` + args: + - /nginx-ingress-controller + - --tcp-services-configmap=ingress-nginx/tcp-services +``` diff --git a/docs/user-guide/external-articles.md b/docs/user-guide/external-articles.md index d9fd828b8..27a3f4447 100644 --- a/docs/user-guide/external-articles.md +++ b/docs/user-guide/external-articles.md @@ -2,5 +2,5 @@ - [Pain(less) NGINX Ingress](http://danielfm.me/posts/painless-nginx-ingress.html) - [Accessing Kubernetes Pods from Outside of the Cluster](http://alesnosek.com/blog/2017/02/14/accessing-kubernetes-pods-from-outside-of-the-cluster) -- [Kubernetes - Redirect HTTP to HTTPS with ELB and the nginx ingress controller](https://dev.to/tomhoule/kubernetes---redirect-http-to-https-with-elb-and-the-nginx-ingress-controller) +- [Kubernetes - Redirect HTTP to HTTPS with ELB and the Ingress-Nginx Controller](https://dev.to/tomhoule/kubernetes---redirect-http-to-https-with-elb-and-the-nginx-ingress-controller) - [Configure Nginx Ingress Controller for TLS termination on Kubernetes on Azure](https://blogs.technet.microsoft.com/livedevopsinjapan/2017/02/28/configure-nginx-ingress-controller-for-tls-termination-on-kubernetes-on-azure-2/) diff --git a/docs/user-guide/k8s-122-migration.md b/docs/user-guide/k8s-122-migration.md new file mode 100644 index 000000000..9a1ca081d --- /dev/null +++ b/docs/user-guide/k8s-122-migration.md @@ -0,0 +1,245 @@ +# FAQ - Migration to Kubernetes 1.22 and apiVersion `networking.k8s.io/v1` + +If you are using Ingress objects in your cluster (running Kubernetes older than v1.22), +and you plan to upgrade to Kubernetes v1.22, this page is relevant to you. + +- Please read this [official blog on deprecated Ingress API versions](https://kubernetes.io/blog/2021/07/26/update-with-ingress-nginx/) +- Please read this [official documentation on the IngressClass object](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) + +## What is an IngressClass and why is it important for users of ingress-nginx controller now? + +IngressClass is a Kubernetes resource. See the description below. +It's important because until now, a default install of the ingress-nginx controller did not require a IngressClass object. +From version 1.0.0 of the ingress-nginx controller, an IngressClass object is required. + +On clusters with more than one instance of the ingress-nginx controller, all instances of the controllers must be aware of which Ingress objects they serve. +The `ingressClassName` field of an Ingress is the way to let the controller know about that. + +```console +kubectl explain ingressclass +``` + +``` +KIND: IngressClass +VERSION: networking.k8s.io/v1 +DESCRIPTION: + IngressClass represents the class of the Ingress, referenced by the Ingress + Spec. The `ingressclass.kubernetes.io/is-default-class` annotation can be + used to indicate that an IngressClass should be considered default. When a + single IngressClass resource has this annotation set to true, new Ingress + resources without a class specified will be assigned this default class. +FIELDS: + apiVersion + APIVersion defines the versioned schema of this representation of an + object. Servers should convert recognized schemas to the latest internal + value, and may reject unrecognized values. More info: + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + kind + Kind is a string value representing the REST resource this object + represents. Servers may infer this from the endpoint the client submits + requests to. Cannot be updated. In CamelCase. More info: + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + metadata + Standard object's metadata. More info: + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + spec + Spec is the desired state of the IngressClass. More info: + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status` +``` + +## What has caused this change in behavior? + +There are 2 primary reasons. + +### Reason 1 + +Until K8s version 1.21, it was possible to create an Ingress resource using deprecated versions of the Ingress API, such as: + +- `extensions/v1beta1` +- `networking.k8s.io/v1beta1` + You would get a message about deprecation, but the Ingress resource would get created. + +From K8s version 1.22 onwards, you can **only** access the Ingress API via the stable, `networking.k8s.io/v1` API. +The reason is explained in the [official blog on deprecated ingress API versions](https://kubernetes.io/blog/2021/07/26/update-with-ingress-nginx/). + +### Reason #2 + +If you are already using the ingress-nginx controller and then upgrade to Kubernetes 1.22, +there are several scenarios where your existing Ingress objects will not work how you expect. + +Read this FAQ to check which scenario matches your use case. + +## What is the `ingressClassName` field? + +`ingressClassName` is a field in the spec of an Ingress object. + +```shell +kubectl explain ingress.spec.ingressClassName +``` + +```console +KIND: Ingress +VERSION: networking.k8s.io/v1 +FIELD: ingressClassName +DESCRIPTION: + IngressClassName is the name of the IngressClass cluster resource. The + associated IngressClass defines which controller will implement the + resource. This replaces the deprecated `kubernetes.io/ingress.class` + annotation. For backwards compatibility, when that annotation is set, it + must be given precedence over this field. The controller may emit a warning + if the field and annotation have different values. Implementations of this + API should ignore Ingresses without a class specified. An IngressClass + resource may be marked as default, which can be used to set a default value + for this field. For more information, refer to the IngressClass + documentation. +``` + +The `.spec.ingressClassName` behavior has precedence over the deprecated `kubernetes.io/ingress.class` annotation. + +## I have only one ingress controller in my cluster. What should I do? + +If a single instance of the ingress-nginx controller is the sole Ingress controller running in your cluster, +you should add the annotation "ingressclass.kubernetes.io/is-default-class" in your IngressClass, +so any new Ingress objects will have this one as default IngressClass. + +When using Helm, you can enable this annotation by setting `.controller.ingressClassResource.default: true` in your Helm chart installation's values file. + +If you have any old Ingress objects remaining without an IngressClass set, you can do one or more of the following to make the ingress-nginx controller aware of the old objects: + +- You can manually set the [`.spec.ingressClassName`](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) field in the manifest of your own Ingress resources. +- You can re-create them after setting the `ingressclass.kubernetes.io/is-default-class` annotation to `true` on the IngressClass +- Alternatively you can make the ingress-nginx controller watch Ingress objects without the ingressClassName field set by starting your ingress-nginx with the flag [--watch-ingress-without-class=true](#what-is-the-flag-watch-ingress-without-class). + When using Helm, you can configure your Helm chart installation's values file with `.controller.watchIngressWithoutClass: true`. + +We recommend that you create the IngressClass as shown below: + +``` +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + labels: + app.kubernetes.io/component: controller + name: nginx + annotations: + ingressclass.kubernetes.io/is-default-class: "true" +spec: + controller: k8s.io/ingress-nginx +``` + +and add the value `spec.ingressClassName=nginx` in your Ingress objects. + +## I have many ingress objects in my cluster. What should I do? + +If you have a lot of ingress objects without ingressClass configuration, +you can run the ingress controller with the flag `--watch-ingress-without-class=true`. + +### What is the flag `--watch-ingress-without-class`? + +It's a flag that is passed, as an argument, to the `nginx-ingress-controller` executable. +In the configuration, it looks like this: + +```yaml +# ... +args: + - /nginx-ingress-controller + - --watch-ingress-without-class=true + - --controller-class=k8s.io/ingress-nginx + # ... +# ... +``` + +## I have more than one controller in my cluster, and I'm already using the annotation + +No problem. This should still keep working, but we highly recommend you to test! +Even though `kubernetes.io/ingress.class` is deprecated, the ingress-nginx controller still understands that annotation. +If you want to follow good practice, you should consider migrating to use IngressClass and `.spec.ingressClassName`. + +## I have more than one controller running in my cluster, and I want to use the new API + +In this scenario, you need to create multiple IngressClasses (see the example above). + +Be aware that IngressClass works in a very specific way: you will need to change the `.spec.controller` value in your IngressClass and configure the controller to expect the exact same value. + +Let's see an example, supposing that you have three IngressClasses: + +- IngressClass `ingress-nginx-one`, with `.spec.controller` equal to `example.com/ingress-nginx1` +- IngressClass `ingress-nginx-two`, with `.spec.controller` equal to `example.com/ingress-nginx2` +- IngressClass `ingress-nginx-three`, with `.spec.controller` equal to `example.com/ingress-nginx1` + +For private use, you can also use a controller name that doesn't contain a `/`, e.g. `ingress-nginx1`. + +When deploying your ingress controllers, you will have to change the `--controller-class` field as follows: + +- Ingress-Nginx A, configured to use controller class name `example.com/ingress-nginx1` +- Ingress-Nginx B, configured to use controller class name `example.com/ingress-nginx2` + +When you create an Ingress object with its `ingressClassName` set to `ingress-nginx-two`, +only controllers looking for the `example.com/ingress-nginx2` controller class pay attention to the new object. + +Given that Ingress-Nginx B is set up that way, it will serve that object, whereas Ingress-Nginx A ignores the new Ingress. + +Bear in mind that if you start Ingress-Nginx B with the command line argument `--watch-ingress-without-class=true`, it will serve: + +1. Ingresses without any `ingressClassName` set +2. Ingresses where the deprecated annotation (`kubernetes.io/ingress.class`) matches the value set in the command line argument `--ingress-class` +3. Ingresses that refer to any IngressClass that has the same `spec.controller` as configured in `--controller-class` +4. If you start Ingress-Nginx B with the command line argument `--watch-ingress-without-class=true` and you run Ingress-Nginx A with the command line argument `--watch-ingress-without-class=false` then this is a supported configuration. + If you have two ingress-nginx controllers for the same cluster, both running with `--watch-ingress-without-class=true` then there is likely to be a conflict. + +## Why am I seeing "ingress class annotation is not equal to the expected by Ingress Controller" in my controller logs? + +It is highly likely that you will also see the name of the ingress resource in the same error message. +This error message has been observed on use the deprecated annotation (`kubernetes.io/ingress.class`) in an Ingress resource manifest. +It is recommended to use the `.spec.ingressClassName` field of the Ingress resource, to specify the name of the IngressClass of the Ingress you are defining. + +## How can I easily install multiple instances of the ingress-nginx controller in the same cluster? + +You can install them in different namespaces. + +- Create a new namespace + ``` + kubectl create namespace ingress-nginx-2 + ``` +- Use Helm to install the additional instance of the ingress controller +- Ensure you have Helm working (refer to the [Helm documentation](https://helm.sh/docs/)) +- We have to assume that you have the helm repo for the ingress-nginx controller already added to your Helm config. + But, if you have not added the helm repo then you can do this to add the repo to your helm config; + ``` + helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx + ``` +- Make sure you have updated the helm repo data; + ``` + helm repo update + ``` +- Now, install an additional instance of the ingress-nginx controller like this: + ``` + helm install ingress-nginx-2 ingress-nginx/ingress-nginx \ + --namespace ingress-nginx-2 \ + --set controller.ingressClassResource.name=nginx-two \ + --set controller.ingressClass=nginx-two \ + --set controller.ingressClassResource.controllerValue="example.com/ingress-nginx-2" \ + --set controller.ingressClassResource.enabled=true \ + --set controller.ingressClassByName=true + ``` + +If you need to install yet another instance, then repeat the procedure to create a new namespace, +change the values such as names & namespaces (for example from "-2" to "-3"), or anything else that meets your needs. + +Note that `controller.ingressClassResource.name` and `controller.ingressClass` have to be set correctly. +The first is to create the IngressClass object and the other is to modify the deployment of the actual ingress controller pod. + +### I can't use multiple namespaces, what should I do? + +If you need to install all instances in the same namespace, then you need to specify a different **election id**, like this: + +``` +helm install ingress-nginx-2 ingress-nginx/ingress-nginx \ +--namespace kube-system \ +--set controller.electionID=nginx-two-leader \ +--set controller.ingressClassResource.name=nginx-two \ +--set controller.ingressClass=nginx-two \ +--set controller.ingressClassResource.controllerValue="example.com/ingress-nginx-2" \ +--set controller.ingressClassResource.enabled=true \ +--set controller.ingressClassByName=true +``` diff --git a/docs/user-guide/miscellaneous.md b/docs/user-guide/miscellaneous.md index 196ea17fc..e7d1ac59c 100644 --- a/docs/user-guide/miscellaneous.md +++ b/docs/user-guide/miscellaneous.md @@ -27,12 +27,12 @@ Support for websockets is provided by NGINX out of the box. No special configura The only requirement to avoid the close of connections is the increase of the values of `proxy-read-timeout` and `proxy-send-timeout`. -The default value of this settings is `60 seconds`. +The default value of these settings is `60 seconds`. A more adequate value to support websockets is a value higher than one hour (`3600`). !!! Important - If the NGINX ingress controller is exposed with a service `type=LoadBalancer` make sure the protocol between the loadbalancer and NGINX is TCP. + If the Ingress-Nginx Controller is exposed with a service `type=LoadBalancer` make sure the protocol between the loadbalancer and NGINX is TCP. ## Optimizing TLS Time To First Byte (TTTFB) @@ -52,4 +52,4 @@ The previous behavior can be restored using `retry-non-idempotent=true` in the c ## Why endpoints and not services -The NGINX ingress controller does not use [Services](http://kubernetes.io/docs/user-guide/services) to route traffic to the pods. Instead it uses the Endpoints API in order to bypass [kube-proxy](http://kubernetes.io/docs/admin/kube-proxy/) to allow NGINX features like session affinity and custom load balancing algorithms. It also removes some overhead, such as conntrack entries for iptables DNAT. +The Ingress-Nginx Controller does not use [Services](http://kubernetes.io/docs/user-guide/services) to route traffic to the pods. Instead it uses the Endpoints API in order to bypass [kube-proxy](http://kubernetes.io/docs/admin/kube-proxy/) to allow NGINX features like session affinity and custom load balancing algorithms. It also removes some overhead, such as conntrack entries for iptables DNAT. diff --git a/docs/user-guide/monitoring.md b/docs/user-guide/monitoring.md index cc9fb91ec..1e30e556f 100644 --- a/docs/user-guide/monitoring.md +++ b/docs/user-guide/monitoring.md @@ -6,14 +6,14 @@ Two different methods to install and configure Prometheus and Grafana are descri ## Prometheus and Grafana installation using Pod Annotations -This tutorial will show you how to install [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) for scraping the metrics of the NGINX Ingress controller. +This tutorial will show you how to install [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) for scraping the metrics of the Ingress-Nginx Controller. !!! important This example uses `emptyDir` volumes for Prometheus and Grafana. This means once the pod gets terminated you will lose all the data. ### Before You Begin -- The NGINX Ingress controller should already be deployed according to the deployment instructions [here](../deploy/index.md). +- The Ingress-Nginx Controller should already be deployed according to the deployment instructions [here](../deploy/index.md). - The controller should be configured for exporting metrics. This requires 3 configurations to the controller. These configurations are : 1. controller.metrics.enabled=true @@ -170,7 +170,7 @@ According to the above example, this URL will be http://10.192.0.3:31086 - By default request metrics are labeled with the hostname. When you have a wildcard domain ingress, then there will be no metrics for that ingress (to prevent the metrics from exploding in cardinality). To get metrics in this case you need to run the ingress controller with `--metrics-per-host=false` (you will lose labeling by hostname, but still have labeling by ingress). ### Grafana dashboard using ingress resource - - If you want to expose the dashboard for grafana using a ingress resource, then you can : + - If you want to expose the dashboard for grafana using an ingress resource, then you can : - change the service type of the prometheus-server service and the grafana service to "ClusterIP" like this : ``` kubectl -n ingress-nginx edit svc grafana @@ -178,15 +178,15 @@ According to the above example, this URL will be http://10.192.0.3:31086 - This will open the currently deployed service grafana in the default editor configured in your shell (vi/nvim/nano/other) - scroll down to line 34 that looks like "type: NodePort" - change it to look like "type: ClusterIP". Save and exit. - - create a ingress resource with backend as "grafana" and port as "3000" - - Similarly, you can edit the service "prometheus-server" and add a ingress resource. + - create an ingress resource with backend as "grafana" and port as "3000" + - Similarly, you can edit the service "prometheus-server" and add an ingress resource. ## Prometheus and Grafana installation using Service Monitors This document assumes you're using helm and using the kube-prometheus-stack package to install Prometheus and Grafana. -### Verify NGINX Ingress controller is installed +### Verify Ingress-Nginx Controller is installed -- The NGINX Ingress controller should already be deployed according to the deployment instructions [here](../deploy/index.md). +- The Ingress-Nginx Controller should already be deployed according to the deployment instructions [here](../deploy/index.md). - To check if Ingress controller is deployed, ``` @@ -214,7 +214,7 @@ This document assumes you're using helm and using the kube-prometheus-stack pack - If prometheus is not installed, then you can install from [here](https://artifacthub.io/packages/helm/prometheus-community/kube-prometheus-stack) -### Re-configure NGINX Ingress controller +### Re-configure Ingress-Nginx Controller - The Ingress NGINX controller needs to be reconfigured for exporting metrics. This requires 3 additional configurations to the controller. These configurations are : ``` @@ -355,56 +355,40 @@ Prometheus metrics are exposed on port 10254. ### Request metrics -* `nginx_ingress_controller_request_duration_seconds` Histogram - - The request processing time in seconds (affected by client speed) - +* `nginx_ingress_controller_request_duration_seconds` Histogram\ + The request processing (time elapsed between the first bytes were read from the client and the log write after the last bytes were sent to the client) time in seconds (affected by client speed).\ nginx var: `request_time` -* `nginx_ingress_controller_response_duration_seconds` Histogram - - The time spent on receiving the response from the upstream server (affected by client speed) - +* `nginx_ingress_controller_response_duration_seconds` Histogram\ + The time spent on receiving the response from the upstream server in seconds (affected by client speed when the response is bigger than proxy buffers).\ + Note: can be up to several millis bigger than the `nginx_ingress_controller_request_duration_seconds` because of the different measuring method. nginx var: `upstream_response_time` -* `nginx_ingress_controller_header_duration_seconds` Histogram - - The time spent on receiving first header from the upstream server - +* `nginx_ingress_controller_header_duration_seconds` Histogram\ + The time spent on receiving first header from the upstream server\ nginx var: `upstream_header_time` -* `nginx_ingress_controller_connect_duration_seconds` Histogram - - The time spent on establishing a connection with the upstream server - +* `nginx_ingress_controller_connect_duration_seconds` Histogram\ + The time spent on establishing a connection with the upstream server\ nginx var: `upstream_connect_time` -* `nginx_ingress_controller_response_size` Histogram - - The response length (including request line, header, and request body) - +* `nginx_ingress_controller_response_size` Histogram\ + The response length (including request line, header, and request body)\ nginx var: `bytes_sent` -* `nginx_ingress_controller_request_size` Histogram - - The request length (including request line, header, and request body) - +* `nginx_ingress_controller_request_size` Histogram\ + The request length (including request line, header, and request body)\ nginx var: `request_length` -* `nginx_ingress_controller_requests` Counter - +* `nginx_ingress_controller_requests` Counter\ The total number of client requests -* `nginx_ingress_controller_bytes_sent` Histogram - - The number of bytes sent to a client. **Deprecated**, use `nginx_ingress_controller_response_size` - +* `nginx_ingress_controller_bytes_sent` Histogram\ + The number of bytes sent to a client. **Deprecated**, use `nginx_ingress_controller_response_size`\ nginx var: `bytes_sent` -* `nginx_ingress_controller_ingress_upstream_latency_seconds` Summary - - Upstream service latency per Ingress. **Deprecated**, use `nginx_ingress_controller_connect_duration_seconds` - +* `nginx_ingress_controller_ingress_upstream_latency_seconds` Summary\ + Upstream service latency per Ingress. **Deprecated**, use `nginx_ingress_controller_connect_duration_seconds`\ nginx var: `upstream_connect_time` ``` @@ -469,6 +453,8 @@ Prometheus metrics are exposed on port 10254. # TYPE nginx_ingress_controller_ssl_certificate_info gauge # HELP nginx_ingress_controller_success Cumulative number of Ingress controller reload operations # TYPE nginx_ingress_controller_success counter +# HELP nginx_ingress_controller_orphan_ingress Gauge reporting status of ingress orphanity, 1 indicates orphaned ingress. 'namespace' is the string used to identify namespace of ingress, 'ingress' for ingress name and 'type' for 'no-service' or 'no-endpoint' of orphanity +# TYPE nginx_ingress_controller_orphan_ingress gauge ``` ### Admission metrics diff --git a/docs/user-guide/multiple-ingress.md b/docs/user-guide/multiple-ingress.md index 179041727..fca93ee65 100644 --- a/docs/user-guide/multiple-ingress.md +++ b/docs/user-guide/multiple-ingress.md @@ -2,7 +2,7 @@ By default, deploying multiple Ingress controllers (e.g., `ingress-nginx` & `gce`) will result in all controllers simultaneously racing to update Ingress status fields in confusing ways. -To fix this problem, use [IngressClasses](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class). The `kubernetes.io/ingress.class` annotation is not being preferred or suggested to use as it can be deprecated in future. Better to use the field `ingress.spec.ingressClassName`. +To fix this problem, use [IngressClasses](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class). The `kubernetes.io/ingress.class` annotation is not being preferred or suggested to use as it can be deprecated in the future. Better to use the field `ingress.spec.ingressClassName`. But, when user has deployed with `scope.enabled`, then the ingress class resource field is not used. @@ -111,7 +111,7 @@ spec: then setting the corresponding `kubernetes.io/ingress.class: "internal-nginx"` annotation on your Ingresses. -To reiterate, setting the annotation to any value which does not match a valid ingress class will force the NGINX Ingress controller to ignore your Ingress. -If you are only running a single NGINX ingress controller, this can be achieved by setting the annotation to any value except "nginx" or an empty string. +To reiterate, setting the annotation to any value which does not match a valid ingress class will force the Ingress-Nginx Controller to ignore your Ingress. +If you are only running a single Ingress-Nginx Controller, this can be achieved by setting the annotation to any value except "nginx" or an empty string. Do this if you wish to use one of the other Ingress controllers at the same time as the NGINX controller. diff --git a/docs/user-guide/nginx-configuration/annotations.md b/docs/user-guide/nginx-configuration/annotations.md index 8cc6f4c16..b515a9f3b 100755 --- a/docs/user-guide/nginx-configuration/annotations.md +++ b/docs/user-guide/nginx-configuration/annotations.md @@ -22,7 +22,7 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz |[nginx.ingress.kubernetes.io/auth-realm](#authentication)|string| |[nginx.ingress.kubernetes.io/auth-secret](#authentication)|string| |[nginx.ingress.kubernetes.io/auth-secret-type](#authentication)|string| -|[nginx.ingress.kubernetes.io/auth-type](#authentication)|basic or digest| +|[nginx.ingress.kubernetes.io/auth-type](#authentication)|"basic" or "digest"| |[nginx.ingress.kubernetes.io/auth-tls-secret](#client-certificate-authentication)|string| |[nginx.ingress.kubernetes.io/auth-tls-verify-depth](#client-certificate-authentication)|number| |[nginx.ingress.kubernetes.io/auth-tls-verify-client](#client-certificate-authentication)|string| @@ -121,11 +121,8 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz |[nginx.ingress.kubernetes.io/enable-access-log](#enable-access-log)|"true" or "false"| |[nginx.ingress.kubernetes.io/enable-opentracing](#enable-opentracing)|"true" or "false"| |[nginx.ingress.kubernetes.io/opentracing-trust-incoming-span](#opentracing-trust-incoming-span)|"true" or "false"| -|[nginx.ingress.kubernetes.io/enable-influxdb](#influxdb)|"true" or "false"| -|[nginx.ingress.kubernetes.io/influxdb-measurement](#influxdb)|string| -|[nginx.ingress.kubernetes.io/influxdb-port](#influxdb)|string| -|[nginx.ingress.kubernetes.io/influxdb-host](#influxdb)|string| -|[nginx.ingress.kubernetes.io/influxdb-server-name](#influxdb)|string| +|[nginx.ingress.kubernetes.io/enable-opentelemetry](#enable-opentelemetry)|"true" or "false"| +|[nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span](#opentelemetry-trust-incoming-spans)|"true" or "false"| |[nginx.ingress.kubernetes.io/use-regex](#use-regex)|bool| |[nginx.ingress.kubernetes.io/enable-modsecurity](#modsecurity)|bool| |[nginx.ingress.kubernetes.io/enable-owasp-core-rules](#modsecurity)|bool| @@ -239,7 +236,7 @@ To enable consistent hashing for a backend: `nginx.ingress.kubernetes.io/upstream-hash-by`: the nginx variable, text value or any combination thereof to use for consistent hashing. For example: `nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"` or `nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri$host"` or `nginx.ingress.kubernetes.io/upstream-hash-by: "${request_uri}-text-value"` to consistently hash upstream requests by the current request URI. -"subset" hashing can be enabled setting `nginx.ingress.kubernetes.io/upstream-hash-by-subset`: "true". This maps requests to subset of nodes instead of a single one. `upstream-hash-by-subset-size` determines the size of each subset (default 3). +"subset" hashing can be enabled setting `nginx.ingress.kubernetes.io/upstream-hash-by-subset`: "true". This maps requests to subset of nodes instead of a single one. `nginx.ingress.kubernetes.io/upstream-hash-by-subset-size` determines the size of each subset (default 3). Please check the [chashsubset](../../examples/chashsubset/deployment.yaml) example. @@ -601,7 +598,7 @@ the User guide. ### Service Upstream -By default the NGINX ingress controller uses a list of all endpoints (Pod IP/port) in the NGINX upstream configuration. +By default the Ingress-Nginx Controller uses a list of all endpoints (Pod IP/port) in the NGINX upstream configuration. The `nginx.ingress.kubernetes.io/service-upstream` annotation disables that behavior and instead uses a single upstream in NGINX, the service's Cluster IP and port. @@ -821,6 +818,24 @@ sometimes need to be overridden to enable it or disable it for a specific ingres nginx.ingress.kubernetes.io/opentracing-trust-incoming-span: "true" ``` +### Enable Opentelemetry + +Opentelemetry can be enabled or disabled globally through the ConfigMap but this will sometimes need to be overridden +to enable it or disable it for a specific ingress (e.g. to turn off telemetry of external health check endpoints) + +```yaml +nginx.ingress.kubernetes.io/enable-opentelemetry: "true" +``` + +### Opentelemetry Trust Incoming Span + +The option to trust incoming trace spans can be enabled or disabled globally through the ConfigMap but this will +sometimes need to be overridden to enable it or disable it for a specific ingress (e.g. only enable on a private endpoint) + +```yaml +nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-spans: "true" +``` + ### X-Forwarded-Prefix Header To add the non-standard `X-Forwarded-Prefix` header to the upstream request with a string value, the following annotation can be used: @@ -876,29 +891,6 @@ nginx.ingress.kubernetes.io/modsecurity-snippet: | Include /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf ``` -### InfluxDB - -Using `influxdb-*` annotations we can monitor requests passing through a Location by sending them to an InfluxDB backend exposing the UDP socket -using the [nginx-influxdb-module](https://github.com/influxdata/nginx-influxdb-module/). - -```yaml -nginx.ingress.kubernetes.io/enable-influxdb: "true" -nginx.ingress.kubernetes.io/influxdb-measurement: "nginx-reqs" -nginx.ingress.kubernetes.io/influxdb-port: "8089" -nginx.ingress.kubernetes.io/influxdb-host: "127.0.0.1" -nginx.ingress.kubernetes.io/influxdb-server-name: "nginx-ingress" -``` - -For the `influxdb-host` parameter you have two options: - -- Use an InfluxDB server configured with the [UDP protocol](https://docs.influxdata.com/influxdb/v1.5/supported_protocols/udp/) enabled. -- Deploy Telegraf as a sidecar proxy to the Ingress controller configured to listen UDP with the [socket listener input](https://github.com/influxdata/telegraf/tree/release-1.6/plugins/inputs/socket_listener) and to write using -anyone of the [outputs plugins](https://github.com/influxdata/telegraf/tree/release-1.7/plugins/outputs) like InfluxDB, Apache Kafka, -Prometheus, etc.. (recommended) - -It's important to remember that there's no DNS resolver at this stage so you will have to configure -an ip address to `nginx.ingress.kubernetes.io/influxdb-host`. If you deploy Influx or Telegraf as sidecar (another container in the same pod) this becomes straightforward since you can directly use `127.0.0.1`. - ### Backend Protocol Using `backend-protocol` annotations is possible to indicate how NGINX should communicate with the backend service. (Replaces `secure-backends` in older versions) diff --git a/docs/user-guide/nginx-configuration/configmap.md b/docs/user-guide/nginx-configuration/configmap.md old mode 100755 new mode 100644 index 77cee0507..ccb115a0f --- a/docs/user-guide/nginx-configuration/configmap.md +++ b/docs/user-guide/nginx-configuration/configmap.md @@ -62,7 +62,7 @@ The following table shows a configuration option's name, type, and the default v |[hsts-max-age](#hsts-max-age)|string|"15724800"| |[hsts-preload](#hsts-preload)|bool|"false"| |[keep-alive](#keep-alive)|int|75| -|[keep-alive-requests](#keep-alive-requests)|int|100| +|[keep-alive-requests](#keep-alive-requests)|int|1000| |[large-client-header-buffers](#large-client-header-buffers)|string|"4 8k"| |[log-format-escape-none](#log-format-escape-none)|bool|"false"| |[log-format-escape-json](#log-format-escape-json)|bool|"false"| @@ -103,7 +103,9 @@ The following table shows a configuration option's name, type, and the default v |[brotli-min-length](#brotli-min-length)|int|20| |[brotli-types](#brotli-types)|string|"application/xml+rss application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/javascript text/plain text/x-component"| |[use-http2](#use-http2)|bool|"true"| +|[gzip-disable](#gzip-disable)|string|""| |[gzip-level](#gzip-level)|int|1| +|[gzip-min-length](#gzip-min-length)|int|256| |[gzip-types](#gzip-types)|string|"application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/javascript text/plain text/x-component"| |[worker-processes](#worker-processes)|string|``| |[worker-cpu-affinity](#worker-cpu-affinity)|string|""| @@ -155,6 +157,19 @@ The following table shows a configuration option's name, type, and the default v |[datadog-operation-name-override](#datadog-operation-name-override)|string|"nginx.handle"| |[datadog-priority-sampling](#datadog-priority-sampling)|bool|"true"| |[datadog-sample-rate](#datadog-sample-rate)|float|1.0| +|[enable-opentelemetry](#enable-opentelemetry)|bool|"false"| +|[opentelemetry-trust-incoming-span](#opentelemetry-trust-incoming-span)|bool|"true"| +|[opentelemetry-operation-name](#opentelemetry-operation-name)|string|""| +|[opentelemetry-config](#/etc/nginx/opentelemetry.toml)|string|"/etc/nginx/opentelemetry.toml"| +|[otlp-collector-host](#otlp-collector-host)|string|""| +|[otlp-collector-port](#otlp-collector-port)|int|4317| +|[otel-max-queuesize](#otel-max-queuesize)|int|| +|[otel-schedule-delay-millis](#otel-schedule-delay-millis)|int|| +|[otel-max-export-batch-size](#otel-max-export-batch-size)|int|| +|[otel-service-name](#otel-service-name)|string|"nginx"| +|[otel-sampler](#otel-sampler)|string|"AlwaysOff"| +|[otel-sampler-parent-based](#otel-sampler-parent-based)|bool|"false"| +|[otel-sampler-ratio](#otel-sampler-ratio)|float|0.01| |[main-snippet](#main-snippet)|string|""| |[http-snippet](#http-snippet)|string|""| |[server-snippet](#server-snippet)|string|""| @@ -693,7 +708,8 @@ _**default:**_ false ## enable-brotli Enables or disables compression of HTTP responses using the ["brotli" module](https://github.com/google/ngx_brotli). -The default mime type list to compress is: `application/xml+rss application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component`. _**default:**_ is disabled +The default mime type list to compress is: `application/xml+rss application/atom+xml application/javascript application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component`. +_**default:**_ false > __Note:__ Brotli does not works in Safari < 11. For more information see [https://caniuse.com/#feat=brotli](https://caniuse.com/#feat=brotli) @@ -714,6 +730,10 @@ _**default:**_ `application/xml+rss application/atom+xml application/javascript Enables or disables [HTTP/2](https://nginx.org/en/docs/http/ngx_http_v2_module.html) support in secure connections. +## gzip-disable + +Disables [gzipping](http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_disable) of responses for requests with "User-Agent" header fields matching any of the specified regular expressions. + ## gzip-level Sets the gzip Compression Level that will be used. _**default:**_ 1 @@ -1002,6 +1022,46 @@ If true disables client-side sampling (thus ignoring `sample_rate`) and enables Specifies sample rate for any traces created. This is effective only when `datadog-priority-sampling` is `false` _**default:**_ 1.0 +## enable-opentelemetry + +Enables the nginx OpenTelemetry extension. _**default:**_ is disabled + +_References:_ +[https://github.com/open-telemetry/opentelemetry-cpp-contrib](https://github.com/open-telemetry/opentelemetry-cpp-contrib/tree/main/instrumentation/nginx) + +## opentelemetry-operation-name + +Specifies a custom name for the server span. _**default:**_ is empty + +For example, set to "HTTP $request_method $uri". + +## otlp-collector-host + +Specifies the host to use when uploading traces. It must be a valid URL. + +## otlp-collector-port + +Specifies the port to use when uploading traces. _**default:**_ 4317 + +## otel-service-name + +Specifies the service name to use for any traces created. _**default:**_ nginx + +## opentelemetry-trust-incoming-span: "true" +Enables or disables using spans from incoming requests as parent for created ones. _**default:**_ true + +## otel-sampler-parent-based + +Uses sampler implementation which by default will take a sample if parent Activity is sampled. _**default:**_ false + +## otel-sampler-ratio + +Specifies sample rate for any traces created. _**default:**_ 0.01 + +## otel-sampler + +Specifies the sampler to be used when sampling traces. The available samplers are: AlwaysOff, AlwaysOn, TraceIdRatioBased, remote. _**default:**_ AlwaysOff + ## main-snippet Adds custom configuration to the main section of the nginx configuration. diff --git a/docs/user-guide/third-party-addons/opentelemetry.md b/docs/user-guide/third-party-addons/opentelemetry.md new file mode 100644 index 000000000..1b9b6536e --- /dev/null +++ b/docs/user-guide/third-party-addons/opentelemetry.md @@ -0,0 +1,260 @@ +# OpenTelemetry + +Enables requests served by NGINX for distributed telemetry via The OpenTelemetry Project. + +Using the third party module [opentelemetry-cpp-contrib/nginx](https://github.com/open-telemetry/opentelemetry-cpp-contrib/tree/main/instrumentation/nginx) the Ingress-Nginx Controller can configure NGINX to enable [OpenTelemetry](http://opentelemetry.io) instrumentation. +By default this feature is disabled. + +## Usage + +To enable the instrumentation we must enable OpenTelemetry in the configuration ConfigMap: +```yaml +data: + enable-opentelemetry: "true" +``` + +To enable or disable instrumentation for a single Ingress, use +the `enable-opentelemetry` annotation: +```yaml +kind: Ingress +metadata: + annotations: + nginx.ingress.kubernetes.io/enable-opentelemetry: "true" +``` + +We must also set the host to use when uploading traces: + +```yaml +otlp-collector-host: "otel-coll-collector.otel.svc" +``` +NOTE: While the option is called `otlp-collector-host`, you will need to point this to any backend that receives otlp-grpc. + +Next you will need to deploy a distributed telemetry system which uses OpenTelemetry. +[opentelemetry-collector](https://github.com/open-telemetry/opentelemetry-collector), [Jaeger](https://www.jaegertracing.io/) +[Tempo](https://github.com/grafana/tempo), and [zipkin](https://zipkin.io/) +have been tested. + +Other optional configuration options: +```yaml +# specifies the name to use for the server span +opentelemetry-operation-name + +# sets whether or not to trust incoming telemetry spans +opentelemetry-trust-incoming-span + +# specifies the port to use when uploading traces, Default: 4317 +otlp-collector-port + +# specifies the service name to use for any traces created, Default: nginx +otel-service-name + +# The maximum queue size. After the size is reached data are dropped. +otel-max-queuesize + +# The delay interval in milliseconds between two consecutive exports. +otel-schedule-delay-millis + +# How long the export can run before it is cancelled. +otel-schedule-delay-millis + +# The maximum batch size of every export. It must be smaller or equal to maxQueueSize. +otel-max-export-batch-size + +# specifies sample rate for any traces created, Default: 0.01 +otel-sampler-ratio + +# specifies the sampler to be used when sampling traces. +# The available samplers are: AlwaysOn, AlwaysOff, TraceIdRatioBased, Default: AlwaysOff +otel-sampler + +# Uses sampler implementation which by default will take a sample if parent Activity is sampled, Default: false +otel-sampler-parent-based +``` + +Note that you can also set whether to trust incoming spans (global default is true) per-location using annotations like the following: +```yaml +kind: Ingress +metadata: + annotations: + nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span: "true" +``` + +## Examples + +The following examples show how to deploy and test different distributed telemetry systems. These example can be performed using Docker Desktop. + +In the [esigo/nginx-example](https://github.com/esigo/nginx-example) +GitHub repository is an example of a simple hello service: + +```mermaid +graph TB + subgraph Browser + start["http://esigo.dev/hello/nginx"] + end + + subgraph app + sa[service-a] + sb[service-b] + sa --> |name: nginx| sb + sb --> |hello nginx!| sa + end + + subgraph otel + otc["Otel Collector"] + end + + subgraph observability + tempo["Tempo"] + grafana["Grafana"] + backend["Jaeger"] + zipkin["Zipkin"] + end + + subgraph ingress-nginx + ngx[nginx] + end + + subgraph ngx[nginx] + ng[nginx] + om[OpenTelemetry module] + end + + subgraph Node + app + otel + observability + ingress-nginx + om --> |otlp-gRPC| otc --> |jaeger| backend + otc --> |zipkin| zipkin + otc --> |otlp-gRPC| tempo --> grafana + sa --> |otlp-gRPC| otc + sb --> |otlp-gRPC| otc + start --> ng --> sa + end +``` + +To install the example and collectors run: + +1. Enable Ingress addon with: + + ```yaml + opentelemetry: + enabled: true + image: registry.k8s.io/ingress-nginx/opentelemetry:v20230107-helm-chart-4.4.2-2-g96b3d2165@sha256:331b9bebd6acfcd2d3048abbdd86555f5be76b7e3d0b5af4300b04235c6056c9 + containerSecurityContext: + allowPrivilegeEscalation: false + ``` + +2. Enable OpenTelemetry and set the otlp-collector-host: + + ```yaml + $ echo ' + apiVersion: v1 + kind: ConfigMap + data: + enable-opentelemetry: "true" + opentelemetry-config: "/etc/nginx/opentelemetry.toml" + opentelemetry-operation-name: "HTTP $request_method $service_name $uri" + opentelemetry-trust-incoming-span: "true" + otlp-collector-host: "otel-coll-collector.otel.svc" + otlp-collector-port: "4317" + otel-max-queuesize: "2048" + otel-schedule-delay-millis: "5000" + otel-max-export-batch-size: "512" + otel-service-name: "nginx-proxy" # Opentelemetry resource name + otel-sampler: "AlwaysOn" # Also: AlwaysOff, TraceIdRatioBased + otel-sampler-ratio: "1.0" + otel-sampler-parent-based: "false" + metadata: + name: ingress-nginx-controller + namespace: ingress-nginx + ' | kubectl replace -f - + ``` + +4. Deploy otel-collector, grafana and Jaeger backend: + + ```bash + # add helm charts needed for grafana and OpenTelemetry collector + helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts + helm repo add grafana https://grafana.github.io/helm-charts + helm repo update + # deply cert-manager needed for OpenTelemetry collector operator + kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml + # create observability namespace + kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/namespace.yaml + # install OpenTelemetry collector operator + helm upgrade --install otel-collector-operator -n otel --create-namespace open-telemetry/opentelemetry-operator + # deploy OpenTelemetry collector + kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/collector.yaml + # deploy Jaeger all-in-one + kubectl apply -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.37.0/jaeger-operator.yaml -n observability + kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/jaeger.yaml -n observability + # deploy zipkin + kubectl apply -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/zipkin.yaml -n observability + # deploy tempo and grafana + helm upgrade --install tempo grafana/tempo --create-namespace -n observability + helm upgrade -f https://raw.githubusercontent.com/esigo/nginx-example/main/observability/grafana/grafana-values.yaml --install grafana grafana/grafana --create-namespace -n observability + ``` + +3. Build and deploy demo app: + + ```bash + # build images + make images + + # deploy demo app: + make deploy-app + ``` + +5. Make a few requests to the Service: + + ```bash + kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8090:80 + curl http://esigo.dev:8090/hello/nginx + + + StatusCode : 200 + StatusDescription : OK + Content : {"v":"hello nginx!"} + + RawContent : HTTP/1.1 200 OK + Connection: keep-alive + Content-Length: 21 + Content-Type: text/plain; charset=utf-8 + Date: Mon, 10 Oct 2022 17:43:33 GMT + + {"v":"hello nginx!"} + + Forms : {} + Headers : {[Connection, keep-alive], [Content-Length, 21], [Content-Type, text/plain; charset=utf-8], [Date, + Mon, 10 Oct 2022 17:43:33 GMT]} + Images : {} + InputFields : {} + Links : {} + ParsedHtml : System.__ComObject + RawContentLength : 21 + ``` + +6. View the Grafana UI: + + ```bash + kubectl port-forward --namespace=observability service/grafana 3000:80 + ``` + In the Grafana interface we can see the details: + ![grafana screenshot](../../images/otel-grafana-demo.png "grafana screenshot") + +7. View the Jaeger UI: + + ```bash + kubectl port-forward --namespace=observability service/jaeger-all-in-one-query 16686:16686 + ``` + In the Jaeger interface we can see the details: + ![Jaeger screenshot](../../images/otel-jaeger-demo.png "Jaeger screenshot") + +8. View the Zipkin UI: + + ```bash + kubectl port-forward --namespace=observability service/zipkin 9411:9411 + ``` + In the Zipkin interface we can see the details: + ![zipkin screenshot](../../images/otel-zipkin-demo.png "zipkin screenshot") diff --git a/docs/user-guide/third-party-addons/opentracing.md b/docs/user-guide/third-party-addons/opentracing.md index 6ed0f195e..f5ec59faf 100644 --- a/docs/user-guide/third-party-addons/opentracing.md +++ b/docs/user-guide/third-party-addons/opentracing.md @@ -2,7 +2,7 @@ Enables requests served by NGINX for distributed tracing via The OpenTracing Project. -Using the third party module [opentracing-contrib/nginx-opentracing](https://github.com/opentracing-contrib/nginx-opentracing) the NGINX ingress controller can configure NGINX to enable [OpenTracing](http://opentracing.io) instrumentation. +Using the third party module [opentracing-contrib/nginx-opentracing](https://github.com/opentracing-contrib/nginx-opentracing) the Ingress-Nginx Controller can configure NGINX to enable [OpenTracing](http://opentracing.io) instrumentation. By default this feature is disabled. ## Usage diff --git a/ginkgo_upgrade.md b/ginkgo_upgrade.md new file mode 100644 index 000000000..1ed996cd1 --- /dev/null +++ b/ginkgo_upgrade.md @@ -0,0 +1,131 @@ +# GINKGO UPGRADE + +#### Bumping ginkgo in the project requires four PRs. + +## 1. Dependabot PR + +- Dependabot automatically updates `ginkgo version` but only in [go.mod ](go.mod) and [go.sum ](go.sum) files. +- This is an automatically generated PR by Dependabot but it needs approval from maintainers to get merged. + +## 2. Edit-hardcoded-version PR + +### a. Make changes to appropriate files in required directories + +- Make changes in files where gingko version is hardcoded. These files are : + - [run-in-docker.sh ](build/run-in-docker.sh) + - [Dockerfile ](images/test-runner/rootfs/Dockerfile) + - [run.sh ](test/e2e/run.sh) + - [run-chart-test.sh ](test/e2e/run-chart-test.sh) + +### b. Create PR + +- Open pull request(s) accordingly, to fire cloudbuild for building the component's image (if applicable). + +### c. Merge + +- Merging will fire cloudbuild, which will result in images being promoted to the [staging container registry](https://console.cloud.google.com/gcr/images/k8s-staging-ingress-nginx). + +### d. Make sure cloudbuild is a success + +- Wait for [cloud build](https://console.cloud.google.com/cloud-build/builds?project=k8s-staging-ingress-nginx). If you don't have access to cloudbuild, you can also have a look at [this](https://prow.k8s.io/?repo=kubernetes%2Fingress-nginx&job=post-*), to see the progress of the build. + +- Proceed only after cloud-build is successful in building a new Ingress-Nginx-Controller image. + + +## 3. PROMOTE the new-testrunner-image PR: + +Promoting the images basically means that images, that were pushed to staging container registry in the steps above, now are also pushed to the public container registry. Thus are publicly available. Follow these steps to promote images: +- When you make changes to the `Dockerfile` or other core content under [images directory ](images), it generates a new image in google cloudbuild. This is because kubernetes projects need to use the infra provided for the kubernetes projects. The new image is always only pushed to the staging repository of K8S. From the staging repo, the new image needs to be promoted to the production repo. And once promoted, its possible to use the sha of the new image in the code. + +### a. Get the sha + +- Get the sha of the new image(s) of the controller, from the cloudbuild, from steps above + + - The sha is available in output from [cloud build](https://console.cloud.google.com/cloud-build/builds?project=k8s-staging-ingress-nginx) + + - The sha is also visible [here](https://console.cloud.google.com/gcr/images/k8s-staging-ingress-nginx/global/e2e-test-runner) + + - The sha is also visible [here]((https://prow.k8s.io/?repo=kubernetes%2Fingress-nginx&job=post-*)), after cloud build is finished. Click on the respective job, go to `Artifacts` section in the UI, then again `artifacts` in the directory browser. In the `build.log` at the very bottom you see something like this: + + ``` + ... + pushing manifest for gcr.io/k8s-staging-ingress-nginx/controller:v1.0.2@sha256:e15fac6e8474d77e1f017edc33d804ce72a184e3c0a30963b2a0d7f0b89f6b16 + ... + ``` + +### b. Add the new image to [k8s.io](http://github.com/kubernetes/k8s.io) + +- The sha(s) from the step before (and the tag(s) for the new image(s) have to be added, as a new line, in a file, of the [k8s.io](http://github.com/kubernetes/k8s.io) project of Kubernetes organization. + +- Fork that other project (if you don't have a fork already). + +- Other project to fork [Github repo kubernetes/k8s.io](http://github.com/kubernetes/k8s.io) + +- Fetch --all and rebase to upstream if already forked. + +- Create a branch in your fork, named as the issue number for this release + +- In the related branch, of your fork, edit the file k8s.gcr.io/images/k8s-staging-ingress-nginx/images.yaml. + +- For making it easier, you can edit your branch directly in the browser. But be careful about making any mistake. + +- Insert the sha(s) & the tag(s), in a new line, in this file [Project kubernetes/k8s.io Ingress-Nginx-Controller Images](https://github.com/kubernetes/k8s.io/blob/main/k8s.gcr.io/images/k8s-staging-ingress-nginx/images.yaml) Look at this [example PR and the diff](https://github.com/kubernetes/k8s.io/pull/4499) to see how it was done before + +- Save and commit + +### c. Create PR + +- Open pull request to promote the new e2e-test-runner image. + +### d. Merge + +- Merge success is required. + +- Proceed only after cloud-build is successful in building a new e2e-test-runner image. + + +## 4. Change testrunner-image-sha PR + +### a. Get the sha + +- Make sure to get the tag and sha of the promoted image from the step before, either from cloudbuild or from [here](https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/ingress-nginx/e2e-test-runner). + +### a. Make sure your git workspace is ready + +- Get your git workspace ready + + - If not using a pre-existing fork, then Fork the repo kubernetes/ingress-nginx + + - Clone (to laptop or wherever) + + - Add upstream + + - Set upstream url to no_push + + - Checkout & switch to branch, named as per related new-release-issue-number + + - If already forked, and upstream already added, then `git fetch --all` and `git rebase upstream/main` (not origin) + + - Checkout a branch in your fork's clone + + - Perform any other diligence as needed + +- Prefer to edit only and only in your branch, in your Fork + +### b. Change testrunner-image-sha + +- You need update the testrunner-image-sha in the following files : + + - [run-in-docker.sh](https://github.com/kubernetes/ingress-nginx/blob/main/build/run-in-docker.sh#L41) + - [Makefile](https://github.com/kubernetes/ingress-nginx/blob/main/test/e2e-image/Makefile#L3) + +### c. Create PR + +- Look at this PR for how it was done before [example PR](https://github.com/kubernetes/ingress-nginx/pull/9444) +- Create a PR + +### d. Merge + +- Finally merge the PR. + +## END ## \ No newline at end of file diff --git a/go.mod b/go.mod index 2daf8e667..9de23ba1a 100644 --- a/go.mod +++ b/go.mod @@ -1,64 +1,54 @@ module k8s.io/ingress-nginx -go 1.19 +go 1.20 require ( github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a github.com/eapache/channels v1.1.0 github.com/fsnotify/fsnotify v1.6.0 - github.com/imdario/mergo v0.3.13 + github.com/imdario/mergo v0.3.15 github.com/json-iterator/go v1.1.12 github.com/kylelemons/godebug v1.1.0 github.com/mitchellh/go-ps v1.0.0 - github.com/mitchellh/hashstructure v1.1.0 + github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/mapstructure v1.5.0 github.com/moul/pb v0.0.0-20220425114252-bca18df4138c github.com/ncabatoff/process-exporter v0.7.10 - github.com/onsi/ginkgo/v2 v2.6.1 - github.com/opencontainers/runc v1.1.4 + github.com/onsi/ginkgo/v2 v2.9.0 + github.com/opencontainers/runc v1.1.7 github.com/pmezard/go-difflib v1.0.0 - github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_golang v1.15.0 github.com/prometheus/client_model v0.3.0 - github.com/prometheus/common v0.39.0 - github.com/spf13/cobra v1.6.1 + github.com/prometheus/common v0.42.0 + github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.2 github.com/yudai/gojsondiff v1.0.0 github.com/zakjan/cert-chain-resolver v0.0.0-20211122211144-c6b0b792af9a - golang.org/x/crypto v0.5.0 - google.golang.org/grpc v1.51.0 + golang.org/x/crypto v0.8.0 + google.golang.org/grpc v1.54.0 google.golang.org/grpc/examples v0.0.0-20221220003428-4f16fbe410f7 gopkg.in/go-playground/pool.v3 v3.1.1 gopkg.in/mcuadros/go-syslog.v2 v2.3.0 - k8s.io/api v0.25.4 - k8s.io/apiextensions-apiserver v0.25.0 - k8s.io/apimachinery v0.25.4 - k8s.io/apiserver v0.25.0 - k8s.io/cli-runtime v0.25.0 - k8s.io/client-go v0.25.4 - k8s.io/code-generator v0.25.0 - k8s.io/component-base v0.25.4 - k8s.io/klog/v2 v2.80.1 + k8s.io/api v0.26.4 + k8s.io/apiextensions-apiserver v0.26.4 + k8s.io/apimachinery v0.26.4 + k8s.io/apiserver v0.26.4 + k8s.io/cli-runtime v0.26.4 + k8s.io/client-go v0.26.4 + k8s.io/code-generator v0.26.4 + k8s.io/component-base v0.26.4 + k8s.io/klog/v2 v2.90.1 pault.ag/go/sniff v0.0.0-20200207005214-cf7e4d167732 - sigs.k8s.io/controller-runtime v0.13.1 + sigs.k8s.io/controller-runtime v0.14.6 sigs.k8s.io/mdtoc v1.1.0 ) require ( - cloud.google.com/go/compute v1.12.1 // indirect - cloud.google.com/go/compute/metadata v0.2.1 // indirect - github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest v0.11.27 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.20 // indirect - github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect - github.com/Azure/go-autorest/logger v0.2.1 // indirect - github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/BurntSushi/toml v1.0.0 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -70,22 +60,23 @@ require ( github.com/go-errors/errors v1.0.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/swag v0.19.14 // indirect + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/godbus/dbus/v5 v5.0.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.2.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/gomarkdown/markdown v0.0.0-20210514010506-3b9f47219fe7 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.1.0 // indirect + github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect - github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.6 // indirect @@ -98,34 +89,35 @@ require ( github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/ncabatoff/go-seq v0.0.0-20180805175032-b08ef85ed833 // indirect + github.com/onsi/ginkgo v1.16.5 // indirect github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect github.com/sergi/go-diff v1.1.0 // indirect github.com/sirupsen/logrus v1.8.1 // indirect github.com/xlab/treeprint v1.1.0 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect github.com/yudai/pp v2.0.1+incompatible // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect - golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.5.0 // indirect - golang.org/x/oauth2 v0.3.0 // indirect - golang.org/x/sys v0.4.0 // indirect - golang.org/x/term v0.4.0 // indirect - golang.org/x/text v0.6.0 // indirect - golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect - golang.org/x/tools v0.4.0 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/net v0.9.0 // indirect + golang.org/x/oauth2 v0.5.0 // indirect + golang.org/x/sys v0.7.0 // indirect + golang.org/x/term v0.7.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.6.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect - k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect - k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect + k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect + k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect + k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect sigs.k8s.io/kustomize/api v0.12.1 // indirect sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect diff --git a/go.sum b/go.sum index 84a8bb106..da99bd248 100644 --- a/go.sum +++ b/go.sum @@ -19,10 +19,6 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= -cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -35,30 +31,10 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -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.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A= -github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= -github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.20 h1:gJ3E98kMpFB1MFqQCvA1yFab8vthOeD4VlFRQULxahg= -github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= -github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= -github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -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= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -74,19 +50,15 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -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.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= @@ -94,7 +66,6 @@ github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxG 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/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/eapache/channels v1.1.0 h1:F1taHcn7/F0i8DYqKXJnyhJcVpp2kgFcNePxXtnyu4k= github.com/eapache/channels v1.1.0/go.mod h1:jMm2qB5Ubtg9zLd+inMZd2/NUvXgzmWXsDaLyQIGfH0= @@ -110,7 +81,8 @@ github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fullsailor/pkcs7 v0.0.0-20160414161337-2585af45975b h1:074/xhloHUBOpTZwlIzQ28rbPY8pNJvzY7Gcx5KnNOk= @@ -126,7 +98,6 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb 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/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= @@ -135,21 +106,20 @@ github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= 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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= -github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -178,8 +148,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/gomarkdown/markdown v0.0.0-20210514010506-3b9f47219fe7 h1:oKYOfNR7Hp6XpZ4JqolL5u642Js5Z0n7psPVl+S5heo= github.com/gomarkdown/markdown v0.0.0-20210514010506-3b9f47219fe7/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -212,6 +183,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -223,11 +196,13 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWet github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= +github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -249,8 +224,8 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -272,8 +247,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= -github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0= -github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= +github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= +github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mmarkdown/mmark v2.0.40+incompatible h1:vMeUeDzBK3H+/mU0oMVfMuhSXJlIA+DE/DMPQNAj5C4= @@ -291,7 +266,6 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/moul/pb v0.0.0-20220425114252-bca18df4138c h1:1STmblv9zmHLDpru4dbnf1PNL6wrrZNf7yBH+SfQU+s= github.com/moul/pb v0.0.0-20220425114252-bca18df4138c/go.mod h1:jE2HT8eoucYyUPBFJMreiVlC3KPHkDMtN8wn+ef7Y64= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -302,16 +276,22 @@ github.com/ncabatoff/go-seq v0.0.0-20180805175032-b08ef85ed833/go.mod h1:0CznHmX github.com/ncabatoff/process-exporter v0.7.10 h1:+Ere7+3se6QqP54gg7aBRagWcL8bq3u5zNi/GRSWeKQ= github.com/ncabatoff/process-exporter v0.7.10/go.mod h1:DHZRZjqxw9LCOpLlX0DjBuyn6d5plh41Jv6Tmttj7Ek= 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/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.6.1 h1:1xQPCjcqYw/J5LchOcp4/2q/jzJFjiAOc25chhnDw+Q= -github.com/onsi/ginkgo/v2 v2.6.1/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= -github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= -github.com/opencontainers/runc v1.1.4 h1:nRCz/8sKg6K6jgYAFLDlXzPeITBZJyX28DBVhWD+5dg= -github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.9.0 h1:Tugw2BKlNHTMfG+CheOITkYvk4LAh6MFOvikhGVnhE8= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.27.1 h1:rfztXRbg6nv/5f+Raen9RcGoSecHIFgBBLQK3Wdj754= +github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= +github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -325,8 +305,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -337,34 +317,30 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/exporter-toolkit v0.7.0/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= 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/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= -github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 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/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= @@ -382,13 +358,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/urfave/cli v1.17.1-0.20160602030128-01a33823596e/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -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/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= @@ -412,7 +384,7 @@ go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee33 go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -421,10 +393,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= 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= @@ -455,10 +425,11 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB 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/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -471,7 +442,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -482,25 +452,24 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/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-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= -golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -511,9 +480,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= 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= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -522,13 +491,14 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-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= 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= @@ -549,33 +519,32 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= 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/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -618,9 +587,10 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +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.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -680,8 +650,8 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 h1:a2S6M0+660BgMNl++4JPlcAO/CjkqYItDEZwkoDQK7c= -google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -694,8 +664,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc/examples v0.0.0-20221220003428-4f16fbe410f7 h1:pPsdyuBif+uoyUoL19yuj/TCfUPsmpJHJZhWQ98JGLU= google.golang.org/grpc/examples v0.0.0-20221220003428-4f16fbe410f7/go.mod h1:8pQa1yxxkh+EsxUK8/455D5MSbv3vgmEJqKCH3y17mI= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -710,9 +680,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -721,6 +690,7 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 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= @@ -730,6 +700,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/mcuadros/go-syslog.v2 v2.3.0 h1:kcsiS+WsTKyIEPABJBJtoG0KkOS6yzvJ+/eZlhD79kk= gopkg.in/mcuadros/go-syslog.v2 v2.3.0/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 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= @@ -740,7 +711,6 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -750,39 +720,38 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.25.4 h1:3YO8J4RtmG7elEgaWMb4HgmpS2CfY1QlaOz9nwB+ZSs= -k8s.io/api v0.25.4/go.mod h1:IG2+RzyPQLllQxnhzD8KQNEu4c4YvyDTpSMztf4A0OQ= -k8s.io/apiextensions-apiserver v0.25.0 h1:CJ9zlyXAbq0FIW8CD7HHyozCMBpDSiH7EdrSTCZcZFY= -k8s.io/apiextensions-apiserver v0.25.0/go.mod h1:3pAjZiN4zw7R8aZC5gR0y3/vCkGlAjCazcg1me8iB/E= -k8s.io/apimachinery v0.25.4 h1:CtXsuaitMESSu339tfhVXhQrPET+EiWnIY1rcurKnAc= -k8s.io/apimachinery v0.25.4/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= -k8s.io/apiserver v0.25.0 h1:8kl2ifbNffD440MyvHtPaIz1mw4mGKVgWqM0nL+oyu4= -k8s.io/apiserver v0.25.0/go.mod h1:BKwsE+PTC+aZK+6OJQDPr0v6uS91/HWxX7evElAH6xo= -k8s.io/cli-runtime v0.25.0 h1:XBnTc2Fi+w818jcJGzhiJKQuXl8479sZ4FhtV5hVJ1Q= -k8s.io/cli-runtime v0.25.0/go.mod h1:bHOI5ZZInRHhbq12OdUiYZQN8ml8aKZLwQgt9QlLINw= -k8s.io/client-go v0.25.4 h1:3RNRDffAkNU56M/a7gUfXaEzdhZlYhoW8dgViGy5fn8= -k8s.io/client-go v0.25.4/go.mod h1:8trHCAC83XKY0wsBIpbirZU4NTUpbuhc2JnI7OruGZw= -k8s.io/code-generator v0.25.0 h1:QP8fJuXu882ztf6dsqJsso/Btm94pMd68TAZC1rE6KI= -k8s.io/code-generator v0.25.0/go.mod h1:B6jZgI3DvDFAualltPitbYMQ74NjaCFxum3YeKZZ+3w= -k8s.io/component-base v0.25.4 h1:n1bjg9Yt+G1C0WnIDJmg2fo6wbEU1UGMRiQSjmj7hNQ= -k8s.io/component-base v0.25.4/go.mod h1:nnZJU8OP13PJEm6/p5V2ztgX2oyteIaAGKGMYb2L2cY= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/api v0.26.4 h1:qSG2PmtcD23BkYiWfoYAcak870eF/hE7NNYBYavTT94= +k8s.io/api v0.26.4/go.mod h1:WwKEXU3R1rgCZ77AYa7DFksd9/BAIKyOmRlbVxgvjCk= +k8s.io/apiextensions-apiserver v0.26.4 h1:9D2RTxYGxrG5uYg6D7QZRcykXvavBvcA59j5kTaedQI= +k8s.io/apiextensions-apiserver v0.26.4/go.mod h1:cd4uGFGIgzEqUghWpRsr9KE8j2KNTjY8Ji8pnMMazyw= +k8s.io/apimachinery v0.26.4 h1:rZccKdBLg9vP6J09JD+z8Yr99Ce8gk3Lbi9TCx05Jzs= +k8s.io/apimachinery v0.26.4/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= +k8s.io/apiserver v0.26.4 h1:3Oq4mnJv0mzVX7BR/Nod+8KjlELf/3Ljvu9ZWDyLUoA= +k8s.io/apiserver v0.26.4/go.mod h1:yAY3O1vBM4/0OIGAGeWcdfzQvgdwJ188VirLcuSAVnw= +k8s.io/cli-runtime v0.26.4 h1:MgSU871KDzBDX7V9GtuqS6Ai9lhQCHgRzkurnXOWtZ0= +k8s.io/cli-runtime v0.26.4/go.mod h1:MjJ2DXMChw2zcG0/agzm17xwKpfVxOfuoCdfY9iOCOE= +k8s.io/client-go v0.26.4 h1:/7P/IbGBuT73A+G97trf44NTPSNqvuBREpOfdLbHvD4= +k8s.io/client-go v0.26.4/go.mod h1:6qOItWm3EwxJdl/8p5t7FWtWUOwyMdA8N9ekbW4idpI= +k8s.io/code-generator v0.26.4 h1:zgDD0qX13p/jtrAoYRRiYeQ5ibnriwmo2cMkMZAtJxc= +k8s.io/code-generator v0.26.4/go.mod h1:ryaiIKwfxEJEaywEzx3dhWOydpVctKYbqLajJf0O8dI= +k8s.io/component-base v0.26.4 h1:Bg2xzyXNKL3eAuiTEu3XE198d6z22ENgFgGQv2GGOUk= +k8s.io/component-base v0.26.4/go.mod h1:lTuWL1Xz/a4e80gmIC3YZG2JCO4xNwtKWHJWeJmsq20= +k8s.io/gengo v0.0.0-20220902162205-c0856e24416d h1:U9tB195lKdzwqicbJvyJeOXV7Klv+wNAWENRnXEGi08= +k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= -k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= -k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4= -k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= pault.ag/go/sniff v0.0.0-20200207005214-cf7e4d167732 h1:SAElp8THCfmBdM+4lmWX5gebiSSkEr7PAYDVF91qpfg= pault.ag/go/sniff v0.0.0-20200207005214-cf7e4d167732/go.mod h1:lpvCfhqEHNJSSpG5R5A2EgsVzG8RTt4RfPoQuRAcDmg= 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/controller-runtime v0.13.1 h1:tUsRCSJVM1QQOOeViGeX3GMT3dQF1eePPw6sEE3xSlg= -sigs.k8s.io/controller-runtime v0.13.1/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= +sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA= +sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= diff --git a/hack/verify-chart-lint.sh b/hack/verify-chart-lint.sh index 2d59dadce..9ece681e0 100755 --- a/hack/verify-chart-lint.sh +++ b/hack/verify-chart-lint.sh @@ -20,5 +20,5 @@ set -o pipefail KUBE_ROOT="$( cd "$(dirname "$0")../" >/dev/null 2>&1 ; pwd -P )" # TODO: This is a temporary workaround while we don't update Helm Chart test -curl https://raw.githubusercontent.com/helm/chart-testing/v3.7.0/etc/chart_schema.yaml -o /tmp/chart_schema.yaml +curl https://raw.githubusercontent.com/helm/chart-testing/v3.8.0/etc/chart_schema.yaml -o /tmp/chart_schema.yaml ct lint --charts ${KUBE_ROOT}/charts/ingress-nginx --validate-maintainers=false --chart-yaml-schema=/tmp/chart_schema.yaml diff --git a/images/README.md b/images/README.md index 13f6bfc3c..e7e5f71a6 100644 --- a/images/README.md +++ b/images/README.md @@ -13,10 +13,11 @@ Directory | Purpose ------------ | ------------- -custom-error-pages | Example of Custom error pages for the NGINX Ingress controller +custom-error-pages | Example of Custom error pages for the Ingress-Nginx Controller e2e | Image to run e2e tests fastcgi-helloserver | FastCGI application for e2e tests grpc-fortune-teller | grpc server application for the nginx-ingress grpc example -httpbin | A simple HTTP Request & Response Service for e2e tests +httpbun | A simple HTTP Request & Response Service for e2e tests +httpbin | [Removed] we are no longer maintaining the httpbin image due to project being unmaintained nginx | NGINX base image using [alpine linux](https://www.alpinelinux.org) cfssl | Image to run cfssl commands diff --git a/images/cfssl/Makefile b/images/cfssl/Makefile index b1909abe3..8d8e597a4 100644 --- a/images/cfssl/Makefile +++ b/images/cfssl/Makefile @@ -18,9 +18,13 @@ SHELL=/bin/bash -o pipefail -o errexit DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh -TAG ?=v$(shell date +%m%d%Y)-$(shell git rev-parse --short HEAD) +SHORT_SHA ?=$(shell git rev-parse --short HEAD) +TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) + REGISTRY ?= local + + IMAGE = $(REGISTRY)/e2e-test-cfssl # required to enable buildx diff --git a/images/cfssl/cloudbuild.yaml b/images/cfssl/cloudbuild.yaml index 5fb9e0c96..4976a3f67 100644 --- a/images/cfssl/cloudbuild.yaml +++ b/images/cfssl/cloudbuild.yaml @@ -6,7 +6,7 @@ steps: entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled - - TAG=$_GIT_TAG + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - REGISTRY=gcr.io/k8s-staging-ingress-nginx # default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx diff --git a/images/cfssl/rootfs/Dockerfile b/images/cfssl/rootfs/Dockerfile index f9370c210..a50c715ea 100644 --- a/images/cfssl/rootfs/Dockerfile +++ b/images/cfssl/rootfs/Dockerfile @@ -12,10 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.17.0 +FROM alpine:3.17.2 + RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories -RUN apk add --no-cache \ +RUN apk update \ + && apk upgrade && \ + apk add --no-cache \ bash \ cfssl@testing diff --git a/images/custom-error-pages/Makefile b/images/custom-error-pages/Makefile index 7564b813d..810736cca 100644 --- a/images/custom-error-pages/Makefile +++ b/images/custom-error-pages/Makefile @@ -20,7 +20,9 @@ SHELL=/bin/bash -o pipefail -o errexit DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh -TAG ?=v$(shell date +%m%d%Y)-$(shell git rev-parse --short HEAD) +SHORT_SHA ?=$(shell git rev-parse --short HEAD) +TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) + REGISTRY ?= local IMAGE = $(REGISTRY)/nginx-errors diff --git a/images/custom-error-pages/README.md b/images/custom-error-pages/README.md index 88983591f..cd6df3e0a 100644 --- a/images/custom-error-pages/README.md +++ b/images/custom-error-pages/README.md @@ -1,3 +1,3 @@ # custom-error-pages -Example of Custom error pages for the NGINX Ingress controller +Example of Custom error pages for the Ingress-Nginx Controller diff --git a/images/custom-error-pages/cloudbuild.yaml b/images/custom-error-pages/cloudbuild.yaml index 8c96d289c..e38d4bcdc 100644 --- a/images/custom-error-pages/cloudbuild.yaml +++ b/images/custom-error-pages/cloudbuild.yaml @@ -6,7 +6,7 @@ steps: entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled - - TAG=$_GIT_TAG + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - REGISTRY=gcr.io/k8s-staging-ingress-nginx # default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx diff --git a/images/custom-error-pages/rootfs/Dockerfile b/images/custom-error-pages/rootfs/Dockerfile index ef825dec1..b34bb6977 100755 --- a/images/custom-error-pages/rootfs/Dockerfile +++ b/images/custom-error-pages/rootfs/Dockerfile @@ -12,8 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.19.4-alpine3.17 as builder -RUN apk add git +FROM golang:1.20.1-alpine3.17 as builder + +RUN apk update \ + && apk upgrade && apk add git WORKDIR /go/src/k8s.io/ingress-nginx/images/custom-error-pages diff --git a/images/custom-error-pages/rootfs/go.mod b/images/custom-error-pages/rootfs/go.mod index b39db8b20..89e47a4b5 100644 --- a/images/custom-error-pages/rootfs/go.mod +++ b/images/custom-error-pages/rootfs/go.mod @@ -1,8 +1,8 @@ module k8s.io/ingress-nginx/custom-error-pages -go 1.19 +go 1.20 -require github.com/prometheus/client_golang v1.11.0 +require github.com/prometheus/client_golang v1.11.1 require ( github.com/beorn7/perks v1.0.1 // indirect @@ -12,6 +12,6 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.26.0 // indirect github.com/prometheus/procfs v0.6.0 // indirect - golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 // indirect + golang.org/x/sys v0.1.0 // indirect google.golang.org/protobuf v1.28.0 // indirect ) diff --git a/images/custom-error-pages/rootfs/go.sum b/images/custom-error-pages/rootfs/go.sum index 87cd96b26..a5f86cade 100644 --- a/images/custom-error-pages/rootfs/go.sum +++ b/images/custom-error-pages/rootfs/go.sum @@ -66,8 +66,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= @@ -113,8 +113,9 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w 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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/images/echo/Makefile b/images/echo/Makefile index 500704e81..a213df5d3 100644 --- a/images/echo/Makefile +++ b/images/echo/Makefile @@ -4,7 +4,7 @@ # 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 +# 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, @@ -18,7 +18,9 @@ SHELL=/bin/bash -o pipefail -o errexit DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh -TAG ?=v1.0.0 +SHORT_SHA ?=$(shell git rev-parse --short HEAD) +TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) + REGISTRY ?= local IMAGE = $(REGISTRY)/e2e-test-echo diff --git a/images/echo/cloudbuild.yaml b/images/echo/cloudbuild.yaml index 8349b5a7f..f07be825a 100644 --- a/images/echo/cloudbuild.yaml +++ b/images/echo/cloudbuild.yaml @@ -6,7 +6,7 @@ steps: entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled - - TAG=$_GIT_TAG + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - REGISTRY=gcr.io/k8s-staging-ingress-nginx # default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx diff --git a/images/echo/rootfs/Dockerfile b/images/echo/rootfs/Dockerfile index 4c9b6ab55..c4ab26561 100644 --- a/images/echo/rootfs/Dockerfile +++ b/images/echo/rootfs/Dockerfile @@ -2,7 +2,7 @@ ARG BASE_IMAGE FROM ${BASE_IMAGE} -RUN apk add -U perl curl make unzip +RUN apk update && apk upgrade && apk add -U --no-cache perl curl make unzip ARG LUAROCKS_VERSION ARG LUAROCKS_SHA diff --git a/images/ext-auth-example-authsvc/cloudbuild.yaml b/images/ext-auth-example-authsvc/cloudbuild.yaml index fbd5d7b63..c5bb5db6a 100644 --- a/images/ext-auth-example-authsvc/cloudbuild.yaml +++ b/images/ext-auth-example-authsvc/cloudbuild.yaml @@ -2,13 +2,13 @@ timeout: 1200s options: substitution_option: ALLOW_LOOSE # job builds a multi-arch docker image for amd64,arm,arm64 and s390x. - machineType: N1_HIGHCPU_8 + machineType: E2_HIGHCPU_8 steps: - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20211118-2f2d816b90 entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled - - TAG=$_GIT_TAG + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - REGISTRY=gcr.io/k8s-staging-ingress-nginx # default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx diff --git a/images/ext-auth-example-authsvc/rootfs/Dockerfile b/images/ext-auth-example-authsvc/rootfs/Dockerfile index d54df8ab9..c604651d4 100644 --- a/images/ext-auth-example-authsvc/rootfs/Dockerfile +++ b/images/ext-auth-example-authsvc/rootfs/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.19.4-alpine3.17 as builder +FROM golang:1.20.1-alpine3.17 as builder RUN mkdir /authsvc WORKDIR /authsvc COPY . ./ diff --git a/images/ext-auth-example-authsvc/rootfs/go.mod b/images/ext-auth-example-authsvc/rootfs/go.mod index 0be630b8b..cc5124072 100644 --- a/images/ext-auth-example-authsvc/rootfs/go.mod +++ b/images/ext-auth-example-authsvc/rootfs/go.mod @@ -1,6 +1,6 @@ module example.com/authsvc -go 1.19 +go 1.20 require k8s.io/apimachinery v0.23.1 diff --git a/images/ext-auth-example-authsvc/rootfs/go.sum b/images/ext-auth-example-authsvc/rootfs/go.sum index 2ca056fae..6e3fab295 100644 --- a/images/ext-auth-example-authsvc/rootfs/go.sum +++ b/images/ext-auth-example-authsvc/rootfs/go.sum @@ -105,7 +105,19 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +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-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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -129,7 +141,12 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/images/fastcgi-helloserver/Makefile b/images/fastcgi-helloserver/Makefile index c1b54703f..4d277a19d 100644 --- a/images/fastcgi-helloserver/Makefile +++ b/images/fastcgi-helloserver/Makefile @@ -20,7 +20,9 @@ SHELL=/bin/bash -o pipefail -o errexit DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh -TAG ?=v$(shell date +%m%d%Y)-$(shell git rev-parse --short HEAD) +SHORT_SHA ?=$(shell git rev-parse --short HEAD) +TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) + REGISTRY ?= local IMAGE = $(REGISTRY)/e2e-test-fastcgi-helloserver diff --git a/images/fastcgi-helloserver/cloudbuild.yaml b/images/fastcgi-helloserver/cloudbuild.yaml index cb4ac2e94..a4c9d5eff 100644 --- a/images/fastcgi-helloserver/cloudbuild.yaml +++ b/images/fastcgi-helloserver/cloudbuild.yaml @@ -6,7 +6,7 @@ steps: entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled - - TAG=$_GIT_TAG + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - REGISTRY=gcr.io/k8s-staging-ingress-nginx # default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx diff --git a/images/fastcgi-helloserver/rootfs/Dockerfile b/images/fastcgi-helloserver/rootfs/Dockerfile index 0213baf87..7d9220ddf 100755 --- a/images/fastcgi-helloserver/rootfs/Dockerfile +++ b/images/fastcgi-helloserver/rootfs/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang:1.19.4-alpine3.17 as builder +FROM golang:1.20.1-alpine3.17 as builder WORKDIR /go/src/k8s.io/ingress-nginx/images/fastcgi diff --git a/images/go-grpc-greeter-server/Makefile b/images/go-grpc-greeter-server/Makefile index 523b83bfb..e221ecfea 100644 --- a/images/go-grpc-greeter-server/Makefile +++ b/images/go-grpc-greeter-server/Makefile @@ -18,7 +18,9 @@ SHELL=/bin/bash -o pipefail -o errexit DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh -TAG ?=v$(shell date +%m%d%Y)-$(shell git rev-parse --short HEAD) +SHORT_SHA ?=$(shell git rev-parse --short HEAD) +TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) + REGISTRY ?= local IMAGE = $(REGISTRY)/go-grpc-greeter-server diff --git a/images/go-grpc-greeter-server/cloudbuild.yaml b/images/go-grpc-greeter-server/cloudbuild.yaml index f4d6cc6d4..6f32bcf50 100644 --- a/images/go-grpc-greeter-server/cloudbuild.yaml +++ b/images/go-grpc-greeter-server/cloudbuild.yaml @@ -2,13 +2,13 @@ timeout: 1200s options: substitution_option: ALLOW_LOOSE # job builds a multi-arch docker image for amd64,arm,arm64 and s390x. - machineType: N1_HIGHCPU_8 + machineType: E2_HIGHCPU_8 steps: - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20211118-2f2d816b90 entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled - - TAG=$_GIT_TAG + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - REGISTRY=gcr.io/k8s-staging-ingress-nginx # default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx diff --git a/images/go-grpc-greeter-server/rootfs/Dockerfile b/images/go-grpc-greeter-server/rootfs/Dockerfile index 547842512..67aed038e 100644 --- a/images/go-grpc-greeter-server/rootfs/Dockerfile +++ b/images/go-grpc-greeter-server/rootfs/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.19.4-alpine3.17 as build +FROM golang:1.20.1-alpine3.17 as build WORKDIR /go/src/greeter-server diff --git a/images/httpbin/Makefile b/images/httpbun/Makefile similarity index 92% rename from images/httpbin/Makefile rename to images/httpbun/Makefile index ac363dfa8..bcb8c7be2 100644 --- a/images/httpbin/Makefile +++ b/images/httpbun/Makefile @@ -18,10 +18,12 @@ SHELL=/bin/bash -o pipefail -o errexit DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh -TAG ?=v$(shell date +%m%d%Y)-$(shell git rev-parse --short HEAD) +SHORT_SHA ?=$(shell git rev-parse --short HEAD) +TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) + REGISTRY ?= local -IMAGE = $(REGISTRY)/e2e-test-httpbin +IMAGE = $(REGISTRY)/e2e-test-httpbun # required to enable buildx export DOCKER_CLI_EXPERIMENTAL=enabled diff --git a/images/httpbin/cloudbuild.yaml b/images/httpbun/cloudbuild.yaml similarity index 87% rename from images/httpbin/cloudbuild.yaml rename to images/httpbun/cloudbuild.yaml index 03f269b6e..9e3af5935 100644 --- a/images/httpbin/cloudbuild.yaml +++ b/images/httpbun/cloudbuild.yaml @@ -2,13 +2,13 @@ timeout: 1200s options: substitution_option: ALLOW_LOOSE # job builds a multi-arch docker image for amd64,arm,arm64 and s390x. - machineType: N1_HIGHCPU_8 + machineType: E2_HIGHCPU_8 steps: - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20211118-2f2d816b90 entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled - - TAG=$_GIT_TAG + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - REGISTRY=gcr.io/k8s-staging-ingress-nginx # default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx @@ -18,7 +18,7 @@ steps: - -c - | gcloud auth configure-docker \ - && cd images/httpbin && make push + && cd images/httpbun && make push substitutions: _GIT_TAG: "12345" _PULL_BASE_REF: "master" diff --git a/images/httpbin/rootfs/Dockerfile b/images/httpbun/rootfs/Dockerfile similarity index 61% rename from images/httpbin/rootfs/Dockerfile rename to images/httpbun/rootfs/Dockerfile index 1a9b55ba5..a1775d303 100644 --- a/images/httpbin/rootfs/Dockerfile +++ b/images/httpbun/rootfs/Dockerfile @@ -12,21 +12,23 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.17.0 +FROM golang:1.20 AS builder ENV LC_ALL=C.UTF-8 ENV LANG=C.UTF-8 +ENV HTTPBUN_COMMIT=a6b387c438b664322734250e426b6966966c2fe4 -RUN apk update \ - && apk add --no-cache \ - python3 python3-dev \ - musl-dev gcc g++ make \ - libffi libffi-dev libstdc++ \ - py3-gevent py3-gunicorn py3-wheel \ - py3-pip \ - && pip3 install httpbin \ - && apk del python3-dev musl-dev gcc g++ make libffi-dev +RUN git clone https://github.com/sharat87/httpbun.git +WORKDIR httpbun +RUN git checkout $HTTPBUN_COMMIT +RUN CGO_ENABLED=0 GOOS=linux go build \ + -installsuffix cgo \ + -trimpath \ + -o bin/httpbun . + +FROM scratch +COPY --from=builder /go/httpbun/bin/httpbun httpbun +ENV HTTPBUN_BIND=0.0.0.0:80 EXPOSE 80 - -CMD ["gunicorn", "-b", "0.0.0.0:80", "httpbin:app", "-k", "gevent"] +ENTRYPOINT ["/httpbun"] diff --git a/images/kube-webhook-certgen/Makefile b/images/kube-webhook-certgen/Makefile index f1d3edc5b..cd014c7c3 100644 --- a/images/kube-webhook-certgen/Makefile +++ b/images/kube-webhook-certgen/Makefile @@ -19,7 +19,9 @@ SHELL=/bin/bash -o pipefail -o errexit DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh -TAG ?=v$(shell date +%m%d%Y)-$(shell git rev-parse --short HEAD) +SHORT_SHA ?=$(shell git rev-parse --short HEAD) +TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) + REGISTRY ?= local IMAGE = $(REGISTRY)/kube-webhook-certgen diff --git a/images/kube-webhook-certgen/cloudbuild.yaml b/images/kube-webhook-certgen/cloudbuild.yaml index 127dee6eb..bf0bd3ce1 100644 --- a/images/kube-webhook-certgen/cloudbuild.yaml +++ b/images/kube-webhook-certgen/cloudbuild.yaml @@ -21,7 +21,7 @@ steps: entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled - - TAG=$_GIT_TAG + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - REGISTRY=gcr.io/k8s-staging-ingress-nginx # default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx diff --git a/images/kube-webhook-certgen/rootfs/Dockerfile b/images/kube-webhook-certgen/rootfs/Dockerfile index 32847fd39..40a2c31ac 100644 --- a/images/kube-webhook-certgen/rootfs/Dockerfile +++ b/images/kube-webhook-certgen/rootfs/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=$BUILDPLATFORM golang:1.19.4 as builder +FROM --platform=$BUILDPLATFORM golang:1.20.1 as builder ARG BUILDPLATFORM ARG TARGETARCH diff --git a/images/kube-webhook-certgen/rootfs/go.mod b/images/kube-webhook-certgen/rootfs/go.mod index b98adf58b..49f95828f 100644 --- a/images/kube-webhook-certgen/rootfs/go.mod +++ b/images/kube-webhook-certgen/rootfs/go.mod @@ -1,6 +1,6 @@ module github.com/jet/kube-webhook-certgen -go 1.19 +go 1.20 require ( github.com/onrik/logrus v0.9.0 @@ -29,11 +29,11 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/tidwall/gjson v1.14.0 // indirect - golang.org/x/net v0.1.0 // indirect + golang.org/x/net v0.7.0 // indirect golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect - golang.org/x/sys v0.1.0 // indirect - golang.org/x/term v0.1.0 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect google.golang.org/appengine v1.6.5 // indirect google.golang.org/protobuf v1.26.0 // indirect diff --git a/images/kube-webhook-certgen/rootfs/go.sum b/images/kube-webhook-certgen/rootfs/go.sum index 0270e3297..7817b7f29 100644 --- a/images/kube-webhook-certgen/rootfs/go.sum +++ b/images/kube-webhook-certgen/rootfs/go.sum @@ -89,7 +89,6 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn 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/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.16.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -484,8 +483,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -545,16 +544,14 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 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= @@ -562,8 +559,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -708,7 +705,6 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/images/kube-webhook-certgen/rootfs/pkg/k8s/k8s.go b/images/kube-webhook-certgen/rootfs/pkg/k8s/k8s.go index 0034235fb..6018b4253 100644 --- a/images/kube-webhook-certgen/rootfs/pkg/k8s/k8s.go +++ b/images/kube-webhook-certgen/rootfs/pkg/k8s/k8s.go @@ -105,7 +105,7 @@ func (k8s *k8s) patchAPIService(ctx context.Context, objectName string, ca []byt return nil } -// PatchWebhookConfigurations will patch validatingWebhook and mutatingWebhook clientConfig configurations with +// patchWebhookConfigurations will patch validatingWebhook and mutatingWebhook clientConfig configurations with // the provided ca data. If failurePolicy is provided, patch all webhooks with this value func (k8s *k8s) patchWebhookConfigurations( ctx context.Context, diff --git a/images/nginx/Makefile b/images/nginx/Makefile index 438d0cfe1..b54a7739b 100644 --- a/images/nginx/Makefile +++ b/images/nginx/Makefile @@ -21,7 +21,9 @@ DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh # 0.0.0 shouldn't clobber any released builds -TAG ?= 0.0 +SHORT_SHA ?=$(shell git rev-parse --short HEAD) +TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) + REGISTRY ?= gcr.io/k8s-staging-ingress-nginx IMAGE = $(REGISTRY)/nginx diff --git a/images/nginx/cloudbuild.yaml b/images/nginx/cloudbuild.yaml index fb9a51225..c581700dd 100644 --- a/images/nginx/cloudbuild.yaml +++ b/images/nginx/cloudbuild.yaml @@ -2,14 +2,14 @@ timeout: 10800s options: substitution_option: ALLOW_LOOSE # job builds a multi-arch docker image for amd64,arm,arm64 and s390x. - machineType: N1_HIGHCPU_32 + machineType: E2_HIGHCPU_32 steps: - name: 'gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20211118-2f2d816b90' entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - - TAG=$_PULL_BASE_SHA - REGISTRY=gcr.io/k8s-staging-ingress-nginx - HOME=/root args: diff --git a/images/nginx/rootfs/Dockerfile b/images/nginx/rootfs/Dockerfile index a9b01ff82..a968eb1b3 100644 --- a/images/nginx/rootfs/Dockerfile +++ b/images/nginx/rootfs/Dockerfile @@ -11,17 +11,17 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.17.0 as builder +FROM alpine:3.17.2 as builder COPY . / RUN apk update \ && apk upgrade \ - && apk add -U bash \ + && apk add -U bash --no-cache \ && /build.sh # Use a multi-stage build -FROM alpine:3.17.0 +FROM alpine:3.17.2 ENV PATH=$PATH:/usr/local/luajit/bin:/usr/local/nginx/sbin:/usr/local/nginx/bin @@ -49,7 +49,6 @@ RUN apk update \ libmaxminddb \ yaml-cpp \ dumb-init \ - nano \ tzdata \ && ln -s /usr/local/nginx/sbin/nginx /sbin/nginx \ && adduser -S -D -H -u 101 -h /usr/local/nginx \ diff --git a/images/nginx/rootfs/build.sh b/images/nginx/rootfs/build.sh index 8023575c0..44c7b20f8 100755 --- a/images/nginx/rootfs/build.sh +++ b/images/nginx/rootfs/build.sh @@ -77,8 +77,6 @@ export LUA_UPSTREAM_VERSION=8aa93ead98ba2060d4efd594ae33a35d153589bf # Check for recent changes: https://github.com/openresty/lua-cjson/compare/2.1.0.10...openresty:master export LUA_CJSON_VERSION=2.1.0.10 -export NGINX_INFLUXDB_VERSION=5b09391cb7b9a889687c0aa67964c06a2d933e8b - # Check for recent changes: https://github.com/leev/ngx_http_geoip2_module/compare/3.3...master export GEOIP2_VERSION=a26c6beed77e81553686852dceb6c7fdacc5970d @@ -270,9 +268,6 @@ fi get_src 586f92166018cc27080d34e17c59d68219b85af745edf3cc9fe41403fc9b4ac6 \ "https://github.com/DataDog/dd-opentracing-cpp/archive/v$DATADOG_CPP_VERSION.tar.gz" -get_src 1af5a5632dc8b00ae103d51b7bf225de3a7f0df82f5c6a401996c080106e600e \ - "https://github.com/influxdata/nginx-influxdb-module/archive/$NGINX_INFLUXDB_VERSION.tar.gz" - get_src 4c1933434572226942c65b2f2b26c8a536ab76aa771a3c7f6c2629faa764976b \ "https://github.com/leev/ngx_http_geoip2_module/archive/$GEOIP2_VERSION.tar.gz" @@ -640,7 +635,6 @@ WITH_MODULES=" \ --add-module=$BUILD_PATH/lua-upstream-nginx-module-$LUA_UPSTREAM_VERSION \ --add-module=$BUILD_PATH/nginx_ajp_module-${NGINX_AJP_VERSION} \ --add-dynamic-module=$BUILD_PATH/nginx-http-auth-digest-$NGINX_DIGEST_AUTH \ - --add-dynamic-module=$BUILD_PATH/nginx-influxdb-module-$NGINX_INFLUXDB_VERSION \ --add-dynamic-module=$BUILD_PATH/nginx-opentracing-$NGINX_OPENTRACING_VERSION/opentracing \ --add-dynamic-module=$BUILD_PATH/ModSecurity-nginx-$MODSECURITY_VERSION \ --add-dynamic-module=$BUILD_PATH/ngx_http_geoip2_module-${GEOIP2_VERSION} \ diff --git a/images/opentelemetry/Makefile b/images/opentelemetry/Makefile index 20fb7ec63..07a66beed 100644 --- a/images/opentelemetry/Makefile +++ b/images/opentelemetry/Makefile @@ -21,7 +21,9 @@ DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh # 0.0.0 shouldn't clobber any released builds -TAG ?=v$(shell date +%m%d%Y)-$(shell git rev-parse --short HEAD) +SHORT_SHA ?=$(shell git rev-parse --short HEAD) +TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) + REGISTRY ?= gcr.io/k8s-staging-ingress-nginx IMAGE = $(REGISTRY)/opentelemetry diff --git a/images/opentelemetry/cloudbuild.yaml b/images/opentelemetry/cloudbuild.yaml index e2aa5a2b2..9556ccba9 100644 --- a/images/opentelemetry/cloudbuild.yaml +++ b/images/opentelemetry/cloudbuild.yaml @@ -2,13 +2,13 @@ timeout: 10800s options: substitution_option: ALLOW_LOOSE # job builds a multi-arch docker image for amd64,arm,arm64 and s390x. - machineType: N1_HIGHCPU_32 + machineType: E2_HIGHCPU_32 steps: - name: gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20211118-2f2d816b90 entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled - - TAG=$_GIT_TAG + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - REGISTRY=gcr.io/k8s-staging-ingress-nginx # default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx diff --git a/images/opentelemetry/rootfs/Dockerfile b/images/opentelemetry/rootfs/Dockerfile index aa4e219af..33f5bcb36 100644 --- a/images/opentelemetry/rootfs/Dockerfile +++ b/images/opentelemetry/rootfs/Dockerfile @@ -13,7 +13,7 @@ # limitations under the License. -FROM alpine:3.17.0 as base +FROM alpine:3.17.2 as base RUN mkdir -p /opt/third_party/install COPY . /opt/third_party/ @@ -39,7 +39,7 @@ COPY --from=grpc /opt/third_party/install/ /usr COPY --from=otel-cpp /opt/third_party/install/ /usr RUN bash /opt/third_party/build.sh -n -FROM alpine:3.17.0 as final +FROM alpine:3.17.2 as final COPY --from=base /opt/third_party/init_module.sh /usr/local/bin/init_module.sh COPY --from=nginx /etc/nginx/modules /etc/nginx/modules COPY --from=nginx /opt/third_party/install/lib /etc/nginx/modules diff --git a/images/test-runner/Makefile b/images/test-runner/Makefile index 4d71b8ad5..562625cff 100644 --- a/images/test-runner/Makefile +++ b/images/test-runner/Makefile @@ -18,7 +18,9 @@ SHELL=/bin/bash -o pipefail -o errexit DIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) INIT_BUILDX=$(DIR)/../../hack/init-buildx.sh -TAG ?=v$(shell date +%m%d%Y)-$(shell git rev-parse --short HEAD) +SHORT_SHA ?=$(shell git rev-parse --short HEAD) +TAG ?=v$(shell date +%Y%m%d)-$(SHORT_SHA) + REGISTRY ?= local IMAGE = $(REGISTRY)/e2e-test-runner @@ -30,27 +32,52 @@ export DOCKER_CLI_EXPERIMENTAL=enabled # build with buildx PLATFORMS?=linux/amd64,linux/arm64 -OUTPUT= +OUTPUT?= PROGRESS=plain -build: ensure-buildx - docker buildx build \ - --platform=${PLATFORMS} $(OUTPUT) \ - --progress=$(PROGRESS) \ +image: + echo "Building docker image ($(ARCH))..." + docker build \ + ${PLATFORM_FLAG} ${PLATFORM} \ + --no-cache \ --pull \ - --build-arg BASE_IMAGE=$(NGINX_BASE_IMAGE) \ - --build-arg GOLANG_VERSION=1.19.4 \ + --push \ + --build-arg BASE_IMAGE=${NGINX_BASE_IMAGE} \ + --build-arg GOLANG_VERSION=1.20.1 \ --build-arg ETCD_VERSION=3.4.3-0 \ - --build-arg K8S_RELEASE=v1.24.2 \ + --build-arg K8S_RELEASE=v1.26.0 \ --build-arg RESTY_CLI_VERSION=0.27 \ --build-arg RESTY_CLI_SHA=e5f4f3128af49ba5c4d039d0554e5ae91bbe05866f60eccfa96d3653274bff90 \ --build-arg LUAROCKS_VERSION=3.8.0 \ --build-arg LUAROCKS_SHA=ab6612ca9ab87c6984871d2712d05525775e8b50172701a0a1cabddf76de2be7 \ - --build-arg CHART_TESTING_VERSION=3.7.0 \ + --build-arg CHART_TESTING_VERSION=3.8.0 \ --build-arg YAML_LINT_VERSION=1.27.1 \ --build-arg YAMALE_VERSION=4.0.4 \ - --build-arg HELM_VERSION=v3.9.0 \ - -t $(IMAGE):$(TAG) rootfs + --build-arg HELM_VERSION=3.11.2 \ + --build-arg GINKGO_VERSION=2.9.0 \ + --build-arg GOLINT_VERSION=latest \ + -t ${IMAGE}:${TAG} rootfs + +build: ensure-buildx + docker buildx build \ + --platform=${PLATFORMS} ${OUTPUT} \ + --progress=${PROGRESS} \ + --pull \ + --build-arg BASE_IMAGE=${NGINX_BASE_IMAGE} \ + --build-arg GOLANG_VERSION=1.20.1 \ + --build-arg ETCD_VERSION=3.4.3-0 \ + --build-arg K8S_RELEASE=v1.26.0 \ + --build-arg RESTY_CLI_VERSION=0.27 \ + --build-arg RESTY_CLI_SHA=e5f4f3128af49ba5c4d039d0554e5ae91bbe05866f60eccfa96d3653274bff90 \ + --build-arg LUAROCKS_VERSION=3.8.0 \ + --build-arg LUAROCKS_SHA=ab6612ca9ab87c6984871d2712d05525775e8b50172701a0a1cabddf76de2be7 \ + --build-arg CHART_TESTING_VERSION=3.8.0 \ + --build-arg YAML_LINT_VERSION=1.27.1 \ + --build-arg YAMALE_VERSION=4.0.4 \ + --build-arg HELM_VERSION=3.11.2 \ + --build-arg GINKGO_VERSION=2.9.0 \ + --build-arg GOLINT_VERSION=latest \ + -t ${IMAGE}:${TAG} rootfs # push the cross built image push: OUTPUT=--push diff --git a/images/test-runner/cloudbuild.yaml b/images/test-runner/cloudbuild.yaml index b1f32d6a2..761ea7f28 100644 --- a/images/test-runner/cloudbuild.yaml +++ b/images/test-runner/cloudbuild.yaml @@ -6,7 +6,7 @@ steps: entrypoint: bash env: - DOCKER_CLI_EXPERIMENTAL=enabled - - TAG=$_GIT_TAG + - SHORT_SHA=$SHORT_SHA - BASE_REF=$_PULL_BASE_REF - REGISTRY=gcr.io/k8s-staging-ingress-nginx # default cloudbuild has HOME=/builder/home and docker buildx is in /root/.docker/cli-plugins/docker-buildx @@ -20,3 +20,4 @@ steps: substitutions: _GIT_TAG: "12345" _PULL_BASE_REF: "master" + _PULL_BASE_SHA: '12345' \ No newline at end of file diff --git a/images/test-runner/rootfs/Dockerfile b/images/test-runner/rootfs/Dockerfile index 1e8bc3643..8574f8752 100644 --- a/images/test-runner/rootfs/Dockerfile +++ b/images/test-runner/rootfs/Dockerfile @@ -11,7 +11,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - ARG BASE_IMAGE ARG GOLANG_VERSION ARG ETCD_VERSION @@ -21,6 +20,20 @@ FROM registry.k8s.io/etcd:${ETCD_VERSION} as etcd FROM ${BASE_IMAGE} +ARG RESTY_CLI_VERSION +ARG RESTY_CLI_SHA +ARG LUAROCKS_VERSION +ARG LUAROCKS_SHA +ARG TARGETARCH +ARG K8S_RELEASE +ARG CHART_TESTING_VERSION +ARG HELM_VERSION +ARG YAMALE_VERSION +ARG YAML_LINT_VERSION +ARG GINKGO_VERSION +ARG GOLINT_VERSION + + RUN set -eux; \ if [ -e /etc/nsswitch.conf ]; then \ grep '^hosts: files dns' /etc/nsswitch.conf; \ @@ -28,13 +41,16 @@ RUN set -eux; \ echo 'hosts: files dns' > /etc/nsswitch.conf; \ fi - COPY --from=GO /usr/local/go /usr/local/go +ENV GOPATH /go +ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH +RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" + COPY --from=etcd /usr/local/bin/etcd /usr/local/bin/etcd -RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories +RUN echo "@testing https://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories -RUN apk add --no-cache \ +RUN apk update && apk upgrade && apk add --no-cache \ bash \ ca-certificates \ wget \ @@ -48,19 +64,15 @@ RUN apk add --no-cache \ py-pip \ unzip \ openssl \ - cfssl@testing + cfssl@testing \ + curl \ + tzdata \ + libc6-compat -ENV GOPATH /go -ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH +RUN go install -v github.com/onsi/ginkgo/v2/ginkgo@v${GINKGO_VERSION} \ + && go install golang.org/x/lint/golint@${GOLINT_VERSION} -RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" - -RUN go install github.com/onsi/ginkgo/v2/ginkgo@v2.6.1 && go install golang.org/x/lint/golint@latest - -ARG RESTY_CLI_VERSION -ARG RESTY_CLI_SHA - -RUN wget -O /tmp/resty_cli.tgz \ +RUN wget -qO /tmp/resty_cli.tgz \ https://github.com/openresty/resty-cli/archive/v${RESTY_CLI_VERSION}.tar.gz \ && echo "${RESTY_CLI_SHA} */tmp/resty_cli.tgz" | sha256sum -c - \ && tar -C /tmp -xzf /tmp/resty_cli.tgz \ @@ -68,10 +80,7 @@ RUN wget -O /tmp/resty_cli.tgz \ && resty -V \ && rm -rf /tmp/* -ARG LUAROCKS_VERSION -ARG LUAROCKS_SHA - -RUN wget -O /tmp/luarocks.tgz \ +RUN wget -qO /tmp/luarocks.tgz \ https://github.com/luarocks/luarocks/archive/v${LUAROCKS_VERSION}.tar.gz \ && echo "${LUAROCKS_SHA} */tmp/luarocks.tgz" | sha256sum -c - \ && tar -C /tmp -xzf /tmp/luarocks.tgz \ @@ -82,48 +91,39 @@ RUN wget -O /tmp/luarocks.tgz \ RUN luarocks install busted \ && luarocks install luacheck -ARG TARGETARCH - -ARG K8S_RELEASE - -RUN wget -O /usr/local/bin/kubectl \ - https://storage.googleapis.com/kubernetes-release/release/${K8S_RELEASE}/bin/linux/${TARGETARCH}/kubectl \ +RUN wget -qO /usr/local/bin/kubectl \ + https://dl.k8s.io/release/${K8S_RELEASE}/bin/linux/${TARGETARCH}/kubectl \ && chmod +x /usr/local/bin/kubectl -RUN wget -O /usr/local/bin/kube-apiserver \ - https://storage.googleapis.com/kubernetes-release/release/${K8S_RELEASE}/bin/linux/${TARGETARCH}/kube-apiserver \ +RUN wget -qO /usr/local/bin/kube-apiserver \ + https://dl.k8s.io/release/${K8S_RELEASE}/bin/linux/${TARGETARCH}/kube-apiserver \ && chmod +x /usr/local/bin/kube-apiserver -ARG CHART_TESTING_VERSION - -RUN wget -O /tmp/ct-${CHART_TESTING_VERSION}-linux-amd64.tar.gz \ - https://github.com/helm/chart-testing/releases/download/v${CHART_TESTING_VERSION}/chart-testing_${CHART_TESTING_VERSION}_linux_amd64.tar.gz \ +RUN wget -qO /tmp/ct-${CHART_TESTING_VERSION}-linux-${TARGETARCH}.tar.gz \ + https://github.com/helm/chart-testing/releases/download/v${CHART_TESTING_VERSION}/chart-testing_${CHART_TESTING_VERSION}_linux_${TARGETARCH}.tar.gz \ && mkdir -p /tmp/ct-download \ - && tar xzvf /tmp/ct-${CHART_TESTING_VERSION}-linux-amd64.tar.gz -C /tmp/ct-download \ - && rm /tmp/ct-${CHART_TESTING_VERSION}-linux-amd64.tar.gz \ + && tar xzvf /tmp/ct-${CHART_TESTING_VERSION}-linux-${TARGETARCH}.tar.gz -C /tmp/ct-download \ + && rm /tmp/ct-${CHART_TESTING_VERSION}-linux-${TARGETARCH}.tar.gz \ && cp /tmp/ct-download/ct /usr/local/bin \ && mkdir -p /etc/ct \ && cp -R /tmp/ct-download/etc/* /etc/ct \ && rm -rf /tmp/* -RUN wget -O /usr/local/bin/lj-releng \ +RUN wget -qO /usr/local/bin/lj-releng \ https://raw.githubusercontent.com/openresty/openresty-devel-utils/master/lj-releng \ && chmod +x /usr/local/bin/lj-releng -ARG HELM_VERSION -RUN wget -O /tmp/helm.tgz \ - https://get.helm.sh/helm-${HELM_VERSION}-linux-${TARGETARCH}.tar.gz \ +RUN wget -qO /tmp/helm.tgz \ + https://get.helm.sh/helm-v${HELM_VERSION}-linux-${TARGETARCH}.tar.gz \ && tar -C /tmp -xzf /tmp/helm.tgz \ && cp /tmp/linux*/helm /usr/local/bin \ && rm -rf /tmp/* # Install a YAML Linter -ARG YAML_LINT_VERSION RUN pip install "yamllint==$YAML_LINT_VERSION" # Install Yamale YAML schema validator -ARG YAMALE_VERSION RUN pip install "yamale==$YAMALE_VERSION" WORKDIR $GOPATH diff --git a/ingress-nginx.yaml b/ingress-nginx.yaml new file mode 100644 index 000000000..be66255e0 --- /dev/null +++ b/ingress-nginx.yaml @@ -0,0 +1,68 @@ +CURRENT_VERSION: "v1.5.1" +GOLANG_VERSION: "1.19.2" +GIT_TAG: "controller-v1.5.1" +NGINX_BASE_IMAGE: "registry.k8s.io/ingress-nginx/nginx:0b5e0685112e4537ee20a0bdbba451e9f6158aa3@sha256:3f5e28bb248d5170e77b77fc2a1a385724aeff41a0b34b5afad7dd9cf93de000" +NGINX_VERSION: "1.21.6" +VERSION_TABLE: + - "v1.5.1": + - Alpine: "3.16.2" + - Kubernetes: ["1.25","1.24","1.23"] + - NGINX: "1.21.6" + - CONTROLLER_IMAGE: "registry.k8s.io/ingress-nginx/controller:v1.5.1@sha256:4ba73c697770664c1e00e9f968de14e08f606ff961c76e5d7033a4a9c593c629" + - CHROOT_CONTROLLER_IMAGE: "registry.k8s.io/ingress-nginx/controller-chroot:v1.5.1@sha256:c1c091b88a6c936a83bd7b098662760a87868d12452529bad0d178fb36147345" + - "v1.4.0": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.3.1": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.3.0": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.2.1": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.1.3": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.1.2": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.1.1": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.1.0": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.0.5": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.0.4": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.0.3": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.0.2": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.0.1": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" + - "v1.0.0": + - Alpine: "3.16.2" + - Kubernetes: [ "1.24","1.23", "1.22", "1.21", "1.20" ] + - NGINX: "1.19.10" diff --git a/internal/ingress/annotations/annotations.go b/internal/ingress/annotations/annotations.go index 14415a4f7..5bb2bf5e6 100644 --- a/internal/ingress/annotations/annotations.go +++ b/internal/ingress/annotations/annotations.go @@ -20,6 +20,7 @@ import ( "github.com/imdario/mergo" "k8s.io/ingress-nginx/internal/ingress/annotations/canary" "k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity" + "k8s.io/ingress-nginx/internal/ingress/annotations/opentelemetry" "k8s.io/ingress-nginx/internal/ingress/annotations/proxyssl" "k8s.io/ingress-nginx/internal/ingress/annotations/sslcipher" "k8s.io/ingress-nginx/internal/ingress/annotations/streamsnippet" @@ -43,7 +44,6 @@ import ( "k8s.io/ingress-nginx/internal/ingress/annotations/fastcgi" "k8s.io/ingress-nginx/internal/ingress/annotations/globalratelimit" "k8s.io/ingress-nginx/internal/ingress/annotations/http2pushpreload" - "k8s.io/ingress-nginx/internal/ingress/annotations/influxdb" "k8s.io/ingress-nginx/internal/ingress/annotations/ipdenylist" "k8s.io/ingress-nginx/internal/ingress/annotations/ipwhitelist" "k8s.io/ingress-nginx/internal/ingress/annotations/loadbalancing" @@ -57,7 +57,6 @@ import ( "k8s.io/ingress-nginx/internal/ingress/annotations/redirect" "k8s.io/ingress-nginx/internal/ingress/annotations/rewrite" "k8s.io/ingress-nginx/internal/ingress/annotations/satisfy" - "k8s.io/ingress-nginx/internal/ingress/annotations/secureupstream" "k8s.io/ingress-nginx/internal/ingress/annotations/serversnippet" "k8s.io/ingress-nginx/internal/ingress/annotations/serviceupstream" "k8s.io/ingress-nginx/internal/ingress/annotations/sessionaffinity" @@ -94,6 +93,7 @@ type Ingress struct { EnableGlobalAuth bool HTTP2PushPreload bool Opentracing opentracing.Config + Opentelemetry opentelemetry.Config Proxy proxy.Config ProxySSL proxyssl.Config RateLimit ratelimit.Config @@ -101,7 +101,6 @@ type Ingress struct { Redirect redirect.Config Rewrite rewrite.Config Satisfy string - SecureUpstream secureupstream.Config ServerSnippet string ServiceUpstream bool SessionAffinity sessionaffinity.Config @@ -115,7 +114,6 @@ type Ingress struct { XForwardedPrefix string SSLCipher sslcipher.Config Logs log.Config - InfluxDB influxdb.Config ModSecurity modsecurity.Config Mirror mirror.Config StreamSnippet string @@ -145,6 +143,7 @@ func NewAnnotationExtractor(cfg resolver.Resolver) Extractor { "EnableGlobalAuth": authreqglobal.NewParser(cfg), "HTTP2PushPreload": http2pushpreload.NewParser(cfg), "Opentracing": opentracing.NewParser(cfg), + "Opentelemetry": opentelemetry.NewParser(cfg), "Proxy": proxy.NewParser(cfg), "ProxySSL": proxyssl.NewParser(cfg), "RateLimit": ratelimit.NewParser(cfg), @@ -152,7 +151,6 @@ func NewAnnotationExtractor(cfg resolver.Resolver) Extractor { "Redirect": redirect.NewParser(cfg), "Rewrite": rewrite.NewParser(cfg), "Satisfy": satisfy.NewParser(cfg), - "SecureUpstream": secureupstream.NewParser(cfg), "ServerSnippet": serversnippet.NewParser(cfg), "ServiceUpstream": serviceupstream.NewParser(cfg), "SessionAffinity": sessionaffinity.NewParser(cfg), @@ -166,7 +164,6 @@ func NewAnnotationExtractor(cfg resolver.Resolver) Extractor { "XForwardedPrefix": xforwardedprefix.NewParser(cfg), "SSLCipher": sslcipher.NewParser(cfg), "Logs": log.NewParser(cfg), - "InfluxDB": influxdb.NewParser(cfg), "BackendProtocol": backendprotocol.NewParser(cfg), "ModSecurity": modsecurity.NewParser(cfg), "Mirror": mirror.NewParser(cfg), diff --git a/internal/ingress/annotations/fastcgi/main.go b/internal/ingress/annotations/fastcgi/main.go index b32b85997..84bac4109 100644 --- a/internal/ingress/annotations/fastcgi/main.go +++ b/internal/ingress/annotations/fastcgi/main.go @@ -88,11 +88,11 @@ func (a fastcgi) Parse(ing *networking.Ingress) (interface{}, error) { } } - if cmns == "" { - cmns = ing.Namespace + if cmns != "" && cmns != ing.Namespace { + return fcgiConfig, fmt.Errorf("different namespace is not supported on fast_cgi param configmap") } - cm = fmt.Sprintf("%v/%v", cmns, cmn) + cm = fmt.Sprintf("%v/%v", ing.Namespace, cmn) cmap, err := a.r.GetConfigMap(cm) if err != nil { return fcgiConfig, ing_errors.LocationDenied{ diff --git a/internal/ingress/annotations/fastcgi/main_test.go b/internal/ingress/annotations/fastcgi/main_test.go index 26d85e7ce..35c5bbc12 100644 --- a/internal/ingress/annotations/fastcgi/main_test.go +++ b/internal/ingress/annotations/fastcgi/main_test.go @@ -17,13 +17,14 @@ limitations under the License. package fastcgi import ( + "fmt" "testing" api "k8s.io/api/core/v1" networking "k8s.io/api/networking/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" - "k8s.io/ingress-nginx/internal/ingress/errors" "k8s.io/ingress-nginx/internal/ingress/resolver" ) @@ -51,14 +52,19 @@ type mockConfigMap struct { } func (m mockConfigMap) GetConfigMap(name string) (*api.ConfigMap, error) { - if name != "default/demo-configmap" { - return nil, errors.Errorf("there is no configmap with name %v", name) + if name != "default/demo-configmap" && name != "otherns/demo-configmap" { + return nil, fmt.Errorf("there is no configmap with name %v", name) + } + + cmns, cmn, err := cache.SplitMetaNamespaceKey(name) + if err != nil { + return nil, fmt.Errorf("invalid configmap name") } return &api.ConfigMap{ ObjectMeta: meta_v1.ObjectMeta{ - Namespace: api.NamespaceDefault, - Name: "demo-secret", + Namespace: cmns, + Name: cmn, }, Data: map[string]string{"REDIRECT_STATUS": "200", "SERVER_NAME": "$server_name"}, }, nil @@ -210,6 +216,20 @@ func TestParseFastCGIParamsConfigMapAnnotationWithNS(t *testing.T) { } } +func TestParseFastCGIParamsConfigMapAnnotationWithDifferentNS(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + data[parser.GetAnnotationWithPrefix("fastcgi-params-configmap")] = "otherns/demo-configmap" + ing.SetAnnotations(data) + + _, err := NewParser(&mockConfigMap{}).Parse(ing) + if err == nil { + t.Errorf("Different namespace configmap should return an error") + } + +} + func TestConfigEquality(t *testing.T) { var nilConfig *Config diff --git a/internal/ingress/annotations/influxdb/main.go b/internal/ingress/annotations/influxdb/main.go deleted file mode 100644 index 1aee91f33..000000000 --- a/internal/ingress/annotations/influxdb/main.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package influxdb - -import ( - networking "k8s.io/api/networking/v1" - - "k8s.io/ingress-nginx/internal/ingress/annotations/parser" - "k8s.io/ingress-nginx/internal/ingress/resolver" -) - -type influxdb struct { - r resolver.Resolver -} - -// Config contains the IfluxDB configuration to be used in the Ingress -type Config struct { - InfluxDBEnabled bool `json:"influxDBEnabled"` - InfluxDBMeasurement string `json:"influxDBMeasurement"` - InfluxDBPort string `json:"influxDBPort"` - InfluxDBHost string `json:"influxDBHost"` - InfluxDBServerName string `json:"influxDBServerName"` -} - -// NewParser creates a new InfluxDB annotation parser -func NewParser(r resolver.Resolver) parser.IngressAnnotation { - return influxdb{r} -} - -// Parse parses the annotations to look for InfluxDB configurations -func (c influxdb) Parse(ing *networking.Ingress) (interface{}, error) { - var err error - config := &Config{} - - config.InfluxDBEnabled, err = parser.GetBoolAnnotation("enable-influxdb", ing) - if err != nil { - config.InfluxDBEnabled = false - } - - config.InfluxDBMeasurement, err = parser.GetStringAnnotation("influxdb-measurement", ing) - if err != nil { - config.InfluxDBMeasurement = "default" - } - - config.InfluxDBPort, err = parser.GetStringAnnotation("influxdb-port", ing) - if err != nil { - // This is not the default 8086 port but the port usually used to expose - // influxdb in UDP, the module uses UDP to talk to influx via the line protocol. - config.InfluxDBPort = "8089" - } - - config.InfluxDBHost, err = parser.GetStringAnnotation("influxdb-host", ing) - if err != nil { - config.InfluxDBHost = "127.0.0.1" - } - - config.InfluxDBServerName, err = parser.GetStringAnnotation("influxdb-server-name", ing) - if err != nil { - config.InfluxDBServerName = "nginx-ingress" - } - - return config, nil -} - -// Equal tests for equality between two Config types -func (e1 *Config) Equal(e2 *Config) bool { - if e1 == e2 { - return true - } - if e1 == nil || e2 == nil { - return false - } - if e1.InfluxDBEnabled != e2.InfluxDBEnabled { - return false - } - if e1.InfluxDBPort != e2.InfluxDBPort { - return false - } - if e1.InfluxDBHost != e2.InfluxDBHost { - return false - } - if e1.InfluxDBServerName != e2.InfluxDBServerName { - return false - } - - return true -} diff --git a/internal/ingress/annotations/influxdb/main_test.go b/internal/ingress/annotations/influxdb/main_test.go deleted file mode 100644 index 13d681509..000000000 --- a/internal/ingress/annotations/influxdb/main_test.go +++ /dev/null @@ -1,138 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package influxdb - -import ( - "testing" - - api "k8s.io/api/core/v1" - 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" -) - -func buildIngress() *networking.Ingress { - defaultBackend := networking.IngressBackend{ - Service: &networking.IngressServiceBackend{ - Name: "default-backend", - Port: networking.ServiceBackendPort{ - Number: 80, - }, - }, - } - - return &networking.Ingress{ - ObjectMeta: meta_v1.ObjectMeta{ - Name: "foo", - Namespace: api.NamespaceDefault, - }, - Spec: networking.IngressSpec{ - DefaultBackend: &networking.IngressBackend{ - Service: &networking.IngressServiceBackend{ - Name: "default-backend", - Port: networking.ServiceBackendPort{ - Number: 80, - }, - }, - }, - Rules: []networking.IngressRule{ - { - Host: "foo.bar.com", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{ - { - Path: "/foo", - Backend: defaultBackend, - }, - }, - }, - }, - }, - }, - }, - } -} - -func TestIngressInvalidInfluxDB(t *testing.T) { - ing := buildIngress() - - influx, _ := NewParser(&resolver.Mock{}).Parse(ing) - nginxInflux, ok := influx.(*Config) - if !ok { - t.Errorf("expected a Config type") - } - - if nginxInflux.InfluxDBEnabled == true { - t.Errorf("expected influxdb enabled but returned %v", nginxInflux.InfluxDBEnabled) - } - - if nginxInflux.InfluxDBMeasurement != "default" { - t.Errorf("expected measurement name not found. Found %v", nginxInflux.InfluxDBMeasurement) - } - - if nginxInflux.InfluxDBPort != "8089" { - t.Errorf("expected port not found. Found %v", nginxInflux.InfluxDBPort) - } - - if nginxInflux.InfluxDBHost != "127.0.0.1" { - t.Errorf("expected host not found. Found %v", nginxInflux.InfluxDBHost) - } - - if nginxInflux.InfluxDBServerName != "nginx-ingress" { - t.Errorf("expected server name not found. Found %v", nginxInflux.InfluxDBServerName) - } -} - -func TestIngressInfluxDB(t *testing.T) { - ing := buildIngress() - - data := map[string]string{} - data[parser.GetAnnotationWithPrefix("enable-influxdb")] = "true" - data[parser.GetAnnotationWithPrefix("influxdb-measurement")] = "nginxmeasures" - data[parser.GetAnnotationWithPrefix("influxdb-port")] = "9091" - data[parser.GetAnnotationWithPrefix("influxdb-host")] = "10.99.0.13" - data[parser.GetAnnotationWithPrefix("influxdb-server-name")] = "nginx-test-1" - ing.SetAnnotations(data) - - influx, _ := NewParser(&resolver.Mock{}).Parse(ing) - nginxInflux, ok := influx.(*Config) - if !ok { - t.Errorf("expected a Config type") - } - - if !nginxInflux.InfluxDBEnabled { - t.Errorf("expected influxdb enabled but returned %v", nginxInflux.InfluxDBEnabled) - } - - if nginxInflux.InfluxDBMeasurement != "nginxmeasures" { - t.Errorf("expected measurement name not found. Found %v", nginxInflux.InfluxDBMeasurement) - } - - if nginxInflux.InfluxDBPort != "9091" { - t.Errorf("expected port not found. Found %v", nginxInflux.InfluxDBPort) - } - - if nginxInflux.InfluxDBHost != "10.99.0.13" { - t.Errorf("expected host not found. Found %v", nginxInflux.InfluxDBHost) - } - - if nginxInflux.InfluxDBServerName != "nginx-test-1" { - t.Errorf("expected server name not found. Found %v", nginxInflux.InfluxDBServerName) - } -} diff --git a/internal/ingress/annotations/opentelemetry/main.go b/internal/ingress/annotations/opentelemetry/main.go new file mode 100644 index 000000000..7dd292322 --- /dev/null +++ b/internal/ingress/annotations/opentelemetry/main.go @@ -0,0 +1,101 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package opentelemetry + +import ( + networking "k8s.io/api/networking/v1" + + "k8s.io/ingress-nginx/internal/ingress/annotations/parser" + "k8s.io/ingress-nginx/internal/ingress/resolver" +) + +type opentelemetry struct { + r resolver.Resolver +} + +// Config contains the configuration to be used in the Ingress +type Config struct { + Enabled bool `json:"enabled"` + Set bool `json:"set"` + TrustEnabled bool `json:"trust-enabled"` + TrustSet bool `json:"trust-set"` + OperationName string `json:"operation-name"` +} + +// Equal tests for equality between two Config types +func (bd1 *Config) Equal(bd2 *Config) bool { + + if bd1.Set != bd2.Set { + return false + } + + if bd1.Enabled != bd2.Enabled { + return false + } + + if bd1.TrustSet != bd2.TrustSet { + return false + } + + if bd1.TrustEnabled != bd2.TrustEnabled { + return false + } + + if bd1.OperationName != bd2.OperationName { + return false + } + + return true +} + +// NewParser creates a new serviceUpstream annotation parser +func NewParser(r resolver.Resolver) parser.IngressAnnotation { + return opentelemetry{r} +} + +// Parse parses the annotations to look for opentelemetry configurations +func (c opentelemetry) Parse(ing *networking.Ingress) (interface{}, error) { + cfg := Config{} + enabled, err := parser.GetBoolAnnotation("enable-opentelemetry", ing) + if err != nil { + return &cfg, nil + } + cfg.Set = true + cfg.Enabled = enabled + if !enabled { + return &cfg, nil + } + + trustEnabled, err := parser.GetBoolAnnotation("opentelemetry-trust-incoming-span", ing) + if err != nil { + operationName, err := parser.GetStringAnnotation("opentelemetry-operation-name", ing) + if err != nil { + return &cfg, nil + } + cfg.OperationName = operationName + return &cfg, nil + } + + cfg.TrustSet = true + cfg.TrustEnabled = trustEnabled + operationName, err := parser.GetStringAnnotation("opentelemetry-operation-name", ing) + if err != nil { + return &cfg, nil + } + cfg.OperationName = operationName + return &cfg, nil +} diff --git a/internal/ingress/annotations/opentelemetry/main_test.go b/internal/ingress/annotations/opentelemetry/main_test.go new file mode 100644 index 000000000..619108fa6 --- /dev/null +++ b/internal/ingress/annotations/opentelemetry/main_test.go @@ -0,0 +1,170 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package opentelemetry + +import ( + "testing" + + api "k8s.io/api/core/v1" + 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" +) + +func buildIngress() *networking.Ingress { + defaultBackend := networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, + } + + return &networking.Ingress{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: "foo", + Namespace: api.NamespaceDefault, + }, + Spec: networking.IngressSpec{ + DefaultBackend: &networking.IngressBackend{ + Service: &networking.IngressServiceBackend{ + Name: "default-backend", + Port: networking.ServiceBackendPort{ + Number: 80, + }, + }, + }, + Rules: []networking.IngressRule{ + { + Host: "foo.bar.com", + IngressRuleValue: networking.IngressRuleValue{ + HTTP: &networking.HTTPIngressRuleValue{ + Paths: []networking.HTTPIngressPath{ + { + Path: "/foo", + Backend: defaultBackend, + }, + }, + }, + }, + }, + }, + }, + } +} + +func TestIngressAnnotationOpentelemetrySetTrue(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + data[parser.GetAnnotationWithPrefix("enable-opentelemetry")] = "true" + ing.SetAnnotations(data) + + val, _ := NewParser(&resolver.Mock{}).Parse(ing) + openTelemetry, ok := val.(*Config) + if !ok { + t.Errorf("expected a Config type") + } + + if !openTelemetry.Enabled { + t.Errorf("expected annotation value to be true, got false") + } + + if !openTelemetry.Set { + t.Errorf("expected annotation value to be true, got false") + } + + if openTelemetry.TrustSet { + t.Errorf("expected annotation value to be false, got true") + } +} + +func TestIngressAnnotationOpentelemetrySetFalse(t *testing.T) { + ing := buildIngress() + + // Test with explicitly set to false + data := map[string]string{} + data[parser.GetAnnotationWithPrefix("enable-opentelemetry")] = "false" + ing.SetAnnotations(data) + + val, _ := NewParser(&resolver.Mock{}).Parse(ing) + openTelemetry, ok := val.(*Config) + if !ok { + t.Errorf("expected a Config type") + } + + if openTelemetry.Enabled { + t.Errorf("expected annotation value to be false, got true") + } + + if !openTelemetry.Set { + t.Errorf("expected annotation value to be true, got false") + } +} + +func TestIngressAnnotationOpentelemetryTrustSetTrue(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + opName := "foo-op" + data[parser.GetAnnotationWithPrefix("enable-opentelemetry")] = "true" + data[parser.GetAnnotationWithPrefix("opentelemetry-trust-incoming-span")] = "true" + data[parser.GetAnnotationWithPrefix("opentelemetry-operation-name")] = opName + ing.SetAnnotations(data) + + val, _ := NewParser(&resolver.Mock{}).Parse(ing) + openTelemetry, ok := val.(*Config) + if !ok { + t.Errorf("expected a Config type") + } + + if !openTelemetry.Enabled { + t.Errorf("expected annotation value to be true, got false") + } + + if !openTelemetry.Set { + t.Errorf("expected annotation value to be true, got false") + } + + if !openTelemetry.TrustEnabled { + t.Errorf("expected annotation value to be true, got false") + } + + if !openTelemetry.TrustSet { + t.Errorf("expected annotation value to be true, got false") + } + + if openTelemetry.OperationName != opName { + t.Errorf("expected annotation value to be %v, got %v", opName, openTelemetry.OperationName) + } +} + +func TestIngressAnnotationOpentelemetryUnset(t *testing.T) { + ing := buildIngress() + + // Test with no annotation specified + data := map[string]string{} + ing.SetAnnotations(data) + + val, _ := NewParser(&resolver.Mock{}).Parse(ing) + _, ok := val.(*Config) + if !ok { + t.Errorf("expected a Config type") + } +} diff --git a/internal/ingress/annotations/secureupstream/main.go b/internal/ingress/annotations/secureupstream/main.go deleted file mode 100644 index ebaea2058..000000000 --- a/internal/ingress/annotations/secureupstream/main.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2016 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 secureupstream - -import ( - networking "k8s.io/api/networking/v1" - "k8s.io/klog/v2" - - "k8s.io/ingress-nginx/internal/ingress/annotations/parser" - "k8s.io/ingress-nginx/internal/ingress/resolver" -) - -// Config describes SSL backend configuration -type Config struct { - CACert resolver.AuthSSLCert `json:"caCert"` -} - -type su struct { - r resolver.Resolver -} - -// NewParser creates a new secure upstream annotation parser -func NewParser(r resolver.Resolver) parser.IngressAnnotation { - return su{r} -} - -// Parse parses the annotations contained in the ingress -// rule used to indicate if the upstream servers should use SSL -func (a su) Parse(ing *networking.Ingress) (secure interface{}, err error) { - if ca, _ := parser.GetStringAnnotation("secure-verify-ca-secret", ing); ca != "" { - klog.Warningf("NOTE! secure-verify-ca-secret is not supported anymore. Please use proxy-ssl-secret instead") - } - return -} diff --git a/internal/ingress/annotations/secureupstream/main_test.go b/internal/ingress/annotations/secureupstream/main_test.go deleted file mode 100644 index 7546cb5cf..000000000 --- a/internal/ingress/annotations/secureupstream/main_test.go +++ /dev/null @@ -1,162 +0,0 @@ -/* -Copyright 2016 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 secureupstream - -import ( - "fmt" - "testing" - - api "k8s.io/api/core/v1" - 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" -) - -func buildIngress() *networking.Ingress { - defaultBackend := networking.IngressBackend{ - Service: &networking.IngressServiceBackend{ - Name: "default-backend", - Port: networking.ServiceBackendPort{ - Number: 80, - }, - }, - } - - return &networking.Ingress{ - ObjectMeta: meta_v1.ObjectMeta{ - Name: "foo", - Namespace: api.NamespaceDefault, - }, - Spec: networking.IngressSpec{ - DefaultBackend: &networking.IngressBackend{ - Service: &networking.IngressServiceBackend{ - Name: "default-backend", - Port: networking.ServiceBackendPort{ - Number: 80, - }, - }, - }, - Rules: []networking.IngressRule{ - { - Host: "foo.bar.com", - IngressRuleValue: networking.IngressRuleValue{ - HTTP: &networking.HTTPIngressRuleValue{ - Paths: []networking.HTTPIngressPath{ - { - Path: "/foo", - Backend: defaultBackend, - }, - }, - }, - }, - }, - }, - }, - } -} - -type mockCfg struct { - resolver.Mock - certs map[string]resolver.AuthSSLCert -} - -func (cfg mockCfg) GetAuthCertificate(secret string) (*resolver.AuthSSLCert, error) { - if cert, ok := cfg.certs[secret]; ok { - return &cert, nil - } - return nil, fmt.Errorf("secret not found: %v", secret) -} - -func TestNoCA(t *testing.T) { - ing := buildIngress() - data := map[string]string{} - data[parser.GetAnnotationWithPrefix("backend-protocol")] = "HTTPS" - ing.SetAnnotations(data) - - _, err := NewParser(mockCfg{ - certs: map[string]resolver.AuthSSLCert{ - "default/secure-verify-ca": {}, - }, - }).Parse(ing) - if err != nil { - t.Errorf("Unexpected error on ingress: %v", err) - } -} - -func TestAnnotations(t *testing.T) { - ing := buildIngress() - data := map[string]string{} - data[parser.GetAnnotationWithPrefix("backend-protocol")] = "HTTPS" - data[parser.GetAnnotationWithPrefix("secure-verify-ca-secret")] = "secure-verify-ca" - ing.SetAnnotations(data) - - _, err := NewParser(mockCfg{ - certs: map[string]resolver.AuthSSLCert{ - "default/secure-verify-ca": {}, - }, - }).Parse(ing) - if err != nil { - t.Errorf("Unexpected error on ingress: %v", err) - } -} - -func TestSecretNotFound(t *testing.T) { - ing := buildIngress() - data := map[string]string{} - data[parser.GetAnnotationWithPrefix("backend-protocol")] = "HTTPS" - data[parser.GetAnnotationWithPrefix("secure-verify-ca-secret")] = "secure-verify-ca" - ing.SetAnnotations(data) - _, err := NewParser(mockCfg{}).Parse(ing) - if err != nil { - t.Error("Expected secret not found error on ingress") - } -} - -func TestSecretOnNonSecure(t *testing.T) { - ing := buildIngress() - data := map[string]string{} - data[parser.GetAnnotationWithPrefix("backend-protocol")] = "HTTP" - data[parser.GetAnnotationWithPrefix("secure-verify-ca-secret")] = "secure-verify-ca" - ing.SetAnnotations(data) - _, err := NewParser(mockCfg{ - certs: map[string]resolver.AuthSSLCert{ - "default/secure-verify-ca": {}, - }, - }).Parse(ing) - if err != nil { - t.Error("Expected CA secret on non secure backend error on ingress") - } -} - -func TestUnsupportedAnnotation(t *testing.T) { - ing := buildIngress() - data := map[string]string{} - data[parser.GetAnnotationWithPrefix("backend-protocol")] = "HTTPS" - data[parser.GetAnnotationWithPrefix("secure-verify-ca-secret")] = "secure-verify-ca" - ing.SetAnnotations(data) - - _, err := NewParser(mockCfg{ - certs: map[string]resolver.AuthSSLCert{ - "default/secure-verify-ca": {}, - }, - }).Parse(ing) - if err != nil { - t.Errorf("Unexpected error on ingress: %v", err) - } -} diff --git a/internal/ingress/controller/checker_test.go b/internal/ingress/controller/checker_test.go index 5d9fb1baf..a0d2baafa 100644 --- a/internal/ingress/controller/checker_test.go +++ b/internal/ingress/controller/checker_test.go @@ -122,7 +122,7 @@ func TestNginxCheck(t *testing.T) { } func callHealthz(expErr bool, healthzPath string, mux *http.ServeMux) error { - req, err := http.NewRequest("GET", healthzPath, nil) + req, err := http.NewRequest(http.MethodGet, healthzPath, nil) if err != nil { return fmt.Errorf("healthz error: %v", err) } diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go index f064dad53..da37ea3c9 100644 --- a/internal/ingress/controller/config/config.go +++ b/internal/ingress/controller/config/config.go @@ -438,6 +438,11 @@ type Configuration struct { // Default: true UseHTTP2 bool `json:"use-http2,omitempty"` + // Disables gzipping of responses for requests with "User-Agent" header fields matching any of + // the specified regular expressions. + // http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_disable + GzipDisable string `json:"gzip-disable,omitempty"` + // gzip Compression Level that will be used GzipLevel int `json:"gzip-level,omitempty"` @@ -563,6 +568,54 @@ type Configuration struct { // Default: true OpentracingTrustIncomingSpan bool `json:"opentracing-trust-incoming-span"` + // EnableOpentelemetry enables the nginx Opentelemetry extension + // By default this is disabled + EnableOpentelemetry bool `json:"enable-opentelemetry"` + + // OpentelemetryConfig sets the opentelemetry config file + // Default: /etc/nginx/opentelemetry.toml + OpentelemetryConfig string `json:"opentelemetry-config"` + + // OpentelemetryOperationName specifies a custom name for the server span + OpentelemetryOperationName string `json:"opentelemetry-operation-name"` + + // OpentelemetryTrustIncomingSpan sets whether or not to trust incoming trace spans + // If false, incoming span headers will be rejected + // Default: true + OpentelemetryTrustIncomingSpan bool `json:"opentelemetry-trust-incoming-span"` + + // OtlpCollectorHost specifies the host to use when uploading traces + OtlpCollectorHost string `json:"otlp-collector-host"` + + // OtlpCollectorPort specifies the port to use when uploading traces + // Default: 4317 + OtlpCollectorPort string `json:"otlp-collector-port"` + + // OtelServiceName specifies the service name to use for any traces created + // Default: nginx + OtelServiceName string `json:"otel-service-name"` + + // OtelSampler specifies the sampler to use for any traces created + // Default: AlwaysOff + OtelSampler string `json:"otel-sampler"` + + // OtelSamplerRatio specifies the sampler ratio to use for any traces created + // Default: 0.01 + OtelSamplerRatio float32 `json:"otel-sampler-ratio"` + + //OtelSamplerParentBased specifies the parent based sampler to be use for any traces created + // Default: false + OtelSamplerParentBased bool `json:"otel-sampler-parent-based"` + + // MaxQueueSize specifies the max queue size for uploading traces + OtelMaxQueueSize int32 `json:"otel-max-queuesize"` + + // ScheduleDelayMillis specifies the max delay between uploading traces + OtelScheduleDelayMillis int32 `json:"otel-schedule-delay-millis"` + + // MaxExportBatchSize specifies the max export batch size to used when uploading traces + OtelMaxExportBatchSize int32 `json:"otel-max-export-batch-size"` + // ZipkinCollectorHost specifies the host to use when uploading traces ZipkinCollectorHost string `json:"zipkin-collector-host"` @@ -794,7 +847,6 @@ func NewDefault() Configuration { defGlobalExternalAuth := GlobalExternalAuth{"", "", "", "", "", append(defResponseHeaders, ""), "", "", "", []string{}, map[string]string{}, false} cfg := Configuration{ - AllowSnippetAnnotations: true, AllowBackendServerHeader: false, AnnotationValueWordBlocklist: "", @@ -835,7 +887,7 @@ func NewDefault() Configuration { GzipMinLength: 256, GzipTypes: gzipTypes, KeepAlive: 75, - KeepAliveRequests: 100, + KeepAliveRequests: 1000, LargeClientHeaderBuffers: "4 8k", LogFormatEscapeJSON: false, LogFormatStream: logFormatStream, @@ -913,6 +965,13 @@ func NewDefault() Configuration { BindAddressIpv4: defBindAddress, BindAddressIpv6: defBindAddress, OpentracingTrustIncomingSpan: true, + OpentelemetryTrustIncomingSpan: true, + OpentelemetryConfig: "/etc/nginx/opentelemetry.toml", + OtlpCollectorPort: "4317", + OtelServiceName: "nginx", + OtelSampler: "AlwaysOff", + OtelSamplerRatio: 0.01, + OtelSamplerParentBased: false, ZipkinCollectorPort: 9411, ZipkinServiceName: "nginx", ZipkinSampleRate: 1.0, diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index 010eba162..80b5b587b 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -23,7 +23,7 @@ import ( "strings" "time" - "github.com/mitchellh/hashstructure" + "github.com/mitchellh/hashstructure/v2" apiv1 "k8s.io/api/core/v1" networking "k8s.io/api/networking/v1" apiequality "k8s.io/apimachinery/pkg/api/equality" @@ -33,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" clientset "k8s.io/client-go/kubernetes" "k8s.io/ingress-nginx/internal/ingress/annotations" + "k8s.io/ingress-nginx/internal/ingress/annotations/canary" "k8s.io/ingress-nginx/internal/ingress/annotations/log" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/annotations/proxy" @@ -50,9 +51,12 @@ import ( ) const ( - defUpstreamName = "upstream-default-backend" - defServerName = "_" - rootLocation = "/" + defUpstreamName = "upstream-default-backend" + defServerName = "_" + rootLocation = "/" + emptyZone = "" + orphanMetricLabelNoService = "no-service" + orphanMetricLabelNoEndpoint = "no-endpoint" ) // Configuration contains all the settings required by an Ingress controller @@ -98,10 +102,11 @@ type Configuration struct { EnableProfiling bool - EnableMetrics bool - MetricsPerHost bool - MetricsBuckets *collectors.HistogramBuckets - ReportStatusClasses bool + EnableMetrics bool + MetricsPerHost bool + MetricsBuckets *collectors.HistogramBuckets + ReportStatusClasses bool + ExcludeSocketMetrics []string FakeCertificate *ingress.SSLCert @@ -131,6 +136,21 @@ type Configuration struct { DynamicConfigurationRetries int DisableSyncEvents bool + + EnableTopologyAwareRouting bool +} + +func getIngressPodZone(svc *apiv1.Service) string { + svcKey := k8s.MetaNamespaceKey(svc) + if svcZoneAnnotation, ok := svc.ObjectMeta.GetAnnotations()[apiv1.AnnotationTopologyAwareHints]; ok { + if strings.ToLower(svcZoneAnnotation) == "auto" { + if foundZone, ok := k8s.IngressNodeDetails.GetLabels()[apiv1.LabelTopologyZone]; ok { + klog.V(3).Infof("Svc has topology aware annotation enabled, try to use zone %q where controller pod is running for Service %q ", foundZone, svcKey) + return foundZone + } + } + } + return emptyZone } // GetPublishService returns the Service used to set the load-balancer status of Ingresses. @@ -169,7 +189,7 @@ func (n *NGINXController) syncIngress(interface{}) error { if !utilingress.IsDynamicConfigurationEnough(pcfg, n.runningConfig) { klog.InfoS("Configuration changes detected, backend reload required") - hash, _ := hashstructure.Hash(pcfg, &hashstructure.HashOptions{ + hash, _ := hashstructure.Hash(pcfg, hashstructure.FormatV1, &hashstructure.HashOptions{ TagName: "json", }) @@ -429,6 +449,13 @@ func (n *NGINXController) getStreamServices(configmapName string, proto apiv1.Pr var endps []ingress.Endpoint /* #nosec */ targetPort, err := strconv.Atoi(svcPort) // #nosec + var zone string + if n.cfg.EnableTopologyAwareRouting { + zone = getIngressPodZone(svc) + } else { + zone = emptyZone + } + if err != nil { // not a port number, fall back to using port name klog.V(3).Infof("Searching Endpoints with %v port name %q for Service %q", proto, svcPort, nsName) @@ -436,7 +463,7 @@ func (n *NGINXController) getStreamServices(configmapName string, proto apiv1.Pr sp := svc.Spec.Ports[i] if sp.Name == svcPort { if sp.Protocol == proto { - endps = getEndpointsFromSlices(svc, &sp, proto, n.store.GetServiceEndpointsSlices) + endps = getEndpointsFromSlices(svc, &sp, proto, zone, n.store.GetServiceEndpointsSlices) break } } @@ -447,7 +474,7 @@ func (n *NGINXController) getStreamServices(configmapName string, proto apiv1.Pr sp := svc.Spec.Ports[i] if sp.Port == int32(targetPort) { if sp.Protocol == proto { - endps = getEndpointsFromSlices(svc, &sp, proto, n.store.GetServiceEndpointsSlices) + endps = getEndpointsFromSlices(svc, &sp, proto, zone, n.store.GetServiceEndpointsSlices) break } } @@ -498,8 +525,13 @@ func (n *NGINXController) getDefaultUpstream() *ingress.Backend { upstream.Endpoints = append(upstream.Endpoints, n.DefaultEndpoint()) return upstream } - - endps := getEndpointsFromSlices(svc, &svc.Spec.Ports[0], apiv1.ProtocolTCP, n.store.GetServiceEndpointsSlices) + var zone string + if n.cfg.EnableTopologyAwareRouting { + zone = getIngressPodZone(svc) + } else { + zone = emptyZone + } + endps := getEndpointsFromSlices(svc, &svc.Spec.Ports[0], apiv1.ProtocolTCP, zone, n.store.GetServiceEndpointsSlices) if len(endps) == 0 { klog.Warningf("Service %q does not have any active Endpoint", svcKey) endps = []ingress.Endpoint{n.DefaultEndpoint()} @@ -511,11 +543,11 @@ func (n *NGINXController) getDefaultUpstream() *ingress.Backend { } // getConfiguration returns the configuration matching the standard kubernetes ingress -func (n *NGINXController) getConfiguration(ingresses []*ingress.Ingress) (sets.String, []*ingress.Server, *ingress.Configuration) { +func (n *NGINXController) getConfiguration(ingresses []*ingress.Ingress) (sets.Set[string], []*ingress.Server, *ingress.Configuration) { upstreams, servers := n.getBackendServers(ingresses) var passUpstreams []*ingress.SSLPassthroughBackend - hosts := sets.NewString() + hosts := sets.New[string]() for _, server := range servers { // If a location is defined by a prefix string that ends with the slash character, and requests are processed by one of @@ -827,7 +859,13 @@ func (n *NGINXController) getBackendServers(ingresses []*ingress.Ingress) ([]*in } sp := location.DefaultBackend.Spec.Ports[0] - endps := getEndpointsFromSlices(location.DefaultBackend, &sp, apiv1.ProtocolTCP, n.store.GetServiceEndpointsSlices) + var zone string + if n.cfg.EnableTopologyAwareRouting { + zone = getIngressPodZone(location.DefaultBackend) + } else { + zone = emptyZone + } + endps := getEndpointsFromSlices(location.DefaultBackend, &sp, apiv1.ProtocolTCP, zone, n.store.GetServiceEndpointsSlices) // custom backend is valid only if contains at least one endpoint if len(endps) > 0 { name := fmt.Sprintf("custom-default-backend-%v-%v", location.DefaultBackend.GetNamespace(), location.DefaultBackend.GetName()) @@ -932,14 +970,7 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B // configure traffic shaping for canary if anns.Canary.Enabled { upstreams[defBackend].NoServer = true - upstreams[defBackend].TrafficShapingPolicy = ingress.TrafficShapingPolicy{ - Weight: anns.Canary.Weight, - WeightTotal: anns.Canary.WeightTotal, - Header: anns.Canary.Header, - HeaderValue: anns.Canary.HeaderValue, - HeaderPattern: anns.Canary.HeaderPattern, - Cookie: anns.Canary.Cookie, - } + upstreams[defBackend].TrafficShapingPolicy = newTrafficShapingPolicy(anns.Canary) } if len(upstreams[defBackend].Endpoints) == 0 { @@ -1004,13 +1035,7 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B // configure traffic shaping for canary if anns.Canary.Enabled { upstreams[name].NoServer = true - upstreams[name].TrafficShapingPolicy = ingress.TrafficShapingPolicy{ - Weight: anns.Canary.Weight, - Header: anns.Canary.Header, - HeaderValue: anns.Canary.HeaderValue, - HeaderPattern: anns.Canary.HeaderPattern, - Cookie: anns.Canary.Cookie, - } + upstreams[name].TrafficShapingPolicy = newTrafficShapingPolicy(anns.Canary) } if len(upstreams[name].Endpoints) == 0 { @@ -1018,8 +1043,16 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B endp, err := n.serviceEndpoints(svcKey, port.String()) if err != nil { klog.Warningf("Error obtaining Endpoints for Service %q: %v", svcKey, err) + n.metricCollector.IncOrphanIngress(ing.Namespace, ing.Name, orphanMetricLabelNoService) continue } + n.metricCollector.DecOrphanIngress(ing.Namespace, ing.Name, orphanMetricLabelNoService) + + if len(endp) == 0 { + n.metricCollector.IncOrphanIngress(ing.Namespace, ing.Name, orphanMetricLabelNoEndpoint) + } else { + n.metricCollector.DecOrphanIngress(ing.Namespace, ing.Name, orphanMetricLabelNoEndpoint) + } upstreams[name].Endpoints = endp } @@ -1083,7 +1116,12 @@ func (n *NGINXController) serviceEndpoints(svcKey, backendPort string) ([]ingres if err != nil { return upstreams, err } - + var zone string + if n.cfg.EnableTopologyAwareRouting { + zone = getIngressPodZone(svc) + } else { + zone = emptyZone + } klog.V(3).Infof("Obtaining ports information for Service %q", svcKey) // Ingress with an ExternalName Service and no port defined for that Service if svc.Spec.Type == apiv1.ServiceTypeExternalName { @@ -1092,7 +1130,7 @@ func (n *NGINXController) serviceEndpoints(svcKey, backendPort string) ([]ingres return upstreams, nil } servicePort := externalNamePorts(backendPort, svc) - endps := getEndpointsFromSlices(svc, servicePort, apiv1.ProtocolTCP, n.store.GetServiceEndpointsSlices) + endps := getEndpointsFromSlices(svc, servicePort, apiv1.ProtocolTCP, zone, n.store.GetServiceEndpointsSlices) if len(endps) == 0 { klog.Warningf("Service %q does not have any active Endpoint.", svcKey) return upstreams, nil @@ -1109,7 +1147,7 @@ func (n *NGINXController) serviceEndpoints(svcKey, backendPort string) ([]ingres servicePort.TargetPort.String() == backendPort || servicePort.Name == backendPort { - endps := getEndpointsFromSlices(svc, &servicePort, apiv1.ProtocolTCP, n.store.GetServiceEndpointsSlices) + endps := getEndpointsFromSlices(svc, &servicePort, apiv1.ProtocolTCP, zone, n.store.GetServiceEndpointsSlices) if len(endps) == 0 { klog.Warningf("Service %q does not have any active Endpoint.", svcKey) } @@ -1407,6 +1445,7 @@ func locationApplyAnnotations(loc *ingress.Location, anns *annotations.Ingress) loc.EnableGlobalAuth = anns.EnableGlobalAuth loc.HTTP2PushPreload = anns.HTTP2PushPreload loc.Opentracing = anns.Opentracing + loc.Opentelemetry = anns.Opentelemetry loc.Proxy = anns.Proxy loc.ProxySSL = anns.ProxySSL loc.RateLimit = anns.RateLimit @@ -1421,7 +1460,6 @@ func locationApplyAnnotations(loc *ingress.Location, anns *annotations.Ingress) loc.UsePortInRedirects = anns.UsePortInRedirects loc.Connection = anns.Connection loc.Logs = anns.Logs - loc.InfluxDB = anns.InfluxDB loc.DefaultBackend = anns.DefaultBackend loc.BackendProtocol = anns.BackendProtocol loc.FastCGI = anns.FastCGI @@ -1770,3 +1808,15 @@ func (n *NGINXController) getStreamSnippets(ingresses []*ingress.Ingress) []stri } return snippets } + +// newTrafficShapingPolicy creates new ingress.TrafficShapingPolicy instance using canary configuration +func newTrafficShapingPolicy(cfg canary.Config) ingress.TrafficShapingPolicy { + return ingress.TrafficShapingPolicy{ + Weight: cfg.Weight, + WeightTotal: cfg.WeightTotal, + Header: cfg.Header, + HeaderValue: cfg.HeaderValue, + HeaderPattern: cfg.HeaderPattern, + Cookie: cfg.Cookie, + } +} diff --git a/internal/ingress/controller/controller_test.go b/internal/ingress/controller/controller_test.go index 796012cd3..8cca10385 100644 --- a/internal/ingress/controller/controller_test.go +++ b/internal/ingress/controller/controller_test.go @@ -2481,8 +2481,9 @@ func newDynamicNginxController(t *testing.T, setConfigMap func(string) *v1.Confi } return &NGINXController{ - store: storer, - cfg: config, - command: NewNginxCommand(), + store: storer, + cfg: config, + command: NewNginxCommand(), + metricCollector: metric.DummyCollector{}, } } diff --git a/internal/ingress/controller/endpointslices.go b/internal/ingress/controller/endpointslices.go index 5a24c3880..ca6e595c8 100644 --- a/internal/ingress/controller/endpointslices.go +++ b/internal/ingress/controller/endpointslices.go @@ -34,8 +34,8 @@ import ( "k8s.io/ingress-nginx/pkg/apis/ingress" ) -// getEndpoints returns a list of Endpoint structs for a given service/target port combination. -func getEndpointsFromSlices(s *corev1.Service, port *corev1.ServicePort, proto corev1.Protocol, +// getEndpointsFromSlices returns a list of Endpoint structs for a given service/target port combination. +func getEndpointsFromSlices(s *corev1.Service, port *corev1.ServicePort, proto corev1.Protocol, zoneForHints string, getServiceEndpointsSlices func(string) ([]*discoveryv1.EndpointSlice, error)) []ingress.Endpoint { upsServers := []ingress.Endpoint{} @@ -49,6 +49,7 @@ func getEndpointsFromSlices(s *corev1.Service, port *corev1.ServicePort, proto c processedUpstreamServers := make(map[string]struct{}) svcKey := k8s.MetaNamespaceKey(s) + var useTopologyHints bool // ExternalName services if s.Spec.Type == corev1.ServiceTypeExternalName { @@ -111,12 +112,38 @@ func getEndpointsFromSlices(s *corev1.Service, port *corev1.ServicePort, proto c ports = append(ports, targetPort) } } + useTopologyHints = false + if zoneForHints != emptyZone { + useTopologyHints = true + // check if all endpointslices has zone hints + for _, ep := range eps.Endpoints { + if ep.Hints == nil || len(ep.Hints.ForZones) == 0 { + useTopologyHints = false + break + } + } + if useTopologyHints { + klog.V(3).Infof("All endpoint slices has zone hint, using zone %q for Service %q", zoneForHints, svcKey) + } + } + for _, ep := range eps.Endpoints { - if !(*ep.Conditions.Ready) { + if (ep.Conditions.Ready != nil) && !(*ep.Conditions.Ready) { continue } + epHasZone := false + if useTopologyHints { + for _, epzone := range ep.Hints.ForZones { + if epzone.Name == zoneForHints { + epHasZone = true + break + } + } + } - // ep.Hints + if useTopologyHints && !epHasZone { + continue + } for _, epPort := range ports { for _, epAddress := range ep.Addresses { diff --git a/internal/ingress/controller/endpointslices_test.go b/internal/ingress/controller/endpointslices_test.go index e404c4949..b61e9a4f3 100644 --- a/internal/ingress/controller/endpointslices_test.go +++ b/internal/ingress/controller/endpointslices_test.go @@ -33,6 +33,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { svc *corev1.Service port *corev1.ServicePort proto corev1.Protocol + zone string fn func(string) ([]*discoveryv1.EndpointSlice, error) result []ingress.Endpoint }{ @@ -41,6 +42,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { nil, nil, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return nil, nil }, @@ -51,6 +53,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { &corev1.Service{}, nil, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return nil, nil }, @@ -61,6 +64,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { &corev1.Service{}, &corev1.ServicePort{Name: "default"}, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{}, nil }, @@ -75,6 +79,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { }, &corev1.ServicePort{Name: "default"}, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{}, nil }, @@ -99,6 +104,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromInt(80), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{}, nil }, @@ -123,6 +129,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromInt(80), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{}, nil }, @@ -147,6 +154,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromInt(80), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{}, nil }, @@ -176,6 +184,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromInt(80), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{}, nil }, @@ -205,6 +214,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromInt(80), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{}, nil }, @@ -229,6 +239,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromInt(80), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return nil, fmt.Errorf("unexpected error") }, @@ -253,6 +264,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromInt(80), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{{ ObjectMeta: metav1.ObjectMeta{ @@ -296,6 +308,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromInt(80), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{{ ObjectMeta: metav1.ObjectMeta{ @@ -339,6 +352,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromString("port-1"), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{{ ObjectMeta: metav1.ObjectMeta{ @@ -382,6 +396,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromInt(80), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{{ ObjectMeta: metav1.ObjectMeta{ @@ -430,6 +445,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromInt(80), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{{ ObjectMeta: metav1.ObjectMeta{ @@ -478,6 +494,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromString("port-1"), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{ { @@ -552,6 +569,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromString("port-1"), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{ { @@ -622,6 +640,7 @@ func TestGetEndpointsFromSlices(t *testing.T) { TargetPort: intstr.FromString("port-1"), }, corev1.ProtocolTCP, + "", func(string) ([]*discoveryv1.EndpointSlice, error) { return []*discoveryv1.EndpointSlice{{ ObjectMeta: metav1.ObjectMeta{ @@ -656,11 +675,251 @@ func TestGetEndpointsFromSlices(t *testing.T) { }, }, }, + { + "should return one endpoint which belongs to zone", + &corev1.Service{ + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeClusterIP, + ClusterIP: "1.1.1.1", + Ports: []corev1.ServicePort{ + { + Name: "default", + TargetPort: intstr.FromString("port-1"), + }, + }, + }, + }, + &corev1.ServicePort{ + Name: "port-1", + TargetPort: intstr.FromString("port-1"), + }, + corev1.ProtocolTCP, + "eu-west-1b", + func(string) ([]*discoveryv1.EndpointSlice, error) { + return []*discoveryv1.EndpointSlice{{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{discoveryv1.LabelServiceName: "default"}, + }, + Endpoints: []discoveryv1.Endpoint{ + { + Addresses: []string{"1.1.1.1"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: &[]bool{true}[0], + }, + Hints: &[]discoveryv1.EndpointHints{{ + ForZones: []discoveryv1.ForZone{{ + Name: "eu-west-1b", + }}, + }}[0], + }, + { + Addresses: []string{"1.1.1.2"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: &[]bool{true}[0], + }, + Hints: &[]discoveryv1.EndpointHints{{ + ForZones: []discoveryv1.ForZone{{ + Name: "eu-west-1a", + }}, + }}[0], + }, + { + Addresses: []string{"1.1.1.3"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: &[]bool{true}[0], + }, + Hints: &[]discoveryv1.EndpointHints{{ + ForZones: []discoveryv1.ForZone{{ + Name: "eu-west-1c", + }}, + }}[0], + }, + }, + Ports: []discoveryv1.EndpointPort{ + { + Protocol: &[]corev1.Protocol{corev1.ProtocolTCP}[0], + Port: &[]int32{80}[0], + Name: &[]string{"port-1"}[0], + }, + }, + }}, nil + }, + []ingress.Endpoint{ + { + Address: "1.1.1.1", + Port: "80", + }, + }, + }, + { + "should return all endpoints because one is missing zone hint", + &corev1.Service{ + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeClusterIP, + ClusterIP: "1.1.1.1", + Ports: []corev1.ServicePort{ + { + Name: "default", + TargetPort: intstr.FromString("port-1"), + }, + }, + }, + }, + &corev1.ServicePort{ + Name: "port-1", + TargetPort: intstr.FromString("port-1"), + }, + corev1.ProtocolTCP, + "eu-west-1b", + func(string) ([]*discoveryv1.EndpointSlice, error) { + return []*discoveryv1.EndpointSlice{{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{discoveryv1.LabelServiceName: "default"}, + }, + Endpoints: []discoveryv1.Endpoint{ + { + Addresses: []string{"1.1.1.1"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: &[]bool{true}[0], + }, + Hints: &[]discoveryv1.EndpointHints{{ + ForZones: []discoveryv1.ForZone{{ + Name: "eu-west-1b", + }}, + }}[0], + }, + { + Addresses: []string{"1.1.1.2"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: &[]bool{true}[0], + }, + Hints: &[]discoveryv1.EndpointHints{{ + ForZones: []discoveryv1.ForZone{{ + Name: "eu-west-1b", + }}, + }}[0], + }, + { + Addresses: []string{"1.1.1.3"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: &[]bool{true}[0], + }, + Hints: &[]discoveryv1.EndpointHints{{}}[0], + }, + }, + Ports: []discoveryv1.EndpointPort{ + { + Protocol: &[]corev1.Protocol{corev1.ProtocolTCP}[0], + Port: &[]int32{80}[0], + Name: &[]string{"port-1"}[0], + }, + }, + }}, nil + }, + []ingress.Endpoint{ + { + Address: "1.1.1.1", + Port: "80", + }, + { + Address: "1.1.1.2", + Port: "80", + }, + { + Address: "1.1.1.3", + Port: "80", + }, + }, + }, + { + "should return all endpoints because no zone from controller node", + &corev1.Service{ + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeClusterIP, + ClusterIP: "1.1.1.1", + Ports: []corev1.ServicePort{ + { + Name: "default", + TargetPort: intstr.FromString("port-1"), + }, + }, + }, + }, + &corev1.ServicePort{ + Name: "port-1", + TargetPort: intstr.FromString("port-1"), + }, + corev1.ProtocolTCP, + "", + func(string) ([]*discoveryv1.EndpointSlice, error) { + return []*discoveryv1.EndpointSlice{{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{discoveryv1.LabelServiceName: "default"}, + }, + Endpoints: []discoveryv1.Endpoint{ + { + Addresses: []string{"1.1.1.1"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: &[]bool{true}[0], + }, + Hints: &[]discoveryv1.EndpointHints{{ + ForZones: []discoveryv1.ForZone{{ + Name: "eu-west-1a", + }}, + }}[0], + }, + { + Addresses: []string{"1.1.1.2"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: &[]bool{true}[0], + }, + Hints: &[]discoveryv1.EndpointHints{{ + ForZones: []discoveryv1.ForZone{{ + Name: "eu-west-1b", + }}, + }}[0], + }, + { + Addresses: []string{"1.1.1.3"}, + Conditions: discoveryv1.EndpointConditions{ + Ready: &[]bool{true}[0], + }, + Hints: &[]discoveryv1.EndpointHints{{ + ForZones: []discoveryv1.ForZone{{ + Name: "eu-west-1c", + }}, + }}[0], + }, + }, + Ports: []discoveryv1.EndpointPort{ + { + Protocol: &[]corev1.Protocol{corev1.ProtocolTCP}[0], + Port: &[]int32{80}[0], + Name: &[]string{"port-1"}[0], + }, + }, + }}, nil + }, + []ingress.Endpoint{ + { + Address: "1.1.1.1", + Port: "80", + }, + { + Address: "1.1.1.2", + Port: "80", + }, + { + Address: "1.1.1.3", + Port: "80", + }, + }, + }, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { - result := getEndpointsFromSlices(testCase.svc, testCase.port, testCase.proto, testCase.fn) + result := getEndpointsFromSlices(testCase.svc, testCase.port, testCase.proto, testCase.zone, testCase.fn) if len(testCase.result) != len(result) { t.Errorf("Expected %d Endpoints but got %d", len(testCase.result), len(result)) } diff --git a/internal/ingress/controller/nginx.go b/internal/ingress/controller/nginx.go index 5575009ea..80693db5c 100644 --- a/internal/ingress/controller/nginx.go +++ b/internal/ingress/controller/nginx.go @@ -673,6 +673,11 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error { return err } + err = createOpentelemetryCfg(cfg) + if err != nil { + return err + } + err = n.testTemplate(content) if err != nil { return err @@ -1056,6 +1061,29 @@ const datadogTmpl = `{ "dd.priority.sampling": {{ .DatadogPrioritySampling }} }` +const otelTmpl = ` +exporter = "otlp" +processor = "batch" + +[exporters.otlp] +# Alternatively the OTEL_EXPORTER_OTLP_ENDPOINT environment variable can also be used. +host = "{{ .OtlpCollectorHost }}" +port = {{ .OtlpCollectorPort }} + +[processors.batch] +max_queue_size = {{ .OtelMaxQueueSize }} +schedule_delay_millis = {{ .OtelScheduleDelayMillis }} +max_export_batch_size = {{ .OtelMaxExportBatchSize }} + +[service] +name = "{{ .OtelServiceName }}" # Opentelemetry resource name + +[sampler] +name = "{{ .OtelSampler }}" # Also: AlwaysOff, TraceIdRatioBased +ratio = {{ .OtelSamplerRatio }} +parent_based = {{ .OtelSamplerParentBased }} +` + func createOpentracingCfg(cfg ngx_config.Configuration) error { var tmpl *template.Template var err error @@ -1091,6 +1119,21 @@ func createOpentracingCfg(cfg ngx_config.Configuration) error { return os.WriteFile("/etc/nginx/opentracing.json", []byte(expanded), file.ReadWriteByUser) } +func createOpentelemetryCfg(cfg ngx_config.Configuration) error { + + tmpl, err := template.New("otel").Parse(otelTmpl) + if err != nil { + return err + } + tmplBuf := bytes.NewBuffer(make([]byte, 0)) + err = tmpl.Execute(tmplBuf, cfg) + if err != nil { + return err + } + + return os.WriteFile(cfg.OpentelemetryConfig, tmplBuf.Bytes(), file.ReadWriteByUser) +} + func cleanTempNginxCfg() error { var files []string diff --git a/internal/ingress/controller/nginx_test.go b/internal/ingress/controller/nginx_test.go index 4d3155194..56eb0f324 100644 --- a/internal/ingress/controller/nginx_test.go +++ b/internal/ingress/controller/nginx_test.go @@ -62,7 +62,7 @@ func TestConfigureDynamically(t *testing.T) { Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) - if r.Method != "POST" { + if r.Method != http.MethodPost { t.Errorf("expected a 'POST' request, got '%s'", r.Method) } @@ -222,7 +222,7 @@ func TestConfigureCertificates(t *testing.T) { Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) - if r.Method != "POST" { + if r.Method != http.MethodPost { t.Errorf("expected a 'POST' request, got '%s'", r.Method) } diff --git a/internal/ingress/controller/store/objectref.go b/internal/ingress/controller/store/objectref.go index 9ef13bf07..89ea47251 100644 --- a/internal/ingress/controller/store/objectref.go +++ b/internal/ingress/controller/store/objectref.go @@ -37,13 +37,13 @@ type ObjectRefMap interface { type objectRefMap struct { sync.Mutex - v map[string]sets.String + v map[string]sets.Set[string] } // NewObjectRefMap returns a new ObjectRefMap. func NewObjectRefMap() ObjectRefMap { return &objectRefMap{ - v: make(map[string]sets.String), + v: make(map[string]sets.Set[string]), } } @@ -54,7 +54,7 @@ func (o *objectRefMap) Insert(consumer string, ref ...string) { for _, r := range ref { if _, ok := o.v[r]; !ok { - o.v[r] = sets.NewString(consumer) + o.v[r] = sets.New[string](consumer) continue } o.v[r].Insert(consumer) @@ -112,7 +112,7 @@ func (o *objectRefMap) Reference(ref string) []string { if !ok { return make([]string, 0) } - return consumers.List() + return consumers.UnsortedList() } // ReferencedBy returns all objects referenced by the given object. diff --git a/internal/ingress/controller/store/store.go b/internal/ingress/controller/store/store.go index 13af28137..7157332c3 100644 --- a/internal/ingress/controller/store/store.go +++ b/internal/ingress/controller/store/store.go @@ -59,7 +59,6 @@ import ( "k8s.io/ingress-nginx/internal/ingress/resolver" "k8s.io/ingress-nginx/internal/k8s" "k8s.io/ingress-nginx/pkg/apis/ingress" - ingressutils "k8s.io/ingress-nginx/pkg/util/ingress" ) // IngressFilterFunc decides if an Ingress should be omitted or not @@ -702,7 +701,6 @@ func New( }, } - // TODO: add e2e test to verify that changes to one or more configmap trigger an update changeTriggerUpdate := func(name string) bool { return name == configmap || name == tcp || name == udp } @@ -865,10 +863,6 @@ func (s *k8sStore) syncIngress(ing *networkingv1.Ingress) { if path.Path == "" { copyIng.Spec.Rules[ri].HTTP.Paths[pi].Path = "/" } - if !ingressutils.IsSafePath(copyIng, path.Path) { - klog.Warningf("ingress %s contains invalid path %s", key, path.Path) - return - } } } diff --git a/internal/ingress/controller/template/configmap.go b/internal/ingress/controller/template/configmap.go index 61e8e4998..c73f3b6c0 100644 --- a/internal/ingress/controller/template/configmap.go +++ b/internal/ingress/controller/template/configmap.go @@ -26,7 +26,7 @@ import ( "k8s.io/klog/v2" - "github.com/mitchellh/hashstructure" + "github.com/mitchellh/hashstructure/v2" "github.com/mitchellh/mapstructure" "k8s.io/apimachinery/pkg/util/sets" @@ -431,7 +431,7 @@ func ReadConfig(src map[string]string) config.Configuration { klog.Warningf("unexpected error merging defaults: %v", err) } - hash, err := hashstructure.Hash(to, &hashstructure.HashOptions{ + hash, err := hashstructure.Hash(to, hashstructure.FormatV1, &hashstructure.HashOptions{ TagName: "json", }) if err != nil { diff --git a/internal/ingress/controller/template/configmap_test.go b/internal/ingress/controller/template/configmap_test.go index c662e0bc7..dad841694 100644 --- a/internal/ingress/controller/template/configmap_test.go +++ b/internal/ingress/controller/template/configmap_test.go @@ -23,7 +23,7 @@ import ( "time" "github.com/kylelemons/godebug/pretty" - "github.com/mitchellh/hashstructure" + "github.com/mitchellh/hashstructure/v2" "k8s.io/ingress-nginx/internal/ingress/annotations/authreq" "k8s.io/ingress-nginx/internal/ingress/controller/config" @@ -64,6 +64,7 @@ func TestMergeConfigMapToStruct(t *testing.T) { "access-log-path": "/var/log/test/access.log", "error-log-path": "/var/log/test/error.log", "use-gzip": "false", + "gzip-disable": "msie6", "gzip-level": "9", "gzip-min-length": "1024", "gzip-types": "text/html", @@ -87,6 +88,7 @@ func TestMergeConfigMapToStruct(t *testing.T) { def.ProxyReadTimeout = 1 def.ProxySendTimeout = 2 def.UseProxyProtocol = true + def.GzipDisable = "msie6" def.GzipLevel = 9 def.GzipMinLength = 1024 def.GzipTypes = "text/html" @@ -102,7 +104,7 @@ func TestMergeConfigMapToStruct(t *testing.T) { def.DefaultType = "text/plain" def.DebugConnections = []string{"127.0.0.1", "1.1.1.1/24", "::1"} - hash, err := hashstructure.Hash(def, &hashstructure.HashOptions{ + hash, err := hashstructure.Hash(def, hashstructure.FormatV1, &hashstructure.HashOptions{ TagName: "json", }) if err != nil { @@ -132,7 +134,7 @@ func TestMergeConfigMapToStruct(t *testing.T) { def.LuaSharedDicts = defaultLuaSharedDicts def.DisableIpv6DNS = true - hash, err = hashstructure.Hash(def, &hashstructure.HashOptions{ + hash, err = hashstructure.Hash(def, hashstructure.FormatV1, &hashstructure.HashOptions{ TagName: "json", }) if err != nil { @@ -153,7 +155,7 @@ func TestMergeConfigMapToStruct(t *testing.T) { def.WhitelistSourceRange = []string{"1.1.1.1/32"} def.DisableIpv6DNS = true - hash, err = hashstructure.Hash(def, &hashstructure.HashOptions{ + hash, err = hashstructure.Hash(def, hashstructure.FormatV1, &hashstructure.HashOptions{ TagName: "json", }) if err != nil { diff --git a/internal/ingress/controller/template/template.go b/internal/ingress/controller/template/template.go index 315262150..6aadab48e 100644 --- a/internal/ingress/controller/template/template.go +++ b/internal/ingress/controller/template/template.go @@ -40,7 +40,6 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" - "k8s.io/ingress-nginx/internal/ingress/annotations/influxdb" "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/annotations/ratelimit" "k8s.io/ingress-nginx/internal/ingress/controller/config" @@ -265,8 +264,8 @@ var ( "buildAuthSignURL": buildAuthSignURL, "buildAuthSignURLLocation": buildAuthSignURLLocation, "buildOpentracing": buildOpentracing, + "buildOpentelemetry": buildOpentelemetry, "proxySetHeader": proxySetHeader, - "buildInfluxDB": buildInfluxDB, "enforceRegexModifier": enforceRegexModifier, "buildCustomErrorDeps": buildCustomErrorDeps, "buildCustomErrorLocationsPerServer": buildCustomErrorLocationsPerServer, @@ -274,11 +273,12 @@ var ( "buildHTTPListener": buildHTTPListener, "buildHTTPSListener": buildHTTPSListener, "buildOpentracingForLocation": buildOpentracingForLocation, + "buildOpentelemetryForLocation": buildOpentelemetryForLocation, "shouldLoadOpentracingModule": shouldLoadOpentracingModule, + "shouldLoadOpentelemetryModule": shouldLoadOpentelemetryModule, "buildModSecurityForLocation": buildModSecurityForLocation, "buildMirrorLocations": buildMirrorLocations, "shouldLoadAuthDigestModule": shouldLoadAuthDigestModule, - "shouldLoadInfluxDBModule": shouldLoadInfluxDBModule, "buildServerName": buildServerName, "buildCorsOriginRegex": buildCorsOriginRegex, } @@ -792,7 +792,7 @@ rewrite "(?i)%s" %s break; func filterRateLimits(input interface{}) []ratelimit.Config { ratelimits := []ratelimit.Config{} - found := sets.String{} + found := sets.Set[string]{} servers, ok := input.([]*ingress.Server) if !ok { @@ -815,12 +815,12 @@ func filterRateLimits(input interface{}) []ratelimit.Config { // for connection limit by IP address, one for limiting requests per minute, and // one for limiting requests per second. func buildRateLimitZones(input interface{}) []string { - zones := sets.String{} + zones := sets.Set[string]{} servers, ok := input.([]*ingress.Server) if !ok { klog.Errorf("expected a '[]*ingress.Server' type but %T was returned", input) - return zones.List() + return zones.UnsortedList() } for _, server := range servers { @@ -859,7 +859,7 @@ func buildRateLimitZones(input interface{}) []string { } } - return zones.List() + return zones.UnsortedList() } // buildRateLimit produces an array of limit_req to be used inside the Path of @@ -1239,27 +1239,31 @@ func buildOpentracing(c interface{}, s interface{}) string { return buf.String() } -// buildInfluxDB produces the single line configuration -// needed by the InfluxDB module to send request's metrics -// for the current resource -func buildInfluxDB(input interface{}) string { - cfg, ok := input.(influxdb.Config) +func buildOpentelemetry(c interface{}, s interface{}) string { + cfg, ok := c.(config.Configuration) if !ok { - klog.Errorf("expected an 'influxdb.Config' type but %T was returned", input) + klog.Errorf("expected a 'config.Configuration' type but %T was returned", c) return "" } - if !cfg.InfluxDBEnabled { + servers, ok := s.([]*ingress.Server) + if !ok { + klog.Errorf("expected an '[]*ingress.Server' type but %T was returned", s) return "" } - return fmt.Sprintf( - "influxdb server_name=%s host=%s port=%s measurement=%s enabled=true;", - cfg.InfluxDBServerName, - cfg.InfluxDBHost, - cfg.InfluxDBPort, - cfg.InfluxDBMeasurement, - ) + if !shouldLoadOpentelemetryModule(cfg, servers) { + return "" + } + + buf := bytes.NewBufferString("") + + buf.WriteString("\r\n") + + if cfg.OpentelemetryOperationName != "" { + buf.WriteString(fmt.Sprintf("opentelemetry_operation_name \"%s\";\n", cfg.OpentelemetryOperationName)) + } + return buf.String() } func proxySetHeader(loc interface{}) string { @@ -1360,6 +1364,13 @@ func opentracingPropagateContext(location *ingress.Location) string { return "opentracing_propagate_context;" } +func opentelemetryPropagateContext(location *ingress.Location) string { + if location == nil { + return "" + } + return "opentelemetry_propagate;" +} + // shouldLoadModSecurityModule determines whether or not the ModSecurity module needs to be loaded. // First, it checks if `enable-modsecurity` is set in the ConfigMap. If it is not, it iterates over all locations to // check if ModSecurity is enabled by the annotation `nginx.ingress.kubernetes.io/enable-modsecurity`. @@ -1575,6 +1586,36 @@ func buildOpentracingForLocation(isOTEnabled bool, isOTTrustSet bool, location * return opc } +func buildOpentelemetryForLocation(isOTEnabled bool, isOTTrustSet bool, location *ingress.Location) string { + isOTEnabledInLoc := location.Opentelemetry.Enabled + isOTSetInLoc := location.Opentelemetry.Set + + if isOTEnabled { + if isOTSetInLoc && !isOTEnabledInLoc { + return "opentelemetry off;" + } + } else if !isOTSetInLoc || !isOTEnabledInLoc { + return "" + } + + opc := opentelemetryPropagateContext(location) + if opc != "" { + opc = fmt.Sprintf("opentelemetry on;\n%v", opc) + } + + if location.Opentelemetry.OperationName != "" { + opc = opc + "\nopentelemetry_operation_name " + location.Opentelemetry.OperationName + ";" + } + + if (!isOTTrustSet && !location.Opentelemetry.TrustSet) || + (location.Opentelemetry.TrustSet && !location.Opentelemetry.TrustEnabled) { + opc = opc + "\nopentelemetry_trust_incoming_spans off;" + } else { + opc = opc + "\nopentelemetry_trust_incoming_spans on;" + } + return opc +} + // shouldLoadOpentracingModule determines whether or not the Opentracing module needs to be loaded. // First, it checks if `enable-opentracing` is set in the ConfigMap. If it is not, it iterates over all locations to // check if Opentracing is enabled by the annotation `nginx.ingress.kubernetes.io/enable-opentracing`. @@ -1606,6 +1647,35 @@ func shouldLoadOpentracingModule(c interface{}, s interface{}) bool { return false } +// shouldLoadOpentelemetryModule determines whether or not the Opentelemetry module needs to be loaded. +// It checks if `enable-opentelemetry` is set in the ConfigMap. +func shouldLoadOpentelemetryModule(c interface{}, s interface{}) bool { + cfg, ok := c.(config.Configuration) + if !ok { + klog.Errorf("expected a 'config.Configuration' type but %T was returned", c) + return false + } + + servers, ok := s.([]*ingress.Server) + if !ok { + klog.Errorf("expected an '[]*ingress.Server' type but %T was returned", s) + return false + } + + if cfg.EnableOpentelemetry { + return true + } + + for _, server := range servers { + for _, location := range server.Locations { + if location.Opentelemetry.Enabled { + return true + } + } + } + return false +} + func buildModSecurityForLocation(cfg config.Configuration, location *ingress.Location) string { isMSEnabledInLoc := location.ModSecurity.Enable isMSEnableSetInLoc := location.ModSecurity.EnableSet @@ -1654,7 +1724,7 @@ func buildModSecurityForLocation(cfg config.Configuration, location *ingress.Loc func buildMirrorLocations(locs []*ingress.Location) string { var buffer bytes.Buffer - mapped := sets.String{} + mapped := sets.Set[string]{} for _, loc := range locs { if loc.Mirror.Source == "" || loc.Mirror.Target == "" { @@ -1701,25 +1771,6 @@ func shouldLoadAuthDigestModule(s interface{}) bool { return false } -// shouldLoadInfluxDBModule determines whether or not the ngx_http_auth_digest_module module needs to be loaded. -func shouldLoadInfluxDBModule(s interface{}) bool { - servers, ok := s.([]*ingress.Server) - if !ok { - klog.Errorf("expected an '[]*ingress.Server' type but %T was returned", s) - return false - } - - for _, server := range servers { - for _, location := range server.Locations { - if location.InfluxDB.InfluxDBEnabled { - return true - } - } - } - - return false -} - // buildServerName ensures wildcard hostnames are valid func buildServerName(hostname string) string { if !strings.HasPrefix(hostname, "*") { @@ -1732,7 +1783,7 @@ func buildServerName(hostname string) string { return `~^(?[\w-]+)\.` + strings.Join(parts, "\\.") + `$` } -// parseComplexNGINXVar parses things like "$my${complex}ngx\$var" into +// parseComplexNginxVarIntoLuaTable parses things like "$my${complex}ngx\$var" into // [["$var", "complex", "my", "ngx"]]. In other words, 2nd and 3rd elements // in the result are actual NGINX variable names, whereas first and 4th elements // are string literals. diff --git a/internal/ingress/controller/template/template_test.go b/internal/ingress/controller/template/template_test.go index cb1ebd1b7..1980d7e52 100644 --- a/internal/ingress/controller/template/template_test.go +++ b/internal/ingress/controller/template/template_test.go @@ -35,8 +35,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-nginx/internal/ingress/annotations/authreq" - "k8s.io/ingress-nginx/internal/ingress/annotations/influxdb" "k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity" + "k8s.io/ingress-nginx/internal/ingress/annotations/opentelemetry" "k8s.io/ingress-nginx/internal/ingress/annotations/opentracing" "k8s.io/ingress-nginx/internal/ingress/annotations/ratelimit" "k8s.io/ingress-nginx/internal/ingress/annotations/rewrite" @@ -1150,6 +1150,26 @@ func TestOpentracingPropagateContext(t *testing.T) { } } +func TestOpentelemetryPropagateContext(t *testing.T) { + tests := map[*ingress.Location]string{ + {BackendProtocol: "HTTP"}: "opentelemetry_propagate;", + {BackendProtocol: "HTTPS"}: "opentelemetry_propagate;", + {BackendProtocol: "AUTO_HTTP"}: "opentelemetry_propagate;", + {BackendProtocol: "GRPC"}: "opentelemetry_propagate;", + {BackendProtocol: "GRPCS"}: "opentelemetry_propagate;", + {BackendProtocol: "AJP"}: "opentelemetry_propagate;", + {BackendProtocol: "FCGI"}: "opentelemetry_propagate;", + nil: "", + } + + for loc, expectedDirective := range tests { + actualDirective := opentelemetryPropagateContext(loc) + if actualDirective != expectedDirective { + t.Errorf("Expected %v but returned %v", expectedDirective, actualDirective) + } + } +} + func TestGetIngressInformation(t *testing.T) { testcases := map[string]struct { @@ -1619,30 +1639,6 @@ func TestProxySetHeader(t *testing.T) { } } -func TestBuildInfluxDB(t *testing.T) { - invalidType := &ingress.Ingress{} - expected := "" - actual := buildInfluxDB(invalidType) - - if expected != actual { - t.Errorf("Expected '%v' but returned '%v'", expected, actual) - } - - cfg := influxdb.Config{ - InfluxDBEnabled: true, - InfluxDBServerName: "ok.com", - InfluxDBHost: "host.com", - InfluxDBPort: "5252", - InfluxDBMeasurement: "ok", - } - expected = "influxdb server_name=ok.com host=host.com port=5252 measurement=ok enabled=true;" - actual = buildInfluxDB(cfg) - - if expected != actual { - t.Errorf("Expected '%v' but returned '%v'", expected, actual) - } -} - func TestBuildOpenTracing(t *testing.T) { invalidType := &ingress.Ingress{} expected := "" @@ -1723,6 +1719,37 @@ func TestBuildOpenTracing(t *testing.T) { } +func TestBuildOpenTelemetry(t *testing.T) { + invalidType := &ingress.Ingress{} + expected := "" + actual := buildOpentelemetry(invalidType, []*ingress.Server{}) + + if expected != actual { + t.Errorf("Expected '%v' but returned '%v'", expected, actual) + } + + cfgNoHost := config.Configuration{ + EnableOpentelemetry: true, + } + expected = "\r\n" + actual = buildOpentelemetry(cfgNoHost, []*ingress.Server{}) + + if expected != actual { + t.Errorf("Expected '%v' but returned '%v'", expected, actual) + } + + cfgOpenTelemetry := config.Configuration{ + EnableOpentelemetry: true, + OpentelemetryOperationName: "my-operation-name", + } + expected = "\r\n" + expected += "opentelemetry_operation_name \"my-operation-name\";\n" + actual = buildOpentelemetry(cfgOpenTelemetry, []*ingress.Server{}) + if expected != actual { + t.Errorf("Expected '%v' but returned '%v'", expected, actual) + } +} + func TestEnforceRegexModifier(t *testing.T) { invalidType := &ingress.Ingress{} expected := false @@ -1903,6 +1930,107 @@ func TestShouldLoadOpentracingModule(t *testing.T) { } } +func TestOpentelemetryForLocation(t *testing.T) { + trueVal := true + falseVal := false + + loadOT := `opentelemetry on; +opentelemetry_propagate; +opentelemetry_trust_incoming_spans on;` + loadOTUntrustedSpan := `opentelemetry on; +opentelemetry_propagate; +opentelemetry_trust_incoming_spans off;` + testCases := []struct { + description string + globalOT bool + isSetInLoc bool + isOTInLoc *bool + globalTrust bool + isTrustSetInLoc bool + isTrustInLoc *bool + expected string + }{ + {"globally enabled, without annotation", true, false, nil, true, false, nil, loadOT}, + {"globally enabled and enabled in location", true, true, &trueVal, true, false, nil, loadOT}, + {"globally disabled and not enabled in location", false, false, nil, true, false, nil, ""}, + {"globally disabled but enabled in location", false, true, &trueVal, true, false, nil, loadOT}, + {"globally trusted, not trusted in location", true, false, nil, true, true, &falseVal, loadOTUntrustedSpan}, + {"not globally trusted, trust set in location", true, false, nil, false, true, &trueVal, loadOT}, + {"not globally trusted, trust not set in location", true, false, nil, false, false, nil, loadOTUntrustedSpan}, + } + + for _, testCase := range testCases { + il := &ingress.Location{ + Opentelemetry: opentelemetry.Config{Set: testCase.isSetInLoc, TrustSet: testCase.isTrustSetInLoc}, + } + if il.Opentelemetry.Set { + il.Opentelemetry.Enabled = *testCase.isOTInLoc + } + if il.Opentelemetry.TrustSet { + il.Opentelemetry.TrustEnabled = *testCase.isTrustInLoc + } + + actual := buildOpentelemetryForLocation(testCase.globalOT, testCase.globalTrust, il) + + if testCase.expected != actual { + t.Errorf("%v: expected '%v' but returned '%v'", testCase.description, testCase.expected, actual) + } + } +} + +func TestShouldLoadOpentelemetryModule(t *testing.T) { + // ### Invalid argument type tests ### + // The first tests should return false. + expected := false + + invalidType := &ingress.Ingress{} + actual := shouldLoadOpentelemetryModule(config.Configuration{}, invalidType) + if expected != actual { + t.Errorf("Expected '%v' but returned '%v'", expected, actual) + } + + actual = shouldLoadOpentelemetryModule(invalidType, []*ingress.Server{}) + if expected != actual { + t.Errorf("Expected '%v' but returned '%v'", expected, actual) + } + + // ### Functional tests ### + actual = shouldLoadOpentelemetryModule(config.Configuration{}, []*ingress.Server{}) + if expected != actual { + t.Errorf("Expected '%v' but returned '%v'", expected, actual) + } + + // All further tests should return true. + expected = true + + configuration := config.Configuration{EnableOpentelemetry: true} + actual = shouldLoadOpentelemetryModule(configuration, []*ingress.Server{}) + if expected != actual { + t.Errorf("Expected '%v' but returned '%v'", expected, actual) + } + + servers := []*ingress.Server{ + { + Locations: []*ingress.Location{ + { + Opentelemetry: opentelemetry.Config{ + Enabled: true, + }, + }, + }, + }, + } + actual = shouldLoadOpentelemetryModule(config.Configuration{}, servers) + if expected != actual { + t.Errorf("Expected '%v' but returned '%v'", expected, actual) + } + + actual = shouldLoadOpentelemetryModule(configuration, servers) + if expected != actual { + t.Errorf("Expected '%v' but returned '%v'", expected, actual) + } +} + func TestModSecurityForLocation(t *testing.T) { loadModule := `modsecurity on; ` diff --git a/internal/ingress/inspector/inspector.go b/internal/ingress/inspector/inspector.go index 98f257997..e7b6c2f10 100644 --- a/internal/ingress/inspector/inspector.go +++ b/internal/ingress/inspector/inspector.go @@ -26,11 +26,11 @@ import ( // if an object contains invalid configurations that may represent a security risk, // and returning an error in this case func DeepInspect(obj interface{}) error { - switch obj.(type) { + switch obj := obj.(type) { case *networking.Ingress: - return InspectIngress(obj.(*networking.Ingress)) + return InspectIngress(obj) case *corev1.Service: - return InspectService(obj.(*corev1.Service)) + return InspectService(obj) default: klog.Warningf("received invalid object to inspect: %T", obj) return nil diff --git a/internal/ingress/metric/collectors/controller.go b/internal/ingress/metric/collectors/controller.go index 5822f0d57..3a65a1a99 100644 --- a/internal/ingress/metric/collectors/controller.go +++ b/internal/ingress/metric/collectors/controller.go @@ -32,6 +32,7 @@ var ( ingressOperation = []string{"controller_namespace", "controller_class", "controller_pod", "namespace", "ingress"} sslLabelHost = []string{"namespace", "class", "host", "secret_name"} sslInfoLabels = []string{"namespace", "class", "host", "secret_name", "identifier", "issuer_organization", "issuer_common_name", "serial_number", "public_key_algorithm"} + orphanityLabels = []string{"controller_namespace", "controller_class", "controller_pod", "namespace", "ingress", "type"} ) // Controller defines base metrics about the ingress controller @@ -48,6 +49,7 @@ type Controller struct { checkIngressOperationErrors *prometheus.CounterVec sslExpireTime *prometheus.GaugeVec sslInfo *prometheus.GaugeVec + OrphanIngress *prometheus.GaugeVec constLabels prometheus.Labels labels prometheus.Labels @@ -171,6 +173,15 @@ func NewController(pod, namespace, class string) *Controller { }, []string{"name"}, ), + OrphanIngress: prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: PrometheusNamespace, + Name: "orphan_ingress", + Help: `Gauge reporting status of ingress orphanity, 1 indicates orphaned ingress. + 'namespace' is the string used to identify namespace of ingress, 'ingress' for ingress name and 'type' for 'no-service' or 'no-endpoint' of orphanity`, + }, + orphanityLabels, + ), } return cm @@ -214,6 +225,26 @@ func (cm *Controller) IncCheckErrorCount(namespace, name string) { cm.checkIngressOperationErrors.MustCurryWith(cm.constLabels).With(labels).Inc() } +// IncOrphanIngress sets the the orphaned ingress gauge to one +func (cm *Controller) IncOrphanIngress(namespace string, name string, orphanityType string) { + labels := prometheus.Labels{ + "namespace": namespace, + "ingress": name, + "type": orphanityType, + } + cm.OrphanIngress.MustCurryWith(cm.constLabels).With(labels).Set(1.0) +} + +// DecOrphanIngress sets the the orphaned ingress gauge to zero (all services has their endpoints) +func (cm *Controller) DecOrphanIngress(namespace string, name string, orphanityType string) { + labels := prometheus.Labels{ + "namespace": namespace, + "ingress": name, + "type": orphanityType, + } + cm.OrphanIngress.MustCurryWith(cm.constLabels).With(labels).Set(0.0) +} + // ConfigSuccess set a boolean flag according to the output of the controller configuration reload func (cm *Controller) ConfigSuccess(hash uint64, success bool) { if success { @@ -242,6 +273,7 @@ func (cm Controller) Describe(ch chan<- *prometheus.Desc) { cm.sslInfo.Describe(ch) cm.leaderElection.Describe(ch) cm.buildInfo.Describe(ch) + cm.OrphanIngress.Describe(ch) } // Collect implements the prometheus.Collector interface. @@ -257,6 +289,7 @@ func (cm Controller) Collect(ch chan<- prometheus.Metric) { cm.sslInfo.Collect(ch) cm.leaderElection.Collect(ch) cm.buildInfo.Collect(ch) + cm.OrphanIngress.Collect(ch) } // SetSSLExpireTime sets the expiration time of SSL Certificates diff --git a/internal/ingress/metric/collectors/socket.go b/internal/ingress/metric/collectors/socket.go index 9c0376cd3..508cc6bc8 100644 --- a/internal/ingress/metric/collectors/socket.go +++ b/internal/ingress/metric/collectors/socket.go @@ -21,6 +21,7 @@ import ( "io" "net" "os" + "strings" "syscall" jsoniter "github.com/json-iterator/go" @@ -60,6 +61,8 @@ type HistogramBuckets struct { SizeBuckets []float64 } +type metricMapping map[string]prometheus.Collector + // SocketCollector stores prometheus metrics and ingress meta-data type SocketCollector struct { prometheus.Collector @@ -78,9 +81,9 @@ type SocketCollector struct { listener net.Listener - metricMapping map[string]interface{} + metricMapping metricMapping - hosts sets.String + hosts sets.Set[string] metricsPerHost bool reportStatusClasses bool @@ -106,7 +109,7 @@ var defObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001} // NewSocketCollector creates a new SocketCollector instance using // the ingress watch namespace and class used by the controller -func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStatusClasses bool, buckets HistogramBuckets) (*SocketCollector, error) { +func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStatusClasses bool, buckets HistogramBuckets, excludeMetrics []string) (*SocketCollector, error) { socket := "/tmp/nginx/prometheus-nginx.socket" // unix sockets must be unlink()ed before being used _ = syscall.Unlink(socket) @@ -132,13 +135,23 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat requestTags = append(requestTags, "host") } + em := make(map[string]struct{}, len(excludeMetrics)) + for _, m := range excludeMetrics { + // remove potential nginx_ingress_controller prefix from the metric name + // TBD: how to handle fully qualified histogram metrics e.g. _buckets and _sum. Should we just remove the suffix and remove the histogram metric or ignore it? + em[strings.TrimPrefix(m, "nginx_ingress_controller_")] = struct{}{} + } + + // create metric mapping with only the metrics that are not excluded + mm := make(metricMapping) + sc := &SocketCollector{ listener: listener, metricsPerHost: metricsPerHost, reportStatusClasses: reportStatusClasses, - connectTime: prometheus.NewHistogramVec( + connectTime: histogramMetric( prometheus.HistogramOpts{ Name: "connect_duration_seconds", Help: "The time spent on establishing a connection with the upstream server", @@ -147,8 +160,11 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat Buckets: buckets.TimeBuckets, }, requestTags, + em, + mm, ), - headerTime: prometheus.NewHistogramVec( + + headerTime: histogramMetric( prometheus.HistogramOpts{ Name: "header_duration_seconds", Help: "The time spent on receiving first header from the upstream server", @@ -157,8 +173,10 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat Buckets: buckets.TimeBuckets, }, requestTags, + em, + mm, ), - responseTime: prometheus.NewHistogramVec( + responseTime: histogramMetric( prometheus.HistogramOpts{ Name: "response_duration_seconds", Help: "The time spent on receiving the response from the upstream server", @@ -167,8 +185,11 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat Buckets: buckets.TimeBuckets, }, requestTags, + em, + mm, ), - requestTime: prometheus.NewHistogramVec( + + requestTime: histogramMetric( prometheus.HistogramOpts{ Name: "request_duration_seconds", Help: "The request processing time in milliseconds", @@ -177,9 +198,11 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat Buckets: buckets.TimeBuckets, }, requestTags, + em, + mm, ), - responseLength: prometheus.NewHistogramVec( + responseLength: histogramMetric( prometheus.HistogramOpts{ Name: "response_size", Help: "The response length (including request line, header, and request body)", @@ -188,19 +211,24 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat Buckets: buckets.LengthBuckets, }, requestTags, + em, + mm, ), - requestLength: prometheus.NewHistogramVec( + + requestLength: histogramMetric( prometheus.HistogramOpts{ Name: "request_size", Help: "The request length (including request line, header, and request body)", Namespace: PrometheusNamespace, - Buckets: buckets.LengthBuckets, ConstLabels: constLabels, + Buckets: buckets.LengthBuckets, }, requestTags, + em, + mm, ), - requests: prometheus.NewCounterVec( + requests: counterMetric( prometheus.CounterOpts{ Name: "requests", Help: "The total number of client requests", @@ -208,9 +236,11 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat ConstLabels: constLabels, }, requestTags, + em, + mm, ), - bytesSent: prometheus.NewHistogramVec( + bytesSent: histogramMetric( prometheus.HistogramOpts{ Name: "bytes_sent", Help: "DEPRECATED The number of bytes sent to a client", @@ -219,9 +249,11 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat ConstLabels: constLabels, }, requestTags, + em, + mm, ), - upstreamLatency: prometheus.NewSummaryVec( + upstreamLatency: summaryMetric( prometheus.SummaryOpts{ Name: "ingress_upstream_latency_seconds", Help: "DEPRECATED Upstream service latency per Ingress", @@ -230,28 +262,59 @@ func NewSocketCollector(pod, namespace, class string, metricsPerHost, reportStat Objectives: defObjectives, }, []string{"ingress", "namespace", "service", "canary"}, + em, + mm, ), } - sc.metricMapping = map[string]interface{}{ - prometheus.BuildFQName(PrometheusNamespace, "", "requests"): sc.requests, - - prometheus.BuildFQName(PrometheusNamespace, "", "connect_duration_seconds"): sc.connectTime, - prometheus.BuildFQName(PrometheusNamespace, "", "header_duration_seconds"): sc.headerTime, - prometheus.BuildFQName(PrometheusNamespace, "", "response_duration_seconds"): sc.responseTime, - prometheus.BuildFQName(PrometheusNamespace, "", "request_duration_seconds"): sc.requestTime, - - prometheus.BuildFQName(PrometheusNamespace, "", "request_size"): sc.requestLength, - prometheus.BuildFQName(PrometheusNamespace, "", "response_size"): sc.responseLength, - - prometheus.BuildFQName(PrometheusNamespace, "", "bytes_sent"): sc.bytesSent, - - prometheus.BuildFQName(PrometheusNamespace, "", "ingress_upstream_latency_seconds"): sc.upstreamLatency, - } - + sc.metricMapping = mm return sc, nil } +func containsMetric(excludeMetrics map[string]struct{}, name string) bool { + if _, ok := excludeMetrics[name]; ok { + klog.V(3).InfoS("Skipping metric", "metric", name) + return true + } + return false +} + +func summaryMetric(opts prometheus.SummaryOpts, requestTags []string, excludeMetrics map[string]struct{}, metricMapping metricMapping) *prometheus.SummaryVec { + if containsMetric(excludeMetrics, opts.Name) { + return nil + } + m := prometheus.NewSummaryVec( + opts, + requestTags, + ) + metricMapping[prometheus.BuildFQName(PrometheusNamespace, "", opts.Name)] = m + return m +} + +func counterMetric(opts prometheus.CounterOpts, requestTags []string, excludeMetrics map[string]struct{}, metricMapping metricMapping) *prometheus.CounterVec { + if containsMetric(excludeMetrics, opts.Name) { + return nil + } + m := prometheus.NewCounterVec( + opts, + requestTags, + ) + metricMapping[prometheus.BuildFQName(PrometheusNamespace, "", opts.Name)] = m + return m +} + +func histogramMetric(opts prometheus.HistogramOpts, requestTags []string, excludeMetrics map[string]struct{}, metricMapping metricMapping) *prometheus.HistogramVec { + if containsMetric(excludeMetrics, opts.Name) { + return nil + } + m := prometheus.NewHistogramVec( + opts, + requestTags, + ) + metricMapping[prometheus.BuildFQName(PrometheusNamespace, "", opts.Name)] = m + return m +} + func (sc *SocketCollector) handleMessage(msg []byte) { klog.V(5).InfoS("Metric", "message", string(msg)) @@ -305,30 +368,36 @@ func (sc *SocketCollector) handleMessage(msg []byte) { "canary": stats.Canary, } - requestsMetric, err := sc.requests.GetMetricWith(collectorLabels) - if err != nil { - klog.ErrorS(err, "Error fetching requests metric") - } else { - requestsMetric.Inc() + if sc.requests != nil { + requestsMetric, err := sc.requests.GetMetricWith(collectorLabels) + if err != nil { + klog.ErrorS(err, "Error fetching requests metric") + } else { + requestsMetric.Inc() + } } if stats.Latency != -1 { - connectTimeMetric, err := sc.connectTime.GetMetricWith(requestLabels) - if err != nil { - klog.ErrorS(err, "Error fetching connect time metric") - } else { - connectTimeMetric.Observe(stats.Latency) + if sc.connectTime != nil { + connectTimeMetric, err := sc.connectTime.GetMetricWith(requestLabels) + if err != nil { + klog.ErrorS(err, "Error fetching connect time metric") + } else { + connectTimeMetric.Observe(stats.Latency) + } } - latencyMetric, err := sc.upstreamLatency.GetMetricWith(latencyLabels) - if err != nil { - klog.ErrorS(err, "Error fetching latency metric") - } else { - latencyMetric.Observe(stats.Latency) + if sc.upstreamLatency != nil { + latencyMetric, err := sc.upstreamLatency.GetMetricWith(latencyLabels) + if err != nil { + klog.ErrorS(err, "Error fetching latency metric") + } else { + latencyMetric.Observe(stats.Latency) + } } } - if stats.HeaderTime != -1 { + if stats.HeaderTime != -1 && sc.headerTime != nil { headerTimeMetric, err := sc.headerTime.GetMetricWith(requestLabels) if err != nil { klog.ErrorS(err, "Error fetching header time metric") @@ -337,7 +406,7 @@ func (sc *SocketCollector) handleMessage(msg []byte) { } } - if stats.RequestTime != -1 { + if stats.RequestTime != -1 && sc.requestTime != nil { requestTimeMetric, err := sc.requestTime.GetMetricWith(requestLabels) if err != nil { klog.ErrorS(err, "Error fetching request duration metric") @@ -346,7 +415,7 @@ func (sc *SocketCollector) handleMessage(msg []byte) { } } - if stats.RequestLength != -1 { + if stats.RequestLength != -1 && sc.requestLength != nil { requestLengthMetric, err := sc.requestLength.GetMetricWith(requestLabels) if err != nil { klog.ErrorS(err, "Error fetching request length metric") @@ -355,7 +424,7 @@ func (sc *SocketCollector) handleMessage(msg []byte) { } } - if stats.ResponseTime != -1 { + if stats.ResponseTime != -1 && sc.responseTime != nil { responseTimeMetric, err := sc.responseTime.GetMetricWith(requestLabels) if err != nil { klog.ErrorS(err, "Error fetching upstream response time metric") @@ -365,18 +434,22 @@ func (sc *SocketCollector) handleMessage(msg []byte) { } if stats.ResponseLength != -1 { - bytesSentMetric, err := sc.bytesSent.GetMetricWith(requestLabels) - if err != nil { - klog.ErrorS(err, "Error fetching bytes sent metric") - } else { - bytesSentMetric.Observe(stats.ResponseLength) + if sc.bytesSent != nil { + bytesSentMetric, err := sc.bytesSent.GetMetricWith(requestLabels) + if err != nil { + klog.ErrorS(err, "Error fetching bytes sent metric") + } else { + bytesSentMetric.Observe(stats.ResponseLength) + } } - responseSizeMetric, err := sc.responseLength.GetMetricWith(requestLabels) - if err != nil { - klog.ErrorS(err, "Error fetching bytes sent metric") - } else { - responseSizeMetric.Observe(stats.ResponseLength) + if sc.responseLength != nil { + responseSizeMetric, err := sc.responseLength.GetMetricWith(requestLabels) + if err != nil { + klog.ErrorS(err, "Error fetching bytes sent metric") + } else { + responseSizeMetric.Observe(stats.ResponseLength) + } } } } @@ -471,41 +544,21 @@ func (sc *SocketCollector) RemoveMetrics(ingresses []string, registry prometheus // Describe implements prometheus.Collector func (sc SocketCollector) Describe(ch chan<- *prometheus.Desc) { - sc.connectTime.Describe(ch) - sc.headerTime.Describe(ch) - sc.responseTime.Describe(ch) - sc.requestTime.Describe(ch) - - sc.requestLength.Describe(ch) - sc.responseLength.Describe(ch) - - sc.requests.Describe(ch) - - sc.upstreamLatency.Describe(ch) - - sc.bytesSent.Describe(ch) + for _, metric := range sc.metricMapping { + metric.Describe(ch) + } } // Collect implements the prometheus.Collector interface. func (sc SocketCollector) Collect(ch chan<- prometheus.Metric) { - sc.connectTime.Collect(ch) - sc.headerTime.Collect(ch) - sc.responseTime.Collect(ch) - sc.requestTime.Collect(ch) - - sc.requestLength.Collect(ch) - sc.responseLength.Collect(ch) - - sc.requests.Collect(ch) - - sc.upstreamLatency.Collect(ch) - - sc.bytesSent.Collect(ch) + for _, metric := range sc.metricMapping { + metric.Collect(ch) + } } // SetHosts sets the hostnames that are being served by the ingress controller // This set of hostnames is used to filter the metrics to be exposed -func (sc *SocketCollector) SetHosts(hosts sets.String) { +func (sc *SocketCollector) SetHosts(hosts sets.Set[string]) { sc.hosts = hosts } diff --git a/internal/ingress/metric/collectors/socket_test.go b/internal/ingress/metric/collectors/socket_test.go index f175828cc..fe442aba0 100644 --- a/internal/ingress/metric/collectors/socket_test.go +++ b/internal/ingress/metric/collectors/socket_test.go @@ -84,6 +84,7 @@ func TestCollector(t *testing.T) { data []string metrics []string useStatusClasses bool + excludeMetrics []string wantBefore string removeIngresses []string wantAfter string @@ -470,13 +471,126 @@ func TestCollector(t *testing.T) { wantAfter: ` `, }, + { + name: "basic exclude metrics test", + data: []string{`[{ + "host":"testshop.com", + "status":"200", + "bytesSent":150.0, + "method":"GET", + "path":"/admin", + "requestLength":300.0, + "requestTime":60.0, + "upstreamLatency":1.0, + "upstreamHeaderTime":5.0, + "upstreamName":"test-upstream", + "upstreamIP":"1.1.1.1:8080", + "upstreamResponseTime":200, + "upstreamStatus":"220", + "namespace":"test-app-production", + "ingress":"web-yml", + "service":"test-app", + "canary":"" + }]`}, + excludeMetrics: []string{"nginx_ingress_controller_connect_duration_seconds"}, + metrics: []string{"nginx_ingress_controller_connect_duration_seconds", "nginx_ingress_controller_response_duration_seconds"}, + useStatusClasses: true, + wantBefore: ` + # HELP nginx_ingress_controller_response_duration_seconds The time spent on receiving the response from the upstream server + # TYPE nginx_ingress_controller_response_duration_seconds histogram + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.005"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.01"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.025"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.05"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.1"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.25"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.5"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="1"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="2.5"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="5"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="10"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="+Inf"} 1 + nginx_ingress_controller_response_duration_seconds_sum{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx"} 200 + nginx_ingress_controller_response_duration_seconds_count{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx"} 1 + `, + }, + { + name: "remove metrics with the short metric name", + data: []string{`[{ + "host":"testshop.com", + "status":"200", + "bytesSent":150.0, + "method":"GET", + "path":"/admin", + "requestLength":300.0, + "requestTime":60.0, + "upstreamLatency":1.0, + "upstreamHeaderTime":5.0, + "upstreamName":"test-upstream", + "upstreamIP":"1.1.1.1:8080", + "upstreamResponseTime":200, + "upstreamStatus":"220", + "namespace":"test-app-production", + "ingress":"web-yml", + "service":"test-app", + "canary":"" + }]`}, + excludeMetrics: []string{"response_duration_seconds"}, + metrics: []string{"nginx_ingress_controller_response_duration_seconds"}, + useStatusClasses: true, + wantBefore: ` + `, + }, + { + name: "exclude metrics make sure to only remove exactly matched metrics", + data: []string{`[{ + "host":"testshop.com", + "status":"200", + "bytesSent":150.0, + "method":"GET", + "path":"/admin", + "requestLength":300.0, + "requestTime":60.0, + "upstreamLatency":1.0, + "upstreamHeaderTime":5.0, + "upstreamName":"test-upstream", + "upstreamIP":"1.1.1.1:8080", + "upstreamResponseTime":200, + "upstreamStatus":"220", + "namespace":"test-app-production", + "ingress":"web-yml", + "service":"test-app", + "canary":"" + }]`}, + excludeMetrics: []string{"response_duration_seconds2", "test.*", "nginx_ingress_.*", "response_duration_secon"}, + metrics: []string{"nginx_ingress_controller_response_duration_seconds"}, + useStatusClasses: true, + wantBefore: ` + # HELP nginx_ingress_controller_response_duration_seconds The time spent on receiving the response from the upstream server + # TYPE nginx_ingress_controller_response_duration_seconds histogram + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.005"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.01"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.025"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.05"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.1"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.25"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="0.5"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="1"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="2.5"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="5"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="10"} 0 + nginx_ingress_controller_response_duration_seconds_bucket{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx",le="+Inf"} 1 + nginx_ingress_controller_response_duration_seconds_sum{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx"} 200 + nginx_ingress_controller_response_duration_seconds_count{canary="",controller_class="ingress",controller_namespace="default",controller_pod="pod",host="testshop.com",ingress="web-yml",method="GET",namespace="test-app-production",path="/admin",service="test-app",status="2xx"} 1 + `, + }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { registry := prometheus.NewPedanticRegistry() - sc, err := NewSocketCollector("pod", "default", "ingress", true, c.useStatusClasses, buckets) + sc, err := NewSocketCollector("pod", "default", "ingress", true, c.useStatusClasses, buckets, c.excludeMetrics) if err != nil { t.Errorf("%v: unexpected error creating new SocketCollector: %v", c.name, err) } @@ -485,7 +599,7 @@ func TestCollector(t *testing.T) { t.Errorf("registering collector failed: %s", err) } - sc.SetHosts(sets.NewString("testshop.com")) + sc.SetHosts(sets.New[string]("testshop.com")) for _, d := range c.data { sc.handleMessage([]byte(d)) diff --git a/internal/ingress/metric/dummy.go b/internal/ingress/metric/dummy.go index 4a6366b84..d8ae0155a 100644 --- a/internal/ingress/metric/dummy.go +++ b/internal/ingress/metric/dummy.go @@ -41,6 +41,12 @@ func (dc DummyCollector) IncReloadCount() {} // IncReloadErrorCount ... func (dc DummyCollector) IncReloadErrorCount() {} +// IncOrphanIngress ... +func (dc DummyCollector) IncOrphanIngress(string, string, string) {} + +// DecOrphanIngress ... +func (dc DummyCollector) DecOrphanIngress(string, string, string) {} + // IncCheckCount ... func (dc DummyCollector) IncCheckCount(string, string) {} @@ -63,7 +69,7 @@ func (dc DummyCollector) SetSSLInfo([]*ingress.Server) {} func (dc DummyCollector) SetSSLExpireTime([]*ingress.Server) {} // SetHosts ... -func (dc DummyCollector) SetHosts(hosts sets.String) {} +func (dc DummyCollector) SetHosts(hosts sets.Set[string]) {} // OnStartedLeading indicates the pod is not the current leader func (dc DummyCollector) OnStartedLeading(electionID string) {} diff --git a/internal/ingress/metric/main.go b/internal/ingress/metric/main.go index b3323c7fe..b2f721f62 100644 --- a/internal/ingress/metric/main.go +++ b/internal/ingress/metric/main.go @@ -43,6 +43,8 @@ type Collector interface { IncCheckCount(string, string) IncCheckErrorCount(string, string) + IncOrphanIngress(string, string, string) + DecOrphanIngress(string, string, string) RemoveMetrics(ingresses, endpoints, certificates []string) @@ -50,7 +52,7 @@ type Collector interface { SetSSLInfo(servers []*ingress.Server) // SetHosts sets the hostnames that are being served by the ingress controller - SetHosts(sets.String) + SetHosts(set sets.Set[string]) Start(string) Stop(string) @@ -69,7 +71,7 @@ type collector struct { } // NewCollector creates a new metric collector the for ingress controller -func NewCollector(metricsPerHost, reportStatusClasses bool, registry *prometheus.Registry, ingressclass string, buckets collectors.HistogramBuckets) (Collector, error) { +func NewCollector(metricsPerHost, reportStatusClasses bool, registry *prometheus.Registry, ingressclass string, buckets collectors.HistogramBuckets, excludedSocketMetrics []string) (Collector, error) { podNamespace := os.Getenv("POD_NAMESPACE") if podNamespace == "" { podNamespace = "default" @@ -87,7 +89,7 @@ func NewCollector(metricsPerHost, reportStatusClasses bool, registry *prometheus return nil, err } - s, err := collectors.NewSocketCollector(podName, podNamespace, ingressclass, metricsPerHost, reportStatusClasses, buckets) + s, err := collectors.NewSocketCollector(podName, podNamespace, ingressclass, metricsPerHost, reportStatusClasses, buckets, excludedSocketMetrics) if err != nil { return nil, err } @@ -181,7 +183,15 @@ func (c *collector) SetSSLInfo(servers []*ingress.Server) { c.ingressController.SetSSLInfo(servers) } -func (c *collector) SetHosts(hosts sets.String) { +func (c *collector) IncOrphanIngress(namespace string, name string, orphanityType string) { + c.ingressController.IncOrphanIngress(namespace, name, orphanityType) +} + +func (c *collector) DecOrphanIngress(namespace string, name string, orphanityType string) { + c.ingressController.DecOrphanIngress(namespace, name, orphanityType) +} + +func (c *collector) SetHosts(hosts sets.Set[string]) { c.socket.SetHosts(hosts) } diff --git a/internal/ingress/status/status.go b/internal/ingress/status/status.go index 2e53682a0..a7506705c 100644 --- a/internal/ingress/status/status.go +++ b/internal/ingress/status/status.go @@ -29,6 +29,7 @@ import ( pool "gopkg.in/go-playground/pool.v3" apiv1 "k8s.io/api/core/v1" + v1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/wait" @@ -128,7 +129,7 @@ func (s statusSync) Shutdown() { } klog.InfoS("removing value from ingress status", "address", addrs) - s.updateStatus([]apiv1.LoadBalancerIngress{}) + s.updateStatus([]v1.IngressLoadBalancerIngress{}) } func (s *statusSync) sync(key interface{}) error { @@ -160,21 +161,21 @@ func NewStatusSyncer(config Config) Syncer { return st } -func nameOrIPToLoadBalancerIngress(nameOrIP string) apiv1.LoadBalancerIngress { +func nameOrIPToLoadBalancerIngress(nameOrIP string) v1.IngressLoadBalancerIngress { if net.ParseIP(nameOrIP) != nil { - return apiv1.LoadBalancerIngress{IP: nameOrIP} + return v1.IngressLoadBalancerIngress{IP: nameOrIP} } - return apiv1.LoadBalancerIngress{Hostname: nameOrIP} + return v1.IngressLoadBalancerIngress{Hostname: nameOrIP} } // runningAddresses returns a list of IP addresses and/or FQDN where the // ingress controller is currently running -func (s *statusSync) runningAddresses() ([]apiv1.LoadBalancerIngress, error) { +func (s *statusSync) runningAddresses() ([]v1.IngressLoadBalancerIngress, error) { if s.PublishStatusAddress != "" { re := regexp.MustCompile(`,\s*`) multipleAddrs := re.Split(s.PublishStatusAddress, -1) - addrs := make([]apiv1.LoadBalancerIngress, len(multipleAddrs)) + addrs := make([]v1.IngressLoadBalancerIngress, len(multipleAddrs)) for i, addr := range multipleAddrs { addrs[i] = nameOrIPToLoadBalancerIngress(addr) } @@ -193,7 +194,7 @@ func (s *statusSync) runningAddresses() ([]apiv1.LoadBalancerIngress, error) { return nil, err } - addrs := make([]apiv1.LoadBalancerIngress, 0) + addrs := make([]v1.IngressLoadBalancerIngress, 0) for i := range pods.Items { pod := pods.Items[i] // only Running pods are valid @@ -250,7 +251,7 @@ func (s *statusSync) isRunningMultiplePods() bool { // standardizeLoadBalancerIngresses sorts the list of loadbalancer by // IP -func standardizeLoadBalancerIngresses(lbi []apiv1.LoadBalancerIngress) []apiv1.LoadBalancerIngress { +func standardizeLoadBalancerIngresses(lbi []v1.IngressLoadBalancerIngress) []v1.IngressLoadBalancerIngress { sort.SliceStable(lbi, func(a, b int) bool { return lbi[a].IP < lbi[b].IP }) @@ -259,7 +260,7 @@ func standardizeLoadBalancerIngresses(lbi []apiv1.LoadBalancerIngress) []apiv1.L } // updateStatus changes the status information of Ingress rules -func (s *statusSync) updateStatus(newIngressPoint []apiv1.LoadBalancerIngress) { +func (s *statusSync) updateStatus(newIngressPoint []v1.IngressLoadBalancerIngress) { ings := s.IngressLister.ListIngresses() p := pool.NewLimited(10) @@ -283,7 +284,7 @@ func (s *statusSync) updateStatus(newIngressPoint []apiv1.LoadBalancerIngress) { batch.WaitAll() } -func runUpdate(ing *ingress.Ingress, status []apiv1.LoadBalancerIngress, +func runUpdate(ing *ingress.Ingress, status []v1.IngressLoadBalancerIngress, client clientset.Interface) pool.WorkFunc { return func(wu pool.WorkUnit) (interface{}, error) { if wu.IsCancelled() { @@ -307,7 +308,7 @@ func runUpdate(ing *ingress.Ingress, status []apiv1.LoadBalancerIngress, } } -func lessLoadBalancerIngress(addrs []apiv1.LoadBalancerIngress) func(int, int) bool { +func lessLoadBalancerIngress(addrs []v1.IngressLoadBalancerIngress) func(int, int) bool { return func(a, b int) bool { switch strings.Compare(addrs[a].Hostname, addrs[b].Hostname) { case -1: @@ -319,7 +320,7 @@ func lessLoadBalancerIngress(addrs []apiv1.LoadBalancerIngress) func(int, int) b } } -func ingressSliceEqual(lhs, rhs []apiv1.LoadBalancerIngress) bool { +func ingressSliceEqual(lhs, rhs []v1.IngressLoadBalancerIngress) bool { if len(lhs) != len(rhs) { return false } @@ -336,7 +337,7 @@ func ingressSliceEqual(lhs, rhs []apiv1.LoadBalancerIngress) bool { return true } -func statusAddressFromService(service string, kubeClient clientset.Interface) ([]apiv1.LoadBalancerIngress, error) { +func statusAddressFromService(service string, kubeClient clientset.Interface) ([]v1.IngressLoadBalancerIngress, error) { ns, name, _ := k8s.ParseNameNS(service) svc, err := kubeClient.CoreV1().Services(ns).Get(context.TODO(), name, metav1.GetOptions{}) if err != nil { @@ -345,28 +346,28 @@ func statusAddressFromService(service string, kubeClient clientset.Interface) ([ switch svc.Spec.Type { case apiv1.ServiceTypeExternalName: - return []apiv1.LoadBalancerIngress{{ + return []v1.IngressLoadBalancerIngress{{ Hostname: svc.Spec.ExternalName, }}, nil case apiv1.ServiceTypeClusterIP: - return []apiv1.LoadBalancerIngress{{ + return []v1.IngressLoadBalancerIngress{{ IP: svc.Spec.ClusterIP, }}, nil case apiv1.ServiceTypeNodePort: if svc.Spec.ExternalIPs == nil { - return []apiv1.LoadBalancerIngress{{ + return []v1.IngressLoadBalancerIngress{{ IP: svc.Spec.ClusterIP, }}, nil } - addrs := make([]apiv1.LoadBalancerIngress, len(svc.Spec.ExternalIPs)) + addrs := make([]v1.IngressLoadBalancerIngress, len(svc.Spec.ExternalIPs)) for i, ip := range svc.Spec.ExternalIPs { - addrs[i] = apiv1.LoadBalancerIngress{IP: ip} + addrs[i] = v1.IngressLoadBalancerIngress{IP: ip} } return addrs, nil case apiv1.ServiceTypeLoadBalancer: - addrs := make([]apiv1.LoadBalancerIngress, len(svc.Status.LoadBalancer.Ingress)) + addrs := make([]v1.IngressLoadBalancerIngress, len(svc.Status.LoadBalancer.Ingress)) for i, ingress := range svc.Status.LoadBalancer.Ingress { - addrs[i] = apiv1.LoadBalancerIngress{} + addrs[i] = v1.IngressLoadBalancerIngress{} if ingress.Hostname != "" { addrs[i].Hostname = ingress.Hostname } @@ -376,7 +377,7 @@ func statusAddressFromService(service string, kubeClient clientset.Interface) ([ } for _, ip := range svc.Spec.ExternalIPs { if !stringInIngresses(ip, addrs) { - addrs = append(addrs, apiv1.LoadBalancerIngress{IP: ip}) + addrs = append(addrs, v1.IngressLoadBalancerIngress{IP: ip}) } } return addrs, nil @@ -386,7 +387,7 @@ func statusAddressFromService(service string, kubeClient clientset.Interface) ([ } // stringInSlice returns true if s is in list -func stringInIngresses(s string, list []apiv1.LoadBalancerIngress) bool { +func stringInIngresses(s string, list []v1.IngressLoadBalancerIngress) bool { for _, v := range list { if v.IP == s || v.Hostname == s { return true diff --git a/internal/ingress/status/status_test.go b/internal/ingress/status/status_test.go index d4ef09e7c..3dd56f37d 100644 --- a/internal/ingress/status/status_test.go +++ b/internal/ingress/status/status_test.go @@ -34,8 +34,8 @@ import ( "k8s.io/ingress-nginx/pkg/apis/ingress" ) -func buildLoadBalancerIngressByIP() []apiv1.LoadBalancerIngress { - return []apiv1.LoadBalancerIngress{ +func buildLoadBalancerIngressByIP() []networking.IngressLoadBalancerIngress { + return []networking.IngressLoadBalancerIngress{ { IP: "10.0.0.1", Hostname: "foo1", @@ -123,17 +123,20 @@ func buildSimpleClientSet() *testclient.Clientset { }, }}, &apiv1.ServiceList{Items: []apiv1.Service{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - Namespace: apiv1.NamespaceDefault, - }, - Status: apiv1.ServiceStatus{ - LoadBalancer: apiv1.LoadBalancerStatus{ - Ingress: buildLoadBalancerIngressByIP(), - }, - }, - }, + // This is commented out as the ServiceStatus.LoadBalancer field expects a LoadBalancerStatus object + // which is incompatible with the current Ingress struct which expects a IngressLoadBalancerStatus object + // TODO: update this service when the ServiceStatus struct gets updated + //{ + // ObjectMeta: metav1.ObjectMeta{ + // Name: "foo", + // Namespace: apiv1.NamespaceDefault, + // }, + // Status: apiv1.ServiceStatus{ + // LoadBalancer: apiv1.LoadBalancerStatus{ + // Ingress: buildLoadBalancerIngressByIP(), + // }, + // }, + //}, { ObjectMeta: metav1.ObjectMeta{ Name: "foo_non_exist", @@ -199,8 +202,8 @@ func buildExtensionsIngresses() []networking.Ingress { Namespace: apiv1.NamespaceDefault, }, Status: networking.IngressStatus{ - LoadBalancer: apiv1.LoadBalancerStatus{ - Ingress: []apiv1.LoadBalancerIngress{ + LoadBalancer: networking.IngressLoadBalancerStatus{ + Ingress: []networking.IngressLoadBalancerIngress{ { IP: "10.0.0.1", Hostname: "foo1", @@ -218,8 +221,8 @@ func buildExtensionsIngresses() []networking.Ingress { }, }, Status: networking.IngressStatus{ - LoadBalancer: apiv1.LoadBalancerStatus{ - Ingress: []apiv1.LoadBalancerIngress{ + LoadBalancer: networking.IngressLoadBalancerStatus{ + Ingress: []networking.IngressLoadBalancerIngress{ { IP: "0.0.0.0", Hostname: "foo.bar.com", @@ -234,8 +237,8 @@ func buildExtensionsIngresses() []networking.Ingress { Namespace: apiv1.NamespaceDefault, }, Status: networking.IngressStatus{ - LoadBalancer: apiv1.LoadBalancerStatus{ - Ingress: []apiv1.LoadBalancerIngress{}, + LoadBalancer: networking.IngressLoadBalancerStatus{ + Ingress: []networking.IngressLoadBalancerIngress{}, }, }, }, @@ -261,7 +264,7 @@ func (til *testIngressLister) ListIngresses() []*ingress.Ingress { Namespace: apiv1.NamespaceDefault, }, Status: networking.IngressStatus{ - LoadBalancer: apiv1.LoadBalancerStatus{ + LoadBalancer: networking.IngressLoadBalancerStatus{ Ingress: buildLoadBalancerIngressByIP(), }, }, @@ -325,7 +328,7 @@ func TestStatusActions(t *testing.T) { fk.sync("just-test") // PublishService is empty, so the running address is: ["11.0.0.2"] // after updated, the ingress's ip should only be "11.0.0.2" - newIPs := []apiv1.LoadBalancerIngress{{ + newIPs := []networking.IngressLoadBalancerIngress{{ IP: "11.0.0.2", }} fooIngress1, err1 := fk.Client.NetworkingV1().Ingresses(apiv1.NamespaceDefault).Get(context.TODO(), "foo_ingress_1", metav1.GetOptions{}) @@ -342,7 +345,7 @@ func TestStatusActions(t *testing.T) { // execute shutdown fk.Shutdown() // ingress should be empty - newIPs2 := []apiv1.LoadBalancerIngress{} + var newIPs2 []networking.IngressLoadBalancerIngress fooIngress2, err2 := fk.Client.NetworkingV1().Ingresses(apiv1.NamespaceDefault).Get(context.TODO(), "foo_ingress_1", metav1.GetOptions{}) if err2 != nil { t.Fatalf("unexpected error") @@ -382,7 +385,7 @@ func TestKeyfunc(t *testing.T) { func TestRunningAddressesWithPublishService(t *testing.T) { testCases := map[string]struct { fakeClient *testclient.Clientset - expected []apiv1.LoadBalancerIngress + expected []networking.IngressLoadBalancerIngress errExpected bool }{ "service type ClusterIP": { @@ -416,7 +419,7 @@ func TestRunningAddressesWithPublishService(t *testing.T) { }, }, ), - []apiv1.LoadBalancerIngress{ + []networking.IngressLoadBalancerIngress{ {IP: "1.1.1.1"}, }, false, @@ -437,7 +440,7 @@ func TestRunningAddressesWithPublishService(t *testing.T) { }, }, ), - []apiv1.LoadBalancerIngress{ + []networking.IngressLoadBalancerIngress{ {IP: "1.1.1.1"}, }, false, @@ -458,7 +461,7 @@ func TestRunningAddressesWithPublishService(t *testing.T) { }, }, ), - []apiv1.LoadBalancerIngress{ + []networking.IngressLoadBalancerIngress{ {Hostname: "foo.bar"}, }, false, @@ -495,7 +498,7 @@ func TestRunningAddressesWithPublishService(t *testing.T) { }, }, ), - []apiv1.LoadBalancerIngress{ + []networking.IngressLoadBalancerIngress{ {IP: "10.0.0.1"}, {Hostname: "foo"}, { @@ -530,7 +533,7 @@ func TestRunningAddressesWithPublishService(t *testing.T) { }, }, ), - []apiv1.LoadBalancerIngress{ + []networking.IngressLoadBalancerIngress{ {IP: "10.0.0.1"}, }, false, @@ -568,7 +571,7 @@ func TestRunningAddressesWithPublishService(t *testing.T) { } if ra == nil { - t.Fatalf("returned nil but expected valid []apiv1.LoadBalancerIngress") + t.Fatalf("returned nil but expected valid []networking.IngressLoadBalancerIngress") } if !reflect.DeepEqual(tc.expected, ra) { @@ -584,7 +587,7 @@ func TestRunningAddressesWithPods(t *testing.T) { r, _ := fk.runningAddresses() if r == nil { - t.Fatalf("returned nil but expected valid []apiv1.LoadBalancerIngress") + t.Fatalf("returned nil but expected valid []networking.IngressLoadBalancerIngress") } rl := len(r) if len(r) != 1 { @@ -592,7 +595,7 @@ func TestRunningAddressesWithPods(t *testing.T) { } rv := r[0] if rv.IP != "11.0.0.2" { - t.Errorf("returned %v but expected %v", rv, apiv1.LoadBalancerIngress{IP: "11.0.0.2"}) + t.Errorf("returned %v but expected %v", rv, networking.IngressLoadBalancerIngress{IP: "11.0.0.2"}) } } @@ -602,7 +605,7 @@ func TestRunningAddressesWithPublishStatusAddress(t *testing.T) { ra, _ := fk.runningAddresses() if ra == nil { - t.Fatalf("returned nil but expected valid []apiv1.LoadBalancerIngress") + t.Fatalf("returned nil but expected valid []networking.IngressLoadBalancerIngress") } rl := len(ra) if len(ra) != 1 { @@ -610,7 +613,7 @@ func TestRunningAddressesWithPublishStatusAddress(t *testing.T) { } rv := ra[0] if rv.IP != "127.0.0.1" { - t.Errorf("returned %v but expected %v", rv, apiv1.LoadBalancerIngress{IP: "127.0.0.1"}) + t.Errorf("returned %v but expected %v", rv, networking.IngressLoadBalancerIngress{IP: "127.0.0.1"}) } } @@ -620,7 +623,7 @@ func TestRunningAddressesWithPublishStatusAddresses(t *testing.T) { ra, _ := fk.runningAddresses() if ra == nil { - t.Fatalf("returned nil but expected valid []apiv1.LoadBalancerIngress") + t.Fatalf("returned nil but expected valid []networking.IngressLoadBalancerIngress") } rl := len(ra) if len(ra) != 2 { @@ -629,10 +632,10 @@ func TestRunningAddressesWithPublishStatusAddresses(t *testing.T) { rv := ra[0] rv2 := ra[1] if rv.IP != "127.0.0.1" { - t.Errorf("returned %v but expected %v", rv, apiv1.LoadBalancerIngress{IP: "127.0.0.1"}) + t.Errorf("returned %v but expected %v", rv, networking.IngressLoadBalancerIngress{IP: "127.0.0.1"}) } if rv2.IP != "1.1.1.1" { - t.Errorf("returned %v but expected %v", rv2, apiv1.LoadBalancerIngress{IP: "1.1.1.1"}) + t.Errorf("returned %v but expected %v", rv2, networking.IngressLoadBalancerIngress{IP: "1.1.1.1"}) } } @@ -642,7 +645,7 @@ func TestRunningAddressesWithPublishStatusAddressesAndSpaces(t *testing.T) { ra, _ := fk.runningAddresses() if ra == nil { - t.Fatalf("returned nil but expected valid []apiv1.LoadBalancerIngresst") + t.Fatalf("returned nil but expected valid []networking.IngressLoadBalancerIngresst") } rl := len(ra) if len(ra) != 2 { @@ -651,15 +654,15 @@ func TestRunningAddressesWithPublishStatusAddressesAndSpaces(t *testing.T) { rv := ra[0] rv2 := ra[1] if rv.IP != "127.0.0.1" { - t.Errorf("returned %v but expected %v", rv, apiv1.LoadBalancerIngress{IP: "127.0.0.1"}) + t.Errorf("returned %v but expected %v", rv, networking.IngressLoadBalancerIngress{IP: "127.0.0.1"}) } if rv2.IP != "1.1.1.1" { - t.Errorf("returned %v but expected %v", rv2, apiv1.LoadBalancerIngress{IP: "1.1.1.1"}) + t.Errorf("returned %v but expected %v", rv2, networking.IngressLoadBalancerIngress{IP: "1.1.1.1"}) } } func TestStandardizeLoadBalancerIngresses(t *testing.T) { - fkEndpoints := []apiv1.LoadBalancerIngress{ + fkEndpoints := []networking.IngressLoadBalancerIngress{ {IP: "2001:db8::68"}, {IP: "10.0.0.1"}, {Hostname: "opensource-k8s-ingress"}, @@ -668,7 +671,7 @@ func TestStandardizeLoadBalancerIngresses(t *testing.T) { r := standardizeLoadBalancerIngresses(fkEndpoints) if r == nil { - t.Fatalf("returned nil but expected a valid []apiv1.LoadBalancerIngress") + t.Fatalf("returned nil but expected a valid []networking.IngressLoadBalancerIngress") } rl := len(r) if rl != 3 { @@ -676,21 +679,21 @@ func TestStandardizeLoadBalancerIngresses(t *testing.T) { } re1 := r[0] if re1.Hostname != "opensource-k8s-ingress" { - t.Fatalf("returned %v but expected %v", re1, apiv1.LoadBalancerIngress{Hostname: "opensource-k8s-ingress"}) + t.Fatalf("returned %v but expected %v", re1, networking.IngressLoadBalancerIngress{Hostname: "opensource-k8s-ingress"}) } re2 := r[1] if re2.IP != "10.0.0.1" { - t.Fatalf("returned %v but expected %v", re2, apiv1.LoadBalancerIngress{IP: "10.0.0.1"}) + t.Fatalf("returned %v but expected %v", re2, networking.IngressLoadBalancerIngress{IP: "10.0.0.1"}) } re3 := r[2] if re3.IP != "2001:db8::68" { - t.Fatalf("returned %v but expected %v", re3, apiv1.LoadBalancerIngress{IP: "2001:db8::68"}) + t.Fatalf("returned %v but expected %v", re3, networking.IngressLoadBalancerIngress{IP: "2001:db8::68"}) } } func TestIngressSliceEqual(t *testing.T) { fk1 := buildLoadBalancerIngressByIP() - fk2 := append(buildLoadBalancerIngressByIP(), apiv1.LoadBalancerIngress{ + fk2 := append(buildLoadBalancerIngressByIP(), networking.IngressLoadBalancerIngress{ IP: "10.0.0.5", Hostname: "foo5", }) @@ -700,8 +703,8 @@ func TestIngressSliceEqual(t *testing.T) { fk4[2].IP = "11.0.0.3" fooTests := []struct { - lhs []apiv1.LoadBalancerIngress - rhs []apiv1.LoadBalancerIngress + lhs []networking.IngressLoadBalancerIngress + rhs []networking.IngressLoadBalancerIngress er bool }{ {fk1, fk1, true}, @@ -710,7 +713,7 @@ func TestIngressSliceEqual(t *testing.T) { {fk4, fk1, false}, {fk1, nil, false}, {nil, nil, true}, - {[]apiv1.LoadBalancerIngress{}, []apiv1.LoadBalancerIngress{}, true}, + {[]networking.IngressLoadBalancerIngress{}, []networking.IngressLoadBalancerIngress{}, true}, } for _, fooTest := range fooTests { diff --git a/internal/k8s/main.go b/internal/k8s/main.go index 5332631a7..d61013a9f 100644 --- a/internal/k8s/main.go +++ b/internal/k8s/main.go @@ -78,6 +78,8 @@ func GetNodeIPOrName(kubeClient clientset.Interface, name string, useInternalIP var ( // IngressPodDetails hold information about the ingress-nginx pod IngressPodDetails *PodInfo + // IngressNodeDetails hold information about the node running ingress-nginx pod + IngressNodeDetails *NodeInfo ) // PodInfo contains runtime information about the pod running the Ingres controller @@ -87,6 +89,12 @@ type PodInfo struct { metav1.ObjectMeta } +// NodeInfo contains runtime information about the node pod running the Ingres controller, eg. zone where pod is running +type NodeInfo struct { + metav1.TypeMeta + metav1.ObjectMeta +} + // GetIngressPod load the ingress-nginx pod func GetIngressPod(kubeClient clientset.Interface) error { podName := os.Getenv("POD_NAME") @@ -108,6 +116,18 @@ func GetIngressPod(kubeClient clientset.Interface) error { pod.ObjectMeta.DeepCopyInto(&IngressPodDetails.ObjectMeta) IngressPodDetails.SetLabels(pod.GetLabels()) + IngressNodeDetails = &NodeInfo{ + TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Node"}, + } + // Try to get node info/labels to determine topology zone where pod is running + node, err := kubeClient.CoreV1().Nodes().Get(context.TODO(), pod.Spec.NodeName, metav1.GetOptions{}) + if err != nil { + klog.Warningf("Unable to get NODE information: %v", err) + } else { + node.ObjectMeta.DeepCopyInto(&IngressNodeDetails.ObjectMeta) + IngressNodeDetails.SetLabels(node.GetLabels()) + } + return nil } diff --git a/internal/nginx/maxmind.go b/internal/nginx/maxmind.go index df9fd2231..5aee414cd 100644 --- a/internal/nginx/maxmind.go +++ b/internal/nginx/maxmind.go @@ -165,7 +165,7 @@ func downloadDatabase(dbName string) error { mmdbFile := dbName + dbExtension tarReader := tar.NewReader(archive) - for true { + for { header, err := tarReader.Next() if err == io.EOF { break diff --git a/magefiles/common.go b/magefiles/common.go new file mode 100644 index 000000000..c5c33f989 --- /dev/null +++ b/magefiles/common.go @@ -0,0 +1,82 @@ +//go:build mage + +/* +Copyright 2023 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 main + +import ( + "fmt" + "os" + "strings" + "time" +) + +var DEBUG bool + +func init() { + DEBUG = false + debugENV := os.Getenv("MAGE_DEBUG") + if debugENV == "true" { + DEBUG = true + } +} + +// CheckArgs should be used to ensure the right command line arguments are +// passed before executing an example. +func CheckArgs(arg ...string) { + if len(os.Args) < len(arg)+1 { + ErrorF("Usage: %s %s", os.Args[0], strings.Join(arg, " ")) + os.Exit(1) + } +} + +// CheckIfError should be used to naively panics if an error is not nil. +func CheckIfError(err error, format string, args ...interface{}) { + if err == nil { + return + } + + fmt.Printf("\x1b[31;1m%s ERROR %s %s\x1b[0m\n", timeStamp(), fmt.Sprintf(format, args...), err) + os.Exit(1) +} + +// Info should be used to describe the example commands that are about to run. +func Info(format string, args ...interface{}) { + fmt.Printf("\x1b[34;1m%s INFO: %s\x1b[0m\n", timeStamp(), fmt.Sprintf(format, args...)) +} + +func timeStamp() string { + t := time.Now() + return t.Format(time.RFC3339) +} + +// Warning should be used to display a warning +func Warning(format string, args ...interface{}) { + fmt.Printf("\x1b[36;1m%s WARNING: %s\x1b[0m\n", timeStamp(), fmt.Sprintf(format, args...)) +} + +// Info should be used to describe the example commands that are about to run. +func Debug(format string, args ...interface{}) { + if DEBUG { + fmt.Printf("\x1b[34;1m%s DEBUG: %s\x1b[0m\n", timeStamp(), fmt.Sprintf(format, args...)) + } +} + +// Info should be used to describe the example commands that are about to run. +func ErrorF(format string, args ...interface{}) { + fmt.Printf("\x1b[31;1m%s ERROR: %s\x1b[0m\n", timeStamp(), fmt.Sprintf(format, args...)) +} diff --git a/magefiles/docker.go b/magefiles/docker.go new file mode 100644 index 000000000..d7c7f588e --- /dev/null +++ b/magefiles/docker.go @@ -0,0 +1,19 @@ +//go:build mage + +/* +Copyright 2023 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 main diff --git a/magefiles/go.go b/magefiles/go.go new file mode 100644 index 000000000..2385b089e --- /dev/null +++ b/magefiles/go.go @@ -0,0 +1,31 @@ +//go:build mage + +/* +Copyright 2023 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 main + +//import ( +// "github.com/magefile/mage/mg" +// "github.com/mysteriumnetwork/go-ci/commands" +//) +// +//type Go mg.Namespace +// +//// Checks for issues with go imports +//func (Go) CheckGoImports() error { +// return commands.GoImports("./...") +//} diff --git a/magefiles/go.mod b/magefiles/go.mod new file mode 100644 index 000000000..40b909600 --- /dev/null +++ b/magefiles/go.mod @@ -0,0 +1,32 @@ +module github.com/kubernetes/ingress-nginx/magefiles + +go 1.20 + +require ( + github.com/blang/semver/v4 v4.0.0 + github.com/google/go-github/v48 v48.2.0 + github.com/helm/helm v2.17.0+incompatible + github.com/magefile/mage v1.14.0 + github.com/vmware-labs/yaml-jsonpath v0.3.2 + golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/cyphar/filepath-securejoin v0.2.3 // indirect + github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/stretchr/testify v1.8.1 // indirect + golang.org/x/crypto v0.1.0 // indirect + golang.org/x/net v0.7.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/apimachinery v0.25.4 // indirect + k8s.io/helm v2.17.0+incompatible // indirect +) diff --git a/magefiles/go.sum b/magefiles/go.sum new file mode 100644 index 000000000..9c0c8ee7f --- /dev/null +++ b/magefiles/go.sum @@ -0,0 +1,105 @@ +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +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/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960 h1:aRd8M7HJVZOqn/vhOzrGcQH0lNAMkqMn+pXUYkatmcA= +github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-github/v48 v48.2.0 h1:68puzySE6WqUY9KWmpOsDEQfDZsso98rT6pZcz9HqcE= +github.com/google/go-github/v48 v48.2.0/go.mod h1:dDlehKBDo850ZPvCTK0sEqTCVWcrGl2LcDiajkYi89Y= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/helm/helm v2.17.0+incompatible h1:0iy95yMXrfWpwaoOA9XRP+cTvitTrq+LcJV9DvR5n1Y= +github.com/helm/helm v2.17.0+incompatible/go.mod h1:ahXhuvluW4YnSL6W6hDVetZsVK8Pv4BP8OwKli7aMqo= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo= +github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2 h1:uqH7bpe+ERSiDa34FDOF7RikN6RzXgduUF8yarlZp94= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +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= +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.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/apimachinery v0.25.4 h1:CtXsuaitMESSu339tfhVXhQrPET+EiWnIY1rcurKnAc= +k8s.io/apimachinery v0.25.4/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= +k8s.io/helm v2.17.0+incompatible h1:Bpn6o1wKLYqKM3+Osh8e+1/K2g/GsQJ4F4yNF2+deao= +k8s.io/helm v2.17.0+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= diff --git a/magefiles/helm.go b/magefiles/helm.go new file mode 100644 index 000000000..585a93413 --- /dev/null +++ b/magefiles/helm.go @@ -0,0 +1,632 @@ +//go:build mage + +/* +Copyright 2023 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 main + +import ( + "bytes" + "fmt" + "os" + "strings" + + semver "github.com/blang/semver/v4" + "github.com/helm/helm/pkg/chartutil" + "github.com/magefile/mage/mg" + "github.com/magefile/mage/sh" + yamlpath "github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath" + "gopkg.in/yaml.v3" +) + +const HelmChartPath = "charts/ingress-nginx/Chart.yaml" +const HelmChartValues = "charts/ingress-nginx/values.yaml" + +type Helm mg.Namespace + +// UpdateAppVersion Updates the Helm App Version of Ingress Nginx Controller +func (Helm) UpdateAppVersion() { + updateAppVersion() +} + +func updateAppVersion() { + +} + +// UpdateVersion Update Helm Version of the Chart +func (Helm) UpdateVersion(version string) { + updateVersion(version) +} + +func currentChartVersion() string { + chart, err := chartutil.LoadChartfile(HelmChartPath) + CheckIfError(err, "HELM Could not Load Chart") + return chart.Version +} + +func currentChartAppVersion() string { + chart, err := chartutil.LoadChartfile(HelmChartPath) + CheckIfError(err, "HELM Could not Load Chart") + return chart.AppVersion +} + +func updateVersion(version string) { + Info("HELM Reading File %v", HelmChartPath) + + chart, err := chartutil.LoadChartfile(HelmChartPath) + CheckIfError(err, "HELM Could not Load Chart") + + //Get the current tag + //appVersionV, err := getIngressNGINXVersion() + //CheckIfError(err, "HELM Issue Retrieving the Current Ingress Nginx Version") + + //remove the v from TAG + appVersion := version + + Info("HELM Ingress-Nginx App Version: %s Chart AppVersion: %s", appVersion, chart.AppVersion) + if appVersion == chart.AppVersion { + Warning("HELM Ingress NGINX Version didnt change Ingress-Nginx App Version: %s Chart AppVersion: %s", appVersion, chart.AppVersion) + return + } + + //Update the helm chart + chart.AppVersion = appVersion + cTag, err := semver.Make(chart.Version) + CheckIfError(err, "HELM Creating Chart Version: %v", err) + + if err = cTag.IncrementPatch(); err != nil { + ErrorF("HELM Incrementing Chart Version: %v", err) + os.Exit(1) + } + chart.Version = cTag.String() + Debug("HELM Updated Chart Version: %v", chart.Version) + + err = chartutil.SaveChartfile(HelmChartPath, chart) + CheckIfError(err, "HELM Saving new Chart") +} + +func updateChartReleaseNotes(releasesNotes []string) { + Info("HELM Updating the Chart Release notes") + chart, err := chartutil.LoadChartfile(HelmChartPath) + CheckIfError(err, "HELM Could not Load Chart to update release notes %s", HelmChartPath) + var releaseNoteString string + for i := range releasesNotes { + releaseNoteString = fmt.Sprintf("%s - \"%s\"\n", releaseNoteString, releasesNotes[i]) + } + Info("HELM Release note string %s", releaseNoteString) + chart.Annotations["artifacthub.io/changes"] = releaseNoteString + err = chartutil.SaveChartfile(HelmChartPath, chart) + CheckIfError(err, "HELM Saving updated release notes for Chart") +} + +func UpdateChartChangelog() { + +} + +// UpdateChartValue Updates the Helm ChartValue +func (Helm) UpdateChartValue(key, value string) { + updateChartValue(key, value) +} + +func updateChartValue(key, value string) { + Info("HELM Updating Chart %s %s:%s", HelmChartValues, key, value) + + //read current values.yaml + data, err := os.ReadFile(HelmChartValues) + CheckIfError(err, "HELM Could not Load Helm Chart Values files %s", HelmChartValues) + + //var valuesStruct IngressChartValue + var n yaml.Node + CheckIfError(yaml.Unmarshal(data, &n), "HELM Could not Unmarshal %s", HelmChartValues) + + //update value + //keyParse := parsePath(key) + p, err := yamlpath.NewPath(key) + CheckIfError(err, "HELM cannot create path") + + q, err := p.Find(&n) + CheckIfError(err, "HELM unexpected error finding path") + + for _, i := range q { + Info("HELM Found %s at %s", i.Value, key) + i.Value = value + Info("HELM Updated %s at %s", i.Value, key) + } + + //// write to file + var b bytes.Buffer + yamlEncoder := yaml.NewEncoder(&b) + yamlEncoder.SetIndent(2) + err = yamlEncoder.Encode(&n) + CheckIfError(err, "HELM Could not Marshal new Values file") + err = os.WriteFile(HelmChartValues, b.Bytes(), 0644) + CheckIfError(err, "HELM Could not write new Values file to %s", HelmChartValues) + + Info("HELM Ingress Nginx Helm Chart update %s %s", key, value) +} + +func (Helm) Helmdocs() error { + return runHelmDocs() +} +func runHelmDocs() error { + err := installHelmDocs() + if err != nil { + return err + } + err = sh.RunV("helm-docs", "--chart-search-root=${PWD}/charts") + if err != nil { + return err + } + return nil +} + +func installHelmDocs() error { + Info("HELM Install HelmDocs") + var g0 = sh.RunCmd("go") + + err := g0("install", "github.com/norwoodj/helm-docs/cmd/helm-docs@v1.11.0") + if err != nil { + return err + } + return nil +} +func parsePath(key string) []string { return strings.Split(key, ".") } + +func updateHelmDocs() { + +} + +type IngressChartValue struct { + CommonLabels struct { + } `yaml:"commonLabels"` + Controller struct { + Name string `yaml:"name"` + Image struct { + Chroot bool `yaml:"chroot"` + Registry string `yaml:"registry"` + Image string `yaml:"image"` + Tag string `yaml:"tag"` + Digest string `yaml:"digest"` + DigestChroot string `yaml:"digestChroot"` + PullPolicy string `yaml:"pullPolicy"` + RunAsUser int `yaml:"runAsUser"` + AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` + } `yaml:"image"` + ExistingPsp string `yaml:"existingPsp"` + ContainerName string `yaml:"containerName"` + ContainerPort struct { + HTTP int `yaml:"http"` + HTTPS int `yaml:"https"` + } `yaml:"containerPort"` + Config struct { + } `yaml:"config"` + ConfigAnnotations struct { + } `yaml:"configAnnotations"` + ProxySetHeaders struct { + } `yaml:"proxySetHeaders"` + AddHeaders struct { + } `yaml:"addHeaders"` + DNSConfig struct { + } `yaml:"dnsConfig"` + Hostname struct { + } `yaml:"hostname"` + DNSPolicy string `yaml:"dnsPolicy"` + ReportNodeInternalIP bool `yaml:"reportNodeInternalIp"` + WatchIngressWithoutClass bool `yaml:"watchIngressWithoutClass"` + IngressClassByName bool `yaml:"ingressClassByName"` + AllowSnippetAnnotations bool `yaml:"allowSnippetAnnotations"` + HostNetwork bool `yaml:"hostNetwork"` + HostPort struct { + Enabled bool `yaml:"enabled"` + Ports struct { + HTTP int `yaml:"http"` + HTTPS int `yaml:"https"` + } `yaml:"ports"` + } `yaml:"hostPort"` + ElectionID string `yaml:"electionID"` + IngressClassResource struct { + Name string `yaml:"name"` + Enabled bool `yaml:"enabled"` + Default bool `yaml:"default"` + ControllerValue string `yaml:"controllerValue"` + Parameters struct { + } `yaml:"parameters"` + } `yaml:"ingressClassResource"` + IngressClass string `yaml:"ingressClass"` + PodLabels struct { + } `yaml:"podLabels"` + PodSecurityContext struct { + } `yaml:"podSecurityContext"` + Sysctls struct { + } `yaml:"sysctls"` + PublishService struct { + Enabled bool `yaml:"enabled"` + PathOverride string `yaml:"pathOverride"` + } `yaml:"publishService"` + Scope struct { + Enabled bool `yaml:"enabled"` + Namespace string `yaml:"namespace"` + NamespaceSelector string `yaml:"namespaceSelector"` + } `yaml:"scope"` + ConfigMapNamespace string `yaml:"configMapNamespace"` + TCP struct { + ConfigMapNamespace string `yaml:"configMapNamespace"` + Annotations struct { + } `yaml:"annotations"` + } `yaml:"tcp"` + UDP struct { + ConfigMapNamespace string `yaml:"configMapNamespace"` + Annotations struct { + } `yaml:"annotations"` + } `yaml:"udp"` + MaxmindLicenseKey string `yaml:"maxmindLicenseKey"` + ExtraArgs struct { + } `yaml:"extraArgs"` + ExtraEnvs []interface{} `yaml:"extraEnvs"` + Kind string `yaml:"kind"` + Annotations struct { + } `yaml:"annotations"` + Labels struct { + } `yaml:"labels"` + UpdateStrategy struct { + } `yaml:"updateStrategy"` + MinReadySeconds int `yaml:"minReadySeconds"` + Tolerations []interface{} `yaml:"tolerations"` + Affinity struct { + } `yaml:"affinity"` + TopologySpreadConstraints []interface{} `yaml:"topologySpreadConstraints"` + TerminationGracePeriodSeconds int `yaml:"terminationGracePeriodSeconds"` + NodeSelector struct { + KubernetesIoOs string `yaml:"kubernetes.io/os"` + } `yaml:"nodeSelector"` + LivenessProbe struct { + HTTPGet struct { + Path string `yaml:"path"` + Port int `yaml:"port"` + Scheme string `yaml:"scheme"` + } `yaml:"httpGet"` + InitialDelaySeconds int `yaml:"initialDelaySeconds"` + PeriodSeconds int `yaml:"periodSeconds"` + TimeoutSeconds int `yaml:"timeoutSeconds"` + SuccessThreshold int `yaml:"successThreshold"` + FailureThreshold int `yaml:"failureThreshold"` + } `yaml:"livenessProbe"` + ReadinessProbe struct { + HTTPGet struct { + Path string `yaml:"path"` + Port int `yaml:"port"` + Scheme string `yaml:"scheme"` + } `yaml:"httpGet"` + InitialDelaySeconds int `yaml:"initialDelaySeconds"` + PeriodSeconds int `yaml:"periodSeconds"` + TimeoutSeconds int `yaml:"timeoutSeconds"` + SuccessThreshold int `yaml:"successThreshold"` + FailureThreshold int `yaml:"failureThreshold"` + } `yaml:"readinessProbe"` + HealthCheckPath string `yaml:"healthCheckPath"` + HealthCheckHost string `yaml:"healthCheckHost"` + PodAnnotations struct { + } `yaml:"podAnnotations"` + ReplicaCount int `yaml:"replicaCount"` + MinAvailable int `yaml:"minAvailable"` + Resources struct { + Requests struct { + CPU string `yaml:"cpu"` + Memory string `yaml:"memory"` + } `yaml:"requests"` + } `yaml:"resources"` + Autoscaling struct { + APIVersion string `yaml:"apiVersion"` + Enabled bool `yaml:"enabled"` + Annotations struct { + } `yaml:"annotations"` + MinReplicas int `yaml:"minReplicas"` + MaxReplicas int `yaml:"maxReplicas"` + TargetCPUUtilizationPercentage int `yaml:"targetCPUUtilizationPercentage"` + TargetMemoryUtilizationPercentage int `yaml:"targetMemoryUtilizationPercentage"` + Behavior struct { + } `yaml:"behavior"` + } `yaml:"autoscaling"` + AutoscalingTemplate []interface{} `yaml:"autoscalingTemplate"` + Keda struct { + APIVersion string `yaml:"apiVersion"` + Enabled bool `yaml:"enabled"` + MinReplicas int `yaml:"minReplicas"` + MaxReplicas int `yaml:"maxReplicas"` + PollingInterval int `yaml:"pollingInterval"` + CooldownPeriod int `yaml:"cooldownPeriod"` + RestoreToOriginalReplicaCount bool `yaml:"restoreToOriginalReplicaCount"` + ScaledObject struct { + Annotations struct { + } `yaml:"annotations"` + } `yaml:"scaledObject"` + Triggers []interface{} `yaml:"triggers"` + Behavior struct { + } `yaml:"behavior"` + } `yaml:"keda"` + EnableMimalloc bool `yaml:"enableMimalloc"` + CustomTemplate struct { + ConfigMapName string `yaml:"configMapName"` + ConfigMapKey string `yaml:"configMapKey"` + } `yaml:"customTemplate"` + Service struct { + Enabled bool `yaml:"enabled"` + AppProtocol bool `yaml:"appProtocol"` + Annotations struct { + } `yaml:"annotations"` + Labels struct { + } `yaml:"labels"` + ExternalIPs []interface{} `yaml:"externalIPs"` + LoadBalancerIP string `yaml:"loadBalancerIP"` + LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` + EnableHTTP bool `yaml:"enableHttp"` + EnableHTTPS bool `yaml:"enableHttps"` + IPFamilyPolicy string `yaml:"ipFamilyPolicy"` + IPFamilies []string `yaml:"ipFamilies"` + Ports struct { + HTTP int `yaml:"http"` + HTTPS int `yaml:"https"` + } `yaml:"ports"` + TargetPorts struct { + HTTP string `yaml:"http"` + HTTPS string `yaml:"https"` + } `yaml:"targetPorts"` + Type string `yaml:"type"` + NodePorts struct { + HTTP string `yaml:"http"` + HTTPS string `yaml:"https"` + TCP struct { + } `yaml:"tcp"` + UDP struct { + } `yaml:"udp"` + } `yaml:"nodePorts"` + External struct { + Enabled bool `yaml:"enabled"` + } `yaml:"external"` + Internal struct { + Enabled bool `yaml:"enabled"` + Annotations struct { + } `yaml:"annotations"` + LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` + } `yaml:"internal"` + } `yaml:"service"` + ShareProcessNamespace bool `yaml:"shareProcessNamespace"` + ExtraContainers []interface{} `yaml:"extraContainers"` + ExtraVolumeMounts []interface{} `yaml:"extraVolumeMounts"` + ExtraVolumes []interface{} `yaml:"extraVolumes"` + ExtraInitContainers []interface{} `yaml:"extraInitContainers"` + ExtraModules []interface{} `yaml:"extraModules"` + Opentelemetry struct { + Enabled bool `yaml:"enabled"` + Image string `yaml:"image"` + ContainerSecurityContext struct { + AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` + } `yaml:"containerSecurityContext"` + } `yaml:"opentelemetry"` + AdmissionWebhooks struct { + Annotations struct { + } `yaml:"annotations"` + Enabled bool `yaml:"enabled"` + ExtraEnvs []interface{} `yaml:"extraEnvs"` + FailurePolicy string `yaml:"failurePolicy"` + Port int `yaml:"port"` + Certificate string `yaml:"certificate"` + Key string `yaml:"key"` + NamespaceSelector struct { + } `yaml:"namespaceSelector"` + ObjectSelector struct { + } `yaml:"objectSelector"` + Labels struct { + } `yaml:"labels"` + ExistingPsp string `yaml:"existingPsp"` + NetworkPolicyEnabled bool `yaml:"networkPolicyEnabled"` + Service struct { + Annotations struct { + } `yaml:"annotations"` + ExternalIPs []interface{} `yaml:"externalIPs"` + LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` + ServicePort int `yaml:"servicePort"` + Type string `yaml:"type"` + } `yaml:"service"` + CreateSecretJob struct { + SecurityContext struct { + AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` + } `yaml:"securityContext"` + Resources struct { + } `yaml:"resources"` + } `yaml:"createSecretJob"` + PatchWebhookJob struct { + SecurityContext struct { + AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` + } `yaml:"securityContext"` + Resources struct { + } `yaml:"resources"` + } `yaml:"patchWebhookJob"` + Patch struct { + Enabled bool `yaml:"enabled"` + Image struct { + Registry string `yaml:"registry"` + Image string `yaml:"image"` + Tag string `yaml:"tag"` + Digest string `yaml:"digest"` + PullPolicy string `yaml:"pullPolicy"` + } `yaml:"image"` + PriorityClassName string `yaml:"priorityClassName"` + PodAnnotations struct { + } `yaml:"podAnnotations"` + NodeSelector struct { + KubernetesIoOs string `yaml:"kubernetes.io/os"` + } `yaml:"nodeSelector"` + Tolerations []interface{} `yaml:"tolerations"` + Labels struct { + } `yaml:"labels"` + SecurityContext struct { + RunAsNonRoot bool `yaml:"runAsNonRoot"` + RunAsUser int `yaml:"runAsUser"` + FsGroup int `yaml:"fsGroup"` + } `yaml:"securityContext"` + } `yaml:"patch"` + CertManager struct { + Enabled bool `yaml:"enabled"` + RootCert struct { + Duration string `yaml:"duration"` + } `yaml:"rootCert"` + AdmissionCert struct { + Duration string `yaml:"duration"` + } `yaml:"admissionCert"` + } `yaml:"certManager"` + } `yaml:"admissionWebhooks"` + Metrics struct { + Port int `yaml:"port"` + PortName string `yaml:"portName"` + Enabled bool `yaml:"enabled"` + Service struct { + Annotations struct { + } `yaml:"annotations"` + ExternalIPs []interface{} `yaml:"externalIPs"` + LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` + ServicePort int `yaml:"servicePort"` + Type string `yaml:"type"` + } `yaml:"service"` + ServiceMonitor struct { + Enabled bool `yaml:"enabled"` + AdditionalLabels struct { + } `yaml:"additionalLabels"` + Namespace string `yaml:"namespace"` + NamespaceSelector struct { + } `yaml:"namespaceSelector"` + ScrapeInterval string `yaml:"scrapeInterval"` + TargetLabels []interface{} `yaml:"targetLabels"` + Relabelings []interface{} `yaml:"relabelings"` + MetricRelabelings []interface{} `yaml:"metricRelabelings"` + } `yaml:"serviceMonitor"` + PrometheusRule struct { + Enabled bool `yaml:"enabled"` + AdditionalLabels struct { + } `yaml:"additionalLabels"` + Rules []interface{} `yaml:"rules"` + } `yaml:"prometheusRule"` + } `yaml:"metrics"` + Lifecycle struct { + PreStop struct { + Exec struct { + Command []string `yaml:"command"` + } `yaml:"exec"` + } `yaml:"preStop"` + } `yaml:"lifecycle"` + PriorityClassName string `yaml:"priorityClassName"` + } `yaml:"controller"` + RevisionHistoryLimit int `yaml:"revisionHistoryLimit"` + DefaultBackend struct { + Enabled bool `yaml:"enabled"` + Name string `yaml:"name"` + Image struct { + Registry string `yaml:"registry"` + Image string `yaml:"image"` + Tag string `yaml:"tag"` + PullPolicy string `yaml:"pullPolicy"` + RunAsUser int `yaml:"runAsUser"` + RunAsNonRoot bool `yaml:"runAsNonRoot"` + ReadOnlyRootFilesystem bool `yaml:"readOnlyRootFilesystem"` + AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` + } `yaml:"image"` + ExistingPsp string `yaml:"existingPsp"` + ExtraArgs struct { + } `yaml:"extraArgs"` + ServiceAccount struct { + Create bool `yaml:"create"` + Name string `yaml:"name"` + AutomountServiceAccountToken bool `yaml:"automountServiceAccountToken"` + } `yaml:"serviceAccount"` + ExtraEnvs []interface{} `yaml:"extraEnvs"` + Port int `yaml:"port"` + LivenessProbe struct { + FailureThreshold int `yaml:"failureThreshold"` + InitialDelaySeconds int `yaml:"initialDelaySeconds"` + PeriodSeconds int `yaml:"periodSeconds"` + SuccessThreshold int `yaml:"successThreshold"` + TimeoutSeconds int `yaml:"timeoutSeconds"` + } `yaml:"livenessProbe"` + ReadinessProbe struct { + FailureThreshold int `yaml:"failureThreshold"` + InitialDelaySeconds int `yaml:"initialDelaySeconds"` + PeriodSeconds int `yaml:"periodSeconds"` + SuccessThreshold int `yaml:"successThreshold"` + TimeoutSeconds int `yaml:"timeoutSeconds"` + } `yaml:"readinessProbe"` + Tolerations []interface{} `yaml:"tolerations"` + Affinity struct { + } `yaml:"affinity"` + PodSecurityContext struct { + } `yaml:"podSecurityContext"` + ContainerSecurityContext struct { + } `yaml:"containerSecurityContext"` + PodLabels struct { + } `yaml:"podLabels"` + NodeSelector struct { + KubernetesIoOs string `yaml:"kubernetes.io/os"` + } `yaml:"nodeSelector"` + PodAnnotations struct { + } `yaml:"podAnnotations"` + ReplicaCount int `yaml:"replicaCount"` + MinAvailable int `yaml:"minAvailable"` + Resources struct { + } `yaml:"resources"` + ExtraVolumeMounts []interface{} `yaml:"extraVolumeMounts"` + ExtraVolumes []interface{} `yaml:"extraVolumes"` + Autoscaling struct { + Annotations struct { + } `yaml:"annotations"` + Enabled bool `yaml:"enabled"` + MinReplicas int `yaml:"minReplicas"` + MaxReplicas int `yaml:"maxReplicas"` + TargetCPUUtilizationPercentage int `yaml:"targetCPUUtilizationPercentage"` + TargetMemoryUtilizationPercentage int `yaml:"targetMemoryUtilizationPercentage"` + } `yaml:"autoscaling"` + Service struct { + Annotations struct { + } `yaml:"annotations"` + ExternalIPs []interface{} `yaml:"externalIPs"` + LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` + ServicePort int `yaml:"servicePort"` + Type string `yaml:"type"` + } `yaml:"service"` + PriorityClassName string `yaml:"priorityClassName"` + Labels struct { + } `yaml:"labels"` + } `yaml:"defaultBackend"` + Rbac struct { + Create bool `yaml:"create"` + Scope bool `yaml:"scope"` + } `yaml:"rbac"` + PodSecurityPolicy struct { + Enabled bool `yaml:"enabled"` + } `yaml:"podSecurityPolicy"` + ServiceAccount struct { + Create bool `yaml:"create"` + Name string `yaml:"name"` + AutomountServiceAccountToken bool `yaml:"automountServiceAccountToken"` + Annotations struct { + } `yaml:"annotations"` + } `yaml:"serviceAccount"` + ImagePullSecrets []interface{} `yaml:"imagePullSecrets"` + TCP struct { + } `yaml:"tcp"` + UDP struct { + } `yaml:"udp"` + PortNamePrefix string `yaml:"portNamePrefix"` + DhParam interface{} `yaml:"dhParam"` +} diff --git a/magefiles/mage.go b/magefiles/mage.go new file mode 100644 index 000000000..605d687a9 --- /dev/null +++ b/magefiles/mage.go @@ -0,0 +1,29 @@ +//go:build ignore +// +build ignore + +/* +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 main + +import ( + "github.com/magefile/mage/mage" + "os" +) + +func main() { + os.Exit(mage.Main()) +} diff --git a/magefiles/release.go b/magefiles/release.go new file mode 100644 index 000000000..c02b88cfd --- /dev/null +++ b/magefiles/release.go @@ -0,0 +1,547 @@ +//go:build mage + +/* +Copyright 2023 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 main + +import ( + "context" + "errors" + "fmt" + "github.com/google/go-github/v48/github" + "github.com/magefile/mage/mg" + "github.com/magefile/mage/sh" + "golang.org/x/oauth2" + "gopkg.in/yaml.v3" + "io" + "net" + "net/http" + "os" + "text/template" + + "regexp" + "strings" + "time" +) + +type Release mg.Namespace + +var INGRESS_ORG = "kubernetes" // the owner so we can test from forks +var INGRESS_REPO = "ingress-nginx" // the repo to pull from +var RELEASE_BRANCH = "main" //we only release from main +var GITHUB_TOKEN string // the Google/gogithub lib needs an PAT to access the GitHub API +var K8S_IO_ORG = "kubernetes" //the owner or organization for the k8s.io repo +var K8S_IO_REPO = "k8s.io" //the repo that holds the images yaml for production promotion +var INGRESS_REGISTRY = "registry.k8s.io" //Container registry for storage Ingress-nginx images +var KUSTOMIZE_INSTALL_VERSION = "sigs.k8s.io/kustomize/kustomize/v4@v4.5.4" //static deploys needs kustomize to generate the template + +// ingress-nginx releases start with a TAG then a cloudbuild, then a promotion through a PR, this the location of that PR +var IMAGES_YAML = "https://raw.githubusercontent.com/kubernetes/k8s.io/main/registry.k8s.io/images/k8s-staging-ingress-nginx/images.yaml" +var ctx = context.Background() // Context used for GitHub Client + +const INDEX_DOCS = "docs/deploy/index.md" //index.md has a version of the controller and needs to updated +const CHANGELOG = "Changelog.md" //Name of the changelog + +// ControllerImage - struct with info about controllers +type ControllerImage struct { + Tag string + Digest string + Registry string + Name string +} + +// IngressRelease All the information about an ingress-nginx release that gets updated +type IngressRelease struct { + ControllerVersion string + ControllerImage ControllerImage + ReleaseNote ReleaseNote + Release *github.RepositoryRelease +} + +// ReleaseNote - All the pieces of information/documents that get updated during a release +type ReleaseNote struct { + Version string + NewControllerVersion string + PreviousControllerVersion string + ControllerImages []ControllerImage + DepUpdates []string + Updates []string + HelmUpdates []string + NewHelmChartVersion string + PreviousHelmChartVersion string +} + +// IMAGES_YAML returns this data structure +type ImageYamls []ImageElement + +// ImageElement - a specific image and it's data structure the dmap is a list of shas and container versions +type ImageElement struct { + Name string `json:"name"` + Dmap map[string][]string `json:"dmap"` +} + +// init will set the GitHub token from the committers/releasers env var +func init() { + GITHUB_TOKEN = os.Getenv("GITHUB_TOKEN") +} + +// PromoteImage Creates PR into the k8s.io repo for promotion of ingress from staging to production +func (Release) PromoteImage(version, sha string) { + +} + +// Release Create a new release of ingress nginx controller +func (Release) NewRelease(version string) { + //newRelease := Release{} + + //update ingress-nginx version + //This is the step that kicks all the release process + //it is already done, so it kicks off the gcloud build of the controller images + //mg.Deps(mg.F(Tag.BumpNginx, version)) + + tag, err := getIngressNGINXVersion() + CheckIfError(err, "RELEASE Retrieving the current Ingress Nginx Version") + + Info("RELEASE Checking Current Version %s to New Version %s", tag, version) + //if the version were upgrading does not match the TAG file, lets update the TAG file + if tag[1:] != version { + Warning("RELEASE Ingress Nginx TAG %s and new version %s do not match", tag, version) + mg.Deps(mg.F(Tag.BumpNginx, fmt.Sprintf("v%s", version))) + } + + //update git controller tag controller-v$version + mg.Deps(mg.F(Tag.NewControllerTag, version)) + + //make release notes + releaseNotes, err := makeReleaseNotes(version) + CheckIfError(err, "RELEASE Creating Release Notes for version %s", version) + Info("RELEASE Release Notes %s completed", releaseNotes.Version) + + //update chart values.yaml new controller tag and image digest + releaseNotes.PreviousHelmChartVersion = currentChartVersion() + + //controller tag + updateChartValue("controller.image.tag", fmt.Sprintf("v%s", releaseNotes.Version)) + //controller digest + if releaseNotes.ControllerImages[0].Name == "controller" { + updateChartValue("controller.image.digest", releaseNotes.ControllerImages[0].Digest) + } + //controller chroot digest + if releaseNotes.ControllerImages[1].Name == "controller-chroot" { + updateChartValue("controller.image.digestChroot", releaseNotes.ControllerImages[1].Digest) + } + + //update helm chart app version + mg.Deps(mg.F(Helm.UpdateVersion, version)) + + releaseNotes.NewHelmChartVersion = currentChartVersion() + + //update helm chart release notes + updateChartReleaseNotes(releaseNotes.HelmUpdates) + + //Run helm docs update + CheckIfError(runHelmDocs(), "Error Updating Helm Docs ") + + releaseNotes.helmTemplate() + + //update static manifest + CheckIfError(updateStaticManifest(), "Error Updating Static manifests") + + ////update e2e docs + updateE2EDocs() + + //update documentation with ingress-nginx version + CheckIfError(updateIndexMD(releaseNotes.PreviousControllerVersion, releaseNotes.NewControllerVersion), "Error Updating %s", INDEX_DOCS) + + //keeping these manual for now + //git commit TODO + //make Pull Request TODO + //make release TODO + //mg.Deps(mg.F(Release.CreateRelease, version)) +} + +// the index.md doc needs the controller version updated +func updateIndexMD(old, new string) error { + Info("Updating Deploy docs with new version") + data, err := os.ReadFile(INDEX_DOCS) + CheckIfError(err, "Could not read INDEX_DOCS file %s", INDEX_DOCS) + datString := string(data) + datString = strings.Replace(datString, old, new, -1) + err = os.WriteFile(INDEX_DOCS, []byte(datString), 644) + if err != nil { + ErrorF("Could not write new %s %s", INDEX_DOCS, err) + return err + } + return nil +} + +// runs the hack/generate-deploy-scripts.sh +func updateE2EDocs() { + updates, err := sh.Output("./hack/generate-e2e-suite-doc.sh") + CheckIfError(err, "Could not run update hack script") + err = os.WriteFile("docs/e2e-tests.md", []byte(updates), 644) + CheckIfError(err, "Could not write new e2e test file ") +} + +// The static deploy scripts use kustomize to generate them, this function ensures kustomize is installed +func installKustomize() error { + Info("Install Kustomize") + var g0 = sh.RunCmd("go") + // somewhere in your main code + err := g0("install", KUSTOMIZE_INSTALL_VERSION) + if err != nil { + return err + } + return nil +} + +func updateStaticManifest() error { + CheckIfError(installKustomize(), "error installing kustomize") + //hack/generate-deploy-scripts.sh + err := sh.RunV("./hack/generate-deploy-scripts.sh") + if err != nil { + return err + } + return nil +} + +//// CreateRelease Creates a new GitHub Release +//func (Release) CreateRelease(name string) { +// releaser, err := gh_release.NewReleaser(INGRESS_ORG, INGRESS_REPO, GITHUB_TOKEN) +// CheckIfError(err, "GitHub Release Client error") +// newRelease, err := releaser.Create(fmt.Sprintf("controller-%s", name)) +// CheckIfError(err, "Create release error") +// Info("New Release: Tag %v, ID: %v", newRelease.TagName, newRelease.ID) +//} + +// Returns a GitHub client ready for use +func githubClient() *github.Client { + ts := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: GITHUB_TOKEN}, + ) + oauthClient := oauth2.NewClient(ctx, ts) + return github.NewClient(oauthClient) +} + +// LatestCommitLogs Retrieves the commit log between the latest two controller versions. +func (Release) LatestCommitLogs() { + commitLog := commitsBetweenTags() + for i, s := range commitLog { + Info("#%v Version %v", i, s) + } +} + +func commitsBetweenTags() []string { + tags := getAllControllerTags() + Info("Getting Commits between %v and %v", tags[0], tags[1]) + commitLog, err := git("log", "--full-history", "--pretty", "--oneline", fmt.Sprintf("%v..%v", tags[1], tags[0])) + + if commitLog == "" { + Warning("All Controller Tags is empty") + } + CheckIfError(err, "Retrieving Commit log") + return strings.Split(commitLog, "\n") +} + +// Generate Release Notes +func (Release) ReleaseNotes(newVersion string) error { + notes, err := makeReleaseNotes(newVersion) + CheckIfError(err, "Creating Release Notes for version %s", newVersion) + Info("Release Notes %s completed", notes.Version) + return nil +} + +func makeReleaseNotes(newVersion string) (*ReleaseNote, error) { + var newReleaseNotes = ReleaseNote{} + + newReleaseNotes.Version = newVersion + allControllerTags := getAllControllerTags() + + //new version + newReleaseNotes.NewControllerVersion = allControllerTags[0] + newControllerVersion := fmt.Sprintf("controller-v%s", newVersion) + + //the newControllerVersion should match the latest tag + if newControllerVersion != allControllerTags[0] { + return nil, errors.New(fmt.Sprintf("Generating release new version %s didnt match the current latest tag %s", newControllerVersion, allControllerTags[0])) + } + //previous version + newReleaseNotes.PreviousControllerVersion = allControllerTags[1] + + Info("New Version: %s Old Version: %s", newReleaseNotes.NewControllerVersion, newReleaseNotes.PreviousControllerVersion) + + commits := commitsBetweenTags() + + //dependency_updates + //all_updates + var allUpdates []string + var depUpdates []string + var helmUpdates []string + prRegex := regexp.MustCompile("\\(#\\d+\\)") + depBot := regexp.MustCompile("^(\\w){1,10} Bump ") + helmRegex := regexp.MustCompile("helm|chart") + for i, s := range commits { + //matches on PR + if prRegex.Match([]byte(s)) { + //matches a dependant bot update + if depBot.Match([]byte(s)) { // + Debug("#%v DEPENDABOT %v", i, s) + u := strings.SplitN(s, " ", 2) + depUpdates = append(depUpdates, u[1]) + } else { // add it to the all updates slice + Debug("#%v ALL UPDATES %v", i, s) + u := strings.SplitN(s, " ", 2) + allUpdates = append(allUpdates, u[1]) + + //helm chart updates + if helmRegex.Match([]byte(s)) { + u := strings.SplitN(s, " ", 2) + helmUpdates = append(helmUpdates, u[1]) + } + } + + } + } + helmUpdates = append(helmUpdates, fmt.Sprintf("Update Ingress-Nginx version %s", newReleaseNotes.NewControllerVersion)) + + newReleaseNotes.Updates = allUpdates + newReleaseNotes.DepUpdates = depUpdates + newReleaseNotes.HelmUpdates = helmUpdates + + //controller_image_digests + imagesYaml, err := downloadFile(IMAGES_YAML) + if err != nil { + ErrorF("Could not download file %s : %s", IMAGES_YAML, err) + return nil, err + } + Debug("%s", imagesYaml) + + data := ImageYamls{} + + err = yaml.Unmarshal([]byte(imagesYaml), &data) + if err != nil { + ErrorF("Could not unmarshal images yaml %s", err) + return nil, err + } + + //controller + controllerDigest := findImageDigest(data, "controller", newVersion) + if len(controllerDigest) == 0 { + ErrorF("Controller Digest could not be found") + return nil, errors.New("Controller digest could not be found") + } + + controllerChrootDigest := findImageDigest(data, "controller-chroot", newVersion) + if len(controllerChrootDigest) == 0 { + ErrorF("Controller Chroot Digest could not be found") + return nil, errors.New("Controller Chroot digest could not be found") + } + + Debug("Latest Controller Digest %v", controllerDigest) + Debug("Latest Controller Chroot Digest %v", controllerChrootDigest) + c1 := ControllerImage{ + Digest: controllerDigest, + Registry: INGRESS_REGISTRY, + Name: "ingress-nginx/controller", + Tag: fmt.Sprintf("v%s", newReleaseNotes.Version), + } + + c2 := ControllerImage{ + Digest: controllerChrootDigest, + Registry: INGRESS_REGISTRY, + Name: "ingress-nginx/controller-chroot", + Tag: fmt.Sprintf("v%s", newReleaseNotes.Version), + } + + newReleaseNotes.ControllerImages = append(newReleaseNotes.ControllerImages, c1) + newReleaseNotes.ControllerImages = append(newReleaseNotes.ControllerImages, c2) + Debug("New Release Controller Images %s %s", newReleaseNotes.ControllerImages[0].Digest, newReleaseNotes.ControllerImages[1].Digest) + + if DEBUG { + newReleaseNotes.printRelease() + } + + //write it all out to the changelog file + newReleaseNotes.template() + + return &newReleaseNotes, nil +} + +func (i ControllerImage) print() string { + return fmt.Sprintf("%s/%s:%s@%s", i.Registry, i.Name, i.Tag, i.Digest) +} + +func (r ReleaseNote) template() { + // Files are provided as a slice of strings. + changelogTemplate, err := os.ReadFile("Changelog.md.gotmpl") + if err != nil { + ErrorF("Could not read changelog template file %s", err) + } + Debug("ChangeLog Templates %s", string(changelogTemplate)) + t := template.Must(template.New("changelog").Parse(string(changelogTemplate))) + // create a new file + file, err := os.Create(fmt.Sprintf("changelog/Changelog-%s.md", r.Version)) + if err != nil { + ErrorF("Could not create changelog file %s", err) + } + defer file.Close() + + err = t.Execute(file, r) + if err != nil { + ErrorF("executing template:", err) + } +} + +func (r ReleaseNote) helmTemplate() { + // Files are provided as a slice of strings. + changelogTemplate, err := os.ReadFile("charts/ingress-nginx/changelog.md.gotmpl") + if err != nil { + ErrorF("Could not read changelog template file %s", err) + } + Debug("ChangeLog Templates %s", string(changelogTemplate)) + t := template.Must(template.New("changelog").Parse(string(changelogTemplate))) + // create a new file + file, err := os.Create(fmt.Sprintf("charts/ingress-nginx/changelog/Changelog-%s.md", r.NewHelmChartVersion)) + if err != nil { + ErrorF("Could not create changelog file %s", err) + } + defer file.Close() + + err = t.Execute(file, r) + if err != nil { + ErrorF("executing template:", err) + } +} + +func (r ReleaseNote) printRelease() { + Info("Release Version: %v", r.NewControllerVersion) + Info("Previous Version: %v", r.PreviousControllerVersion) + Info("Controller Image: %v", r.ControllerImages[0].print()) + Info("Controller Chroot Image: %v", r.ControllerImages[1].print()) + for i := range r.Updates { + Info("Update #%v - %v", i, r.Updates[i]) + } + for j := range r.DepUpdates { + Info("Dependabot Update #%v - %v", j, r.DepUpdates[j]) + } +} + +func findImageDigest(yaml ImageYamls, image, version string) string { + version = fmt.Sprintf("v%s", version) + Info("Searching Digest for %s:%s", image, version) + for i := range yaml { + if yaml[i].Name == image { + for k, v := range yaml[i].Dmap { + if v[0] == version { + return k + } + } + return "" + } + } + return "" +} + +func downloadFile(url string) (string, error) { + client := &http.Client{ + Transport: &http.Transport{ + DialContext: (&net.Dialer{ + Timeout: 5 * time.Second, + KeepAlive: 5 * time.Second, + }).DialContext, + TLSHandshakeTimeout: 5 * time.Second, + ResponseHeaderTimeout: 5 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + MaxIdleConnsPerHost: -1, + }, + } + resp, err := client.Get(url) + if err != nil { + return "", nil + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return "", errors.New(fmt.Sprintf("Could not retrieve file, response from server %s for file %s", resp.StatusCode, url)) + } + bodyBytes, err := io.ReadAll(resp.Body) + if err != nil { + return "", nil + } + return string(bodyBytes), nil +} + +// Latest returns latest Github Release +func (Release) Latest() error { + r, _, err := latestRelease() + if err != nil { + ErrorF("Latest Release error %s", err) + return err + } + Info("Latest Release %v", r.String()) + return nil +} + +func (Release) ReleaseByTag(tag string) error { + r, _, err := releaseByTag(tag) + if err != nil { + ErrorF("Release retrieve tag error %s", tag, err) + return err + } + + Info("Latest Release %v", r.String()) + + return nil +} + +func releaseByTag(tag string) (*github.RepositoryRelease, *github.Response, error) { + ghClient := githubClient() + return ghClient.Repositories.GetReleaseByTag(ctx, INGRESS_ORG, INGRESS_REPO, tag) +} + +func latestRelease() (*github.RepositoryRelease, *github.Response, error) { + ghClient := githubClient() + return ghClient.Repositories.GetLatestRelease(ctx, INGRESS_ORG, INGRESS_REPO) +} + +// Copy Test function to copy a release +func (Release) Copy() error { + ghClient := githubClient() + kRelease, _, err := ghClient.Repositories.GetLatestRelease(ctx, "kubernetes", "ingress-nginx") + if err != nil { + ErrorF("Get Release from kubernetes %s", err) + return err + } + + sRelease := &github.RepositoryRelease{ + TagName: kRelease.TagName, + Name: kRelease.Name, + Body: kRelease.Body, + Draft: kRelease.Draft, + Prerelease: kRelease.GenerateReleaseNotes, + DiscussionCategoryName: kRelease.DiscussionCategoryName, + GenerateReleaseNotes: kRelease.GenerateReleaseNotes, + } + + sRelease, _, err = ghClient.Repositories.CreateRelease(ctx, "strongjz", "ingress-nginx", sRelease) + if err != nil { + ErrorF("Creating Strongjz release %s", err) + return err + } + Info("Copied over Kubernetes Release %v to Strongjz %v", &kRelease.Name, &sRelease.Name) + return nil +} diff --git a/magefiles/tags.go b/magefiles/tags.go new file mode 100644 index 000000000..02bbbcb37 --- /dev/null +++ b/magefiles/tags.go @@ -0,0 +1,146 @@ +//go:build mage + +/* +Copyright 2023 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 main + +import ( + "fmt" + semver "github.com/blang/semver/v4" + "github.com/magefile/mage/mg" + "github.com/magefile/mage/sh" + "os" + "strings" +) + +type Tag mg.Namespace + +var git = sh.OutCmd("git") + +// Nginx returns the ingress-nginx current version +func (Tag) Nginx() { + tag, err := getIngressNGINXVersion() + CheckIfError(err, "") + fmt.Printf("%v", tag) +} + +func getIngressNGINXVersion() (string, error) { + dat, err := os.ReadFile("TAG") + CheckIfError(err, "Could not read TAG file") + datString := string(dat) + //remove newline + datString = strings.Replace(datString, "\n", "", -1) + return datString, nil +} + +func checkSemVer(currentVersion, newVersion string) bool { + Info("Checking Sem Ver between current %s and new %s", currentVersion, newVersion) + cVersion, err := semver.Make(currentVersion[1:]) + if err != nil { + ErrorF("TAG Error Current Tag %v Making Semver : %v", currentVersion[1:], err) + return false + } + nVersion, err := semver.Make(newVersion) + if err != nil { + ErrorF("TAG %v Error Making Semver %v \n", newVersion, err) + return false + } + + err = nVersion.Validate() + if err != nil { + ErrorF("TAG %v not a valid Semver %v \n", newVersion, err) + return false + } + + //The result will be + //0 if newVersion == currentVersion + //-1 if newVersion < currentVersion + //+1 if newVersion > currentVersion. + Info("TAG Comparing Old %s to New %s", cVersion.String(), nVersion.String()) + comp := nVersion.Compare(cVersion) + if comp <= 0 { + Warning("SemVer:%v is not an update\n", newVersion) + return false + } + return true +} + +// BumpNginx will update the nginx TAG +func (Tag) BumpNginx(newTag string) { + Info("TAG BumpNginx version %v", newTag) + currentTag, err := getIngressNGINXVersion() + CheckIfError(err, "Getting Ingress-nginx Version") + bump(currentTag, newTag) +} + +func bump(currentTag, newTag string) { + //check if semver is valid + if !checkSemVer(currentTag, newTag) { + ErrorF("ERROR: Semver is not valid %v", newTag) + os.Exit(1) + } + + Info("Updating Tag %v to %v", currentTag, newTag) + err := os.WriteFile("TAG", []byte(newTag), 0666) + CheckIfError(err, "Error Writing New Tag File") +} + +// Git Returns the latest git tag +func (Tag) Git() { + tag, err := getGitTag() + CheckIfError(err, "Retrieving Git Tag") + Info("Git tag: %v", tag) +} + +func getGitTag() (string, error) { + return git("describe", "--tags", "--match", "controller-v*", "--abbrev=0") +} + +// ControllerTag Creates a new Git Tag for the ingress controller +func (Tag) NewControllerTag(version string) { + Info("Create Ingress Nginx Controller Tag v%s", version) + tag, err := controllerTag(version) + CheckIfError(err, "Creating git tag") + Debug("Git Tag: %s", tag) +} + +func controllerTag(version string) (string, error) { + return git("tag", "-a", "-m", fmt.Sprintf("-m \"Automated Controller release %v\"", version), fmt.Sprintf("controller-v%s", version)) +} + +func (Tag) AllControllerTags() { + tags := getAllControllerTags() + for i, s := range tags { + Info("#%v Version %v", i, s) + } +} + +func getAllControllerTags() []string { + allControllerTags, err := git("tag", "-l", "--sort=-v:refname", "controller-v*") + CheckIfError(err, "Retrieving git tags") + if !sh.CmdRan(err) { + Warning("Issue Running Command") + } + if allControllerTags == "" { + Warning("All Controller Tags is empty") + } + Debug("Controller Tags: %v", allControllerTags) + + temp := strings.Split(allControllerTags, "\n") + Debug("There are %v controller tags", len(temp)) + return temp +} diff --git a/magefiles/yaml.go b/magefiles/yaml.go new file mode 100644 index 000000000..d7c7f588e --- /dev/null +++ b/magefiles/yaml.go @@ -0,0 +1,19 @@ +//go:build mage + +/* +Copyright 2023 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 main diff --git a/mkdocs.yml b/mkdocs.yml index c76a640f6..39eab9ef0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,4 +1,4 @@ -site_name: NGINX Ingress Controller +site_name: Ingress-Nginx Controller repo_name: "kubernetes/ingress-nginx" repo_url: https://github.com/kubernetes/ingress-nginx site_url: https://kubernetes.github.io/ingress-nginx @@ -101,6 +101,7 @@ nav: - Third party addons: - ModSecurity Web Application Firewall: "user-guide/third-party-addons/modsecurity.md" - OpenTracing: "user-guide/third-party-addons/opentracing.md" + - OpenTelemetry: "user-guide/third-party-addons/opentelemetry.md" - Examples: - Introduction: "examples/index.md" - Prerequisites: "examples/PREREQUISITES.md" diff --git a/pkg/apis/ingress/types.go b/pkg/apis/ingress/types.go index 9395683ec..e50666c18 100644 --- a/pkg/apis/ingress/types.go +++ b/pkg/apis/ingress/types.go @@ -29,12 +29,12 @@ import ( "k8s.io/ingress-nginx/internal/ingress/annotations/cors" "k8s.io/ingress-nginx/internal/ingress/annotations/fastcgi" "k8s.io/ingress-nginx/internal/ingress/annotations/globalratelimit" - "k8s.io/ingress-nginx/internal/ingress/annotations/influxdb" "k8s.io/ingress-nginx/internal/ingress/annotations/ipdenylist" "k8s.io/ingress-nginx/internal/ingress/annotations/ipwhitelist" "k8s.io/ingress-nginx/internal/ingress/annotations/log" "k8s.io/ingress-nginx/internal/ingress/annotations/mirror" "k8s.io/ingress-nginx/internal/ingress/annotations/modsecurity" + "k8s.io/ingress-nginx/internal/ingress/annotations/opentelemetry" "k8s.io/ingress-nginx/internal/ingress/annotations/opentracing" "k8s.io/ingress-nginx/internal/ingress/annotations/proxy" "k8s.io/ingress-nginx/internal/ingress/annotations/proxyssl" @@ -337,9 +337,6 @@ type Location struct { // Logs allows to enable or disable the nginx logs // By default access logs are enabled and rewrite logs are disabled Logs log.Config `json:"logs,omitempty"` - // InfluxDB allows to monitor the incoming request by sending them to an influxdb database - // +optional - InfluxDB influxdb.Config `json:"influxDB,omitempty"` // BackendProtocol indicates which protocol should be used to communicate with the service // By default this is HTTP BackendProtocol string `json:"backend-protocol"` @@ -360,6 +357,9 @@ type Location struct { // Opentracing allows the global opentracing setting to be overridden for a location // +optional Opentracing opentracing.Config `json:"opentracing"` + // Opentelemetry allows the global opentelemetry setting to be overridden for a location + // +optional + Opentelemetry opentelemetry.Config `json:"opentelemetry"` } // SSLPassthroughBackend describes a SSL upstream server configured diff --git a/pkg/apis/ingress/types_equals.go b/pkg/apis/ingress/types_equals.go index 0941e0956..84b1a186a 100644 --- a/pkg/apis/ingress/types_equals.go +++ b/pkg/apis/ingress/types_equals.go @@ -76,11 +76,7 @@ func (c1 *Configuration) Equal(c2 *Configuration) bool { } } - if c1.BackendConfigChecksum != c2.BackendConfigChecksum { - return false - } - - return true + return c1.BackendConfigChecksum == c2.BackendConfigChecksum } // Equal tests for equality between two Backend types @@ -435,10 +431,6 @@ func (l1 *Location) Equal(l2 *Location) bool { return false } - if !(&l1.InfluxDB).Equal(&l2.InfluxDB) { - return false - } - if l1.BackendProtocol != l2.BackendProtocol { return false } @@ -468,6 +460,10 @@ func (l1 *Location) Equal(l2 *Location) bool { return false } + if !l1.Opentelemetry.Equal(&l2.Opentelemetry) { + return false + } + if !l1.Mirror.Equal(&l2.Mirror) { return false } diff --git a/pkg/flags/flags.go b/pkg/flags/flags.go index 6e183289c..370510380 100644 --- a/pkg/flags/flags.go +++ b/pkg/flags/flags.go @@ -171,10 +171,11 @@ Requires the update-status parameter.`) reportStatusClasses = flags.Bool("report-status-classes", false, `Use status classes (2xx, 3xx, 4xx and 5xx) instead of status codes in metrics.`) - timeBuckets = flags.Float64Slice("time-buckets", prometheus.DefBuckets, "Set of buckets which will be used for prometheus histogram metrics such as RequestTime, ResponseTime.") - lengthBuckets = flags.Float64Slice("length-buckets", prometheus.LinearBuckets(10, 10, 10), "Set of buckets which will be used for prometheus histogram metrics such as RequestLength, ResponseLength.") - sizeBuckets = flags.Float64Slice("size-buckets", prometheus.ExponentialBuckets(10, 10, 7), "Set of buckets which will be used for prometheus histogram metrics such as BytesSent.") - monitorMaxBatchSize = flags.Int("monitor-max-batch-size", 10000, "Max batch size of NGINX metrics.") + timeBuckets = flags.Float64Slice("time-buckets", prometheus.DefBuckets, "Set of buckets which will be used for prometheus histogram metrics such as RequestTime, ResponseTime.") + lengthBuckets = flags.Float64Slice("length-buckets", prometheus.LinearBuckets(10, 10, 10), "Set of buckets which will be used for prometheus histogram metrics such as RequestLength, ResponseLength.") + sizeBuckets = flags.Float64Slice("size-buckets", prometheus.ExponentialBuckets(10, 10, 7), "Set of buckets which will be used for prometheus histogram metrics such as BytesSent.") + excludeSocketMetrics = flags.StringSlice("exclude-socket-metrics", []string{}, "et of socket request metrics to exclude which won't be exported nor being calculated. E.g. 'nginx_ingress_controller_success,nginx_ingress_controller_header_duration_seconds'.") + monitorMaxBatchSize = flags.Int("monitor-max-batch-size", 10000, "Max batch size of NGINX metrics.") httpPort = flags.Int("http-port", 80, `Port to use for servicing HTTP traffic.`) httpsPort = flags.Int("https-port", 443, `Port to use for servicing HTTPS traffic.`) @@ -216,6 +217,8 @@ Takes the form ":port". If not provided, no admission controller is starte dynamicConfigurationRetries = flags.Int("dynamic-configuration-retries", 15, "Number of times to retry failed dynamic configuration before failing to sync an ingress.") disableSyncEvents = flags.Bool("disable-sync-events", false, "Disables the creation of 'Sync' event resources") + + enableTopologyAwareRouting = flags.Bool("enable-topology-aware-routing", false, "Enable topology aware hints feature, needs service object annotation service.kubernetes.io/topology-aware-hints sets to auto.") ) flags.StringVar(&nginx.MaxmindMirror, "maxmind-mirror", "", `Maxmind mirror url (example: http://geoip.local/databases.`) @@ -326,6 +329,7 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g MetricsPerHost: *metricsPerHost, MetricsBuckets: histogramBuckets, ReportStatusClasses: *reportStatusClasses, + ExcludeSocketMetrics: *excludeSocketMetrics, MonitorMaxBatchSize: *monitorMaxBatchSize, DisableServiceExternalName: *disableServiceExternalName, EnableSSLPassthrough: *enableSSLPassthrough, @@ -348,6 +352,7 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g SyncRateLimit: *syncRateLimit, HealthCheckHost: *healthzHost, DynamicConfigurationRetries: *dynamicConfigurationRetries, + EnableTopologyAwareRouting: *enableTopologyAwareRouting, ListenPorts: &ngx_config.ListenPorts{ Default: *defServerPort, Health: *healthzPort, diff --git a/pkg/tcpproxy/tcp.go b/pkg/tcpproxy/tcp.go index 4c34e1f7b..86850ad54 100644 --- a/pkg/tcpproxy/tcp.go +++ b/pkg/tcpproxy/tcp.go @@ -59,11 +59,12 @@ func (p *TCPProxy) Get(host string) *TCPServer { // and open a connection to the passthrough server. func (p *TCPProxy) Handle(conn net.Conn) { defer conn.Close() - data := make([]byte, 4096) + // See: https://www.ibm.com/docs/en/ztpf/1.1.0.15?topic=sessions-ssl-record-format + data := make([]byte, 16384) length, err := conn.Read(data) if err != nil { - klog.V(4).ErrorS(err, "Error reading the first 4k of the connection") + klog.V(4).ErrorS(err, "Error reading data from the connection") return } diff --git a/pkg/util/file/file_watcher.go b/pkg/util/file/file_watcher.go index eeb7b5721..daf955e52 100644 --- a/pkg/util/file/file_watcher.go +++ b/pkg/util/file/file_watcher.go @@ -72,8 +72,8 @@ func (f *OSFileWatcher) watch() error { for { select { case event := <-watcher.Events: - if event.Op&fsnotify.Create == fsnotify.Create || - event.Op&fsnotify.Write == fsnotify.Write { + if event.Has(fsnotify.Create) || + event.Has(fsnotify.Write) { if finfo, err := os.Lstat(event.Name); err != nil { log.Printf("can not lstat file: %v\n", err) } else if finfo.Mode()&os.ModeSymlink != 0 { diff --git a/pkg/util/ingress/ingress.go b/pkg/util/ingress/ingress.go index 5fb3ee7b9..e69ca7b29 100644 --- a/pkg/util/ingress/ingress.go +++ b/pkg/util/ingress/ingress.go @@ -18,30 +18,15 @@ package ingress import ( "fmt" - "regexp" "strings" - networkingv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/k8s" "k8s.io/ingress-nginx/internal/net/ssl" "k8s.io/ingress-nginx/pkg/apis/ingress" "k8s.io/klog/v2" ) -const ( - alphaNumericChars = `\-\.\_\~a-zA-Z0-9/` - regexEnabledChars = `\^\$\[\]\(\)\{\}\*\+` -) - -var ( - // pathAlphaNumeric is a regex validation of something like "^/[a-zA-Z]+$" on path - pathAlphaNumeric = regexp.MustCompile("^/[" + alphaNumericChars + "]*$").MatchString - // pathRegexEnabled is a regex validation of paths that may contain regex. - pathRegexEnabled = regexp.MustCompile("^/[" + alphaNumericChars + regexEnabledChars + "]*$").MatchString -) - func GetRemovedHosts(rucfg, newcfg *ingress.Configuration) []string { oldSet := sets.NewString() newSet := sets.NewString() @@ -61,7 +46,7 @@ func GetRemovedHosts(rucfg, newcfg *ingress.Configuration) []string { return oldSet.Difference(newSet).List() } -// GetRemovedCertificateSerialNumber extracts the difference of certificates between two configurations +// GetRemovedCertificateSerialNumbers extracts the difference of certificates between two configurations func GetRemovedCertificateSerialNumbers(rucfg, newcfg *ingress.Configuration) []string { oldCertificates := sets.NewString() newCertificates := sets.NewString() @@ -192,7 +177,7 @@ type redirect struct { // BuildRedirects build the redirects of servers based on configurations and certificates func BuildRedirects(servers []*ingress.Server) []*redirect { - names := sets.String{} + names := sets.Set[string]{} redirectServers := make([]*redirect, 0) for _, srv := range servers { @@ -246,13 +231,3 @@ func BuildRedirects(servers []*ingress.Server) []*redirect { return redirectServers } - -// IsSafePath verifies if the path used in ingress object contains only valid characters. -// It will behave differently if regex is enabled or not -func IsSafePath(copyIng *networkingv1.Ingress, path string) bool { - isRegex, _ := parser.GetBoolAnnotation("use-regex", copyIng) - if isRegex { - return pathRegexEnabled(path) - } - return pathAlphaNumeric(path) -} diff --git a/pkg/util/ingress/ingress_test.go b/pkg/util/ingress/ingress_test.go index d829a57f1..24597fb6e 100644 --- a/pkg/util/ingress/ingress_test.go +++ b/pkg/util/ingress/ingress_test.go @@ -17,13 +17,8 @@ limitations under the License. package ingress import ( - "fmt" "testing" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - networkingv1 "k8s.io/api/networking/v1" - "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/pkg/apis/ingress" ) @@ -135,83 +130,3 @@ func TestIsDynamicConfigurationEnough(t *testing.T) { t.Errorf("Expected new config to not change") } } - -func generateDumbIngressforPathTest(regexEnabled bool) *networkingv1.Ingress { - var annotations = make(map[string]string) - regexAnnotation := fmt.Sprintf("%s/use-regex", parser.AnnotationsPrefix) - if regexEnabled { - annotations[regexAnnotation] = "true" - } - return &networkingv1.Ingress{ - ObjectMeta: metav1.ObjectMeta{ - Name: "dumb", - Namespace: "default", - Annotations: annotations, - }, - } -} - -func TestIsSafePath(t *testing.T) { - tests := []struct { - name string - copyIng *networkingv1.Ingress - path string - want bool - }{ - { - name: "should accept valid path with regex disabled", - want: true, - copyIng: generateDumbIngressforPathTest(false), - path: "/xpto/~user/t-e_st.exe", - }, - { - name: "should accept valid path / with regex disabled", - want: true, - copyIng: generateDumbIngressforPathTest(false), - path: "/", - }, - { - name: "should reject invalid path with invalid chars", - want: false, - copyIng: generateDumbIngressforPathTest(false), - path: "/foo/bar/;xpto", - }, - { - name: "should reject regex path when regex is disabled", - want: false, - copyIng: generateDumbIngressforPathTest(false), - path: "/foo/bar/(.+)", - }, - { - name: "should accept valid path / with regex enabled", - want: true, - copyIng: generateDumbIngressforPathTest(true), - path: "/", - }, - { - name: "should accept regex path when regex is enabled", - want: true, - copyIng: generateDumbIngressforPathTest(true), - path: "/foo/bar/(.+)", - }, - { - name: "should reject regex path when regex is enabled but the path is invalid", - want: false, - copyIng: generateDumbIngressforPathTest(true), - path: "/foo/bar/;xpto", - }, - { - name: "should reject regex path when regex is enabled but the path is invalid", - want: false, - copyIng: generateDumbIngressforPathTest(true), - path: ";xpto", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := IsSafePath(tt.copyIng, tt.path); got != tt.want { - t.Errorf("IsSafePath() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/rootfs/Dockerfile-chroot b/rootfs/Dockerfile-chroot index bdb9be60b..7ab8584a7 100644 --- a/rootfs/Dockerfile-chroot +++ b/rootfs/Dockerfile-chroot @@ -23,7 +23,7 @@ RUN apk update \ && apk upgrade \ && /chroot.sh -FROM alpine:3.17.0 +FROM alpine:3.17.2 ARG TARGETARCH ARG VERSION @@ -49,8 +49,8 @@ RUN apk update \ && apk upgrade \ && apk add -U --no-cache \ bash \ - curl \ openssl \ + curl \ ca-certificates \ dumb-init \ tzdata \ diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl old mode 100755 new mode 100644 index fc48de912..9b3a47de3 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -21,10 +21,6 @@ load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so; load_module /etc/nginx/modules/ngx_http_brotli_static_module.so; {{ end }} -{{ if (shouldLoadInfluxDBModule $servers) }} -load_module /etc/nginx/modules/ngx_http_influxdb_module.so; -{{ end }} - {{ if (shouldLoadAuthDigestModule $servers) }} load_module /etc/nginx/modules/ngx_http_auth_digest_module.so; {{ end }} @@ -37,6 +33,10 @@ load_module /etc/nginx/modules/ngx_http_modsecurity_module.so; load_module /etc/nginx/modules/ngx_http_opentracing_module.so; {{ end }} +{{ if (shouldLoadOpentelemetryModule $cfg $servers) }} +load_module /modules_mount/etc/nginx/modules/otel/otel_ngx_module.so; +{{ end }} + daemon off; worker_processes {{ $cfg.WorkerProcesses }}; @@ -64,6 +64,10 @@ events { } http { + {{ if (shouldLoadOpentelemetryModule $cfg $servers) }} + opentelemetry_config {{ $cfg.OpentelemetryConfig }}; + {{ end }} + lua_package_path "/etc/nginx/lua/?.lua;;"; {{ buildLuaSharedDictionaries $cfg $servers }} @@ -184,8 +188,10 @@ http { geoip2 /etc/nginx/geoip/GeoLite2-Country.mmdb { $geoip2_country_code source=$remote_addr country iso_code; $geoip2_country_name source=$remote_addr country names en; + $geoip2_country_geoname_id source=$remote_addr country geoname_id; $geoip2_continent_code source=$remote_addr continent code; $geoip2_continent_name source=$remote_addr continent names en; + $geoip2_continent_geoname_id source=$remote_addr continent geoname_id; } {{ end }} @@ -193,8 +199,10 @@ http { geoip2 /etc/nginx/geoip/GeoIP2-Country.mmdb { $geoip2_country_code source=$remote_addr country iso_code; $geoip2_country_name source=$remote_addr country names en; + $geoip2_country_geoname_id source=$remote_addr country geoname_id; $geoip2_continent_code source=$remote_addr continent code; $geoip2_continent_name source=$remote_addr continent names en; + $geoip2_continent_geoname_id source=$remote_addr continent geoname_id; } {{ end }} @@ -202,7 +210,9 @@ http { geoip2 /etc/nginx/geoip/GeoLite2-City.mmdb { $geoip2_city_country_code source=$remote_addr country iso_code; $geoip2_city_country_name source=$remote_addr country names en; + $geoip2_city_country_geoname_id source=$remote_addr country geoname_id; $geoip2_city source=$remote_addr city names en; + $geoip2_city_geoname_id source=$remote_addr city geoname_id; $geoip2_postal_code source=$remote_addr postal code; $geoip2_dma_code source=$remote_addr location metro_code; $geoip2_latitude source=$remote_addr location latitude; @@ -210,8 +220,10 @@ http { $geoip2_time_zone source=$remote_addr location time_zone; $geoip2_region_code source=$remote_addr subdivisions 0 iso_code; $geoip2_region_name source=$remote_addr subdivisions 0 names en; + $geoip2_region_geoname_id source=$remote_addr subdivisions 0 geoname_id; $geoip2_subregion_code source=$remote_addr subdivisions 1 iso_code; $geoip2_subregion_name source=$remote_addr subdivisions 1 names en; + $geoip2_subregion_geoname_id source=$remote_addr subdivisions 1 geoname_id; } {{ end }} @@ -219,7 +231,9 @@ http { geoip2 /etc/nginx/geoip/GeoIP2-City.mmdb { $geoip2_city_country_code source=$remote_addr country iso_code; $geoip2_city_country_name source=$remote_addr country names en; + $geoip2_city_country_geoname_id source=$remote_addr country geoname_id; $geoip2_city source=$remote_addr city names en; + $geoip2_city_geoname_id source=$remote_addr city geoname_id; $geoip2_postal_code source=$remote_addr postal code; $geoip2_dma_code source=$remote_addr location metro_code; $geoip2_latitude source=$remote_addr location latitude; @@ -227,8 +241,10 @@ http { $geoip2_time_zone source=$remote_addr location time_zone; $geoip2_region_code source=$remote_addr subdivisions 0 iso_code; $geoip2_region_name source=$remote_addr subdivisions 0 names en; + $geoip2_region_geoname_id source=$remote_addr subdivisions 0 geoname_id; $geoip2_subregion_code source=$remote_addr subdivisions 1 iso_code; $geoip2_subregion_name source=$remote_addr subdivisions 1 names en; + $geoip2_subregion_geoname_id source=$remote_addr subdivisions 1 geoname_id; } {{ end }} @@ -322,6 +338,7 @@ http { limit_conn_status {{ $cfg.LimitConnStatusCode }}; {{ buildOpentracing $cfg $servers }} + {{ buildOpentelemetry $cfg $servers }} include /etc/nginx/mime.types; default_type {{ $cfg.DefaultType }}; @@ -336,6 +353,9 @@ http { {{ if $cfg.UseGzip }} gzip on; gzip_comp_level {{ $cfg.GzipLevel }}; + {{- if $cfg.GzipDisable }} + gzip_disable "{{ $cfg.GzipDisable }}"; + {{- end }} gzip_http_version 1.1; gzip_min_length {{ $cfg.GzipMinLength}}; gzip_types {{ $cfg.GzipTypes }}; @@ -692,6 +712,9 @@ http { opentracing off; {{ end }} + {{ if $cfg.EnableOpentelemetry }} + opentelemetry off; + {{ end }} location {{ $healthzURI }} { return 200; } @@ -1060,6 +1083,11 @@ stream { opentracing_propagate_context; {{ end }} + {{ if (or $all.Cfg.EnableOpentelemetry $location.Opentelemetry.Enabled) }} + opentelemetry on; + opentelemetry_propagate; + {{ end }} + access_log off; # Ensure that modsecurity will not run on an internal location as this is not accessible from outside @@ -1177,6 +1205,10 @@ stream { add_header Set-Cookie $auth_cookie; + {{ if $location.CorsConfig.CorsEnabled }} + {{ template "CORS" $location }} + {{ end }} + # Ensure that modsecurity will not run on an internal location as this is not accessible from outside {{ if $all.Cfg.EnableModsecurity }} modsecurity off; @@ -1197,6 +1229,7 @@ stream { set $global_rate_limit_exceeding n; {{ buildOpentracingForLocation $all.Cfg.EnableOpentracing $all.Cfg.OpentracingTrustIncomingSpan $location }} + {{ buildOpentelemetryForLocation $all.Cfg.EnableOpentelemetry $all.Cfg.OpentelemetryTrustIncomingSpan $location }} {{ if $location.Mirror.Source }} mirror {{ $location.Mirror.Source }}; @@ -1341,8 +1374,6 @@ stream { {{ range $limit := $limits }} {{ $limit }}{{ end }} - {{ buildInfluxDB $location.InfluxDB }} - {{ if isValidByteSize $location.Proxy.BodySize true }} client_max_body_size {{ $location.Proxy.BodySize }}; {{ end }} @@ -1513,6 +1544,10 @@ stream { opentracing off; {{ end }} + {{ if $all.Cfg.EnableOpentelemetry }} + opentelemetry off; + {{ end }} + access_log off; return 200; } @@ -1524,6 +1559,10 @@ stream { opentracing off; {{ end }} + {{ if $all.Cfg.EnableOpentelemetry }} + opentelemetry off; + {{ end }} + {{ range $v := $all.NginxStatusIpv4Whitelist }} allow {{ $v }}; {{ end }} diff --git a/test/data/config.json b/test/data/config.json index 5d8a88cbe..d51e1c40b 100644 --- a/test/data/config.json +++ b/test/data/config.json @@ -413,7 +413,7 @@ "secured": false }, "externalAuth": { - "url": "https://httpbin.org/basic-auth/user/passwd", + "url": "https://httpbun.com/basic-auth/user/passwd", "method": "", "sendBody": false }, @@ -59354,7 +59354,7 @@ "secured": false }, "externalAuth": { - "url": "https://httpbin.org/basic-auth/user/passwd", + "url": "https://httpbun.com/basic-auth/user/passwd", "method": "", "sendBody": false }, @@ -60272,4 +60272,4 @@ "failTimeout": 0 }] }] -} \ No newline at end of file +} diff --git a/test/e2e-image/Dockerfile b/test/e2e-image/Dockerfile index ab4ba5026..11abc26b4 100644 --- a/test/e2e-image/Dockerfile +++ b/test/e2e-image/Dockerfile @@ -1,9 +1,10 @@ ARG E2E_BASE_IMAGE FROM ${E2E_BASE_IMAGE} AS BASE -FROM alpine:3.16.2 +FROM alpine:3.17.2 -RUN apk add -U --no-cache \ +RUN apk update \ + && apk upgrade && apk add -U --no-cache \ ca-certificates \ bash \ curl \ diff --git a/test/e2e-image/Makefile b/test/e2e-image/Makefile index f89bf6bf2..011396531 100644 --- a/test/e2e-image/Makefile +++ b/test/e2e-image/Makefile @@ -1,6 +1,6 @@ DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) -E2E_BASE_IMAGE="registry.k8s.io/ingress-nginx/e2e-test-runner:v20221221-controller-v1.5.1-62-g6ffaef32a@sha256:8f025472964cd15ae2d379503aba150565a8d78eb36b41ddfc5f1e3b1ca81a8e" +E2E_BASE_IMAGE ?= "registry.k8s.io/ingress-nginx/e2e-test-runner:v20230314-helm-chart-4.5.2-32-g520384b11@sha256:754c62f9a5efd1ee515ee908ecc16c0c4d1dda96a8cc8019667182a55f3a9035" image: echo "..entered Makefile in /test/e2e-image" diff --git a/test/e2e-image/e2e.sh b/test/e2e-image/e2e.sh index 7b4d56f10..f8ecd5337 100755 --- a/test/e2e-image/e2e.sh +++ b/test/e2e-image/e2e.sh @@ -14,60 +14,39 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -eu NC='\e[0m' BGREEN='\e[32m' -#SLOW_E2E_THRESHOLD=${SLOW_E2E_THRESHOLD:-"5s"} -FOCUS=${FOCUS:-.*} E2E_NODES=${E2E_NODES:-5} E2E_CHECK_LEAKS=${E2E_CHECK_LEAKS:-""} +reportFile="report-e2e-test-suite.xml" ginkgo_args=( - "-randomize-all" - "-flake-attempts=2" - "-fail-fast" - "--show-node-events" + "--fail-fast" + "--flake-attempts=2" + "--junit-report=${reportFile}" + "--nodes=${E2E_NODES}" "--poll-progress-after=180s" -# "-slow-spec-threshold=${SLOW_E2E_THRESHOLD}" - "-succinct" - "-timeout=75m" + "--randomize-all" + "--show-node-events" + "--succinct" + "--timeout=75m" ) -# Variable for the prefix of report filenames -reportFileNamePrefix="report-e2e-test-suite" - -echo -e "${BGREEN}Running e2e test suite (FOCUS=${FOCUS})...${NC}" -ginkgo "${ginkgo_args[@]}" \ - -focus="${FOCUS}" \ - -skip="\[Serial\]|\[MemoryLeak\]" \ - -nodes="${E2E_NODES}" \ - --junit-report=$reportFileNamePrefix.xml \ - /e2e.test -# Create configMap out of a compressed report file for extraction later - -echo -e "${BGREEN}Running e2e test suite with tests that require serial execution...${NC}" -ginkgo "${ginkgo_args[@]}" \ - -focus="\[Serial\]" \ - -skip="\[MemoryLeak\]" \ - --junit-report=$reportFileNamePrefix-serial.xml \ - /e2e.test -# Create configMap out of a compressed report file for extraction later - -if [[ ${E2E_CHECK_LEAKS} != "" ]]; then - echo -e "${BGREEN}Running e2e test suite with tests that check for memory leaks...${NC}" - ginkgo "${ginkgo_args[@]}" \ - -focus="\[MemoryLeak\]" \ - -skip="\[Serial\]" \ - --junit-report=$reportFileNamePrefix-memleak.xml \ - /e2e.test -# Create configMap out of a compressed report file for extraction later +if [ -n "${FOCUS}" ]; then + ginkgo_args+=("--focus=${FOCUS}") fi -for rFile in `ls $reportFileNamePrefix*` -do - gzip -k $rFile - kubectl create cm $rFile.gz --from-file $rFile.gz - kubectl label cm $rFile.gz junitreport=true -done +if [ -z "${E2E_CHECK_LEAKS}" ]; then + ginkgo_args+=("--skip=\[Memory Leak\]") +fi + +echo -e "${BGREEN}Running e2e test suite...${NC}" +(set -x; ginkgo "${ginkgo_args[@]}" /e2e.test) + +# Create configMap out of a compressed report file for extraction later +gzip -k ${reportFile} +kubectl create cm ${reportFile}.gz --from-file ${reportFile}.gz +kubectl label cm ${reportFile}.gz junitreport=true diff --git a/test/e2e-image/namespace-overlays/topology/values.yaml b/test/e2e-image/namespace-overlays/topology/values.yaml new file mode 100644 index 000000000..5e27f7902 --- /dev/null +++ b/test/e2e-image/namespace-overlays/topology/values.yaml @@ -0,0 +1,34 @@ +# TODO: remove the need to use fullnameOverride +fullnameOverride: nginx-ingress +controller: + image: + repository: ingress-controller/controller + chroot: true + tag: 1.0.0-dev + digest: + digestChroot: + scope: + # Necessary to allow the ingress controller to get the topology information from the nodes + enabled: false + config: + worker-processes: "1" + readinessProbe: + initialDelaySeconds: 3 + periodSeconds: 1 + livenessProbe: + initialDelaySeconds: 3 + periodSeconds: 1 + service: + type: NodePort + extraArgs: + # e2e tests do not require information about ingress status + update-status: "false" + terminationGracePeriodSeconds: 1 + admissionWebhooks: + enabled: false + + enableTopologyAwareRouting: true + +rbac: + create: true + scope: false diff --git a/test/e2e/admission/admission.go b/test/e2e/admission/admission.go index bde98fddf..4a4e31980 100644 --- a/test/e2e/admission/admission.go +++ b/test/e2e/admission/admission.go @@ -32,7 +32,7 @@ import ( "k8s.io/ingress-nginx/test/e2e/framework" ) -var _ = framework.IngressNginxDescribe("[Serial] admission controller", func() { +var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller", func() { f := framework.NewDefaultFramework("admission") ginkgo.BeforeEach(func() { @@ -40,11 +40,6 @@ var _ = framework.IngressNginxDescribe("[Serial] admission controller", func() { f.NewSlowEchoDeployment() }) - ginkgo.AfterEach(func() { - err := uninstallChart(f) - assert.Nil(ginkgo.GinkgoT(), err, "uninstalling helm chart") - }) - ginkgo.It("reject ingress with global-rate-limit annotations when memcached is not configured", func() { host := "admission-test" @@ -216,16 +211,6 @@ var _ = framework.IngressNginxDescribe("[Serial] admission controller", func() { }) }) -func uninstallChart(f *framework.Framework) error { - cmd := exec.Command("helm", "uninstall", "--namespace", f.Namespace, "nginx-ingress") - _, err := cmd.CombinedOutput() - if err != nil { - return fmt.Errorf("unexpected error uninstalling ingress-nginx release: %v", err) - } - - return nil -} - const ( validV1Ingress = ` apiVersion: networking.k8s.io/v1 diff --git a/test/e2e/annotations/auth.go b/test/e2e/annotations/auth.go index 1f0f4c3b2..4ca034825 100644 --- a/test/e2e/annotations/auth.go +++ b/test/e2e/annotations/auth.go @@ -21,11 +21,12 @@ import ( "fmt" "net/http" "net/url" - "os/exec" "regexp" "strings" "time" + "golang.org/x/crypto/bcrypt" + "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" @@ -389,10 +390,10 @@ http { assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets), 1, "expected at least one endpoint") assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets[0].Addresses), 1, "expected at least one address ready in the endpoint") - httpbinIP := e.Subsets[0].Addresses[0].IP + httpbunIP := e.Subsets[0].Addresses[0].IP annotations = map[string]string{ - "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/cookies/set/alma/armud", httpbinIP), + "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/cookies/set/alma/armud", httpbunIP), "nginx.ingress.kubernetes.io/auth-signin": "http://$host/auth/start", } @@ -456,21 +457,21 @@ http { var ing *networking.Ingress ginkgo.BeforeEach(func() { - f.NewHttpbinDeployment() + f.NewHttpbunDeployment() - err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBinService, f.Namespace, 1) + err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBunService, f.Namespace, 1) assert.Nil(ginkgo.GinkgoT(), err) - e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBinService, metav1.GetOptions{}) + e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBunService, metav1.GetOptions{}) assert.Nil(ginkgo.GinkgoT(), err) assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets), 1, "expected at least one endpoint") assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets[0].Addresses), 1, "expected at least one address ready in the endpoint") - httpbinIP := e.Subsets[0].Addresses[0].IP + httpbunIP := e.Subsets[0].Addresses[0].IP annotations = map[string]string{ - "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbinIP), + "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbunIP), "nginx.ingress.kubernetes.io/auth-signin": "http://$host/auth/start", } @@ -649,20 +650,20 @@ http { var ing *networking.Ingress ginkgo.BeforeEach(func() { - f.NewHttpbinDeployment() + f.NewHttpbunDeployment() - var httpbinIP string + var httpbunIP string - err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBinService, f.Namespace, 1) + err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBunService, f.Namespace, 1) assert.Nil(ginkgo.GinkgoT(), err) - e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBinService, metav1.GetOptions{}) + e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBunService, metav1.GetOptions{}) assert.Nil(ginkgo.GinkgoT(), err) - httpbinIP = e.Subsets[0].Addresses[0].IP + httpbunIP = e.Subsets[0].Addresses[0].IP annotations = map[string]string{ - "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbinIP), + "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbunIP), "nginx.ingress.kubernetes.io/auth-signin": "http://$host/auth/start", "nginx.ingress.kubernetes.io/auth-signin-redirect-param": "orig", } @@ -728,23 +729,23 @@ http { barPath := "/bar" ginkgo.BeforeEach(func() { - f.NewHttpbinDeployment() + f.NewHttpbunDeployment() - err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBinService, f.Namespace, 1) + err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBunService, f.Namespace, 1) assert.Nil(ginkgo.GinkgoT(), err) framework.Sleep(1 * time.Second) - e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBinService, metav1.GetOptions{}) + e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBunService, metav1.GetOptions{}) assert.Nil(ginkgo.GinkgoT(), err) assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets), 1, "expected at least one endpoint") assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets[0].Addresses), 1, "expected at least one address ready in the endpoint") - httpbinIP := e.Subsets[0].Addresses[0].IP + httpbunIP := e.Subsets[0].Addresses[0].IP annotations := map[string]string{ - "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbinIP), + "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbunIP), "nginx.ingress.kubernetes.io/auth-signin": "http://$host/auth/start", "nginx.ingress.kubernetes.io/auth-cache-key": "fixed", "nginx.ingress.kubernetes.io/auth-cache-duration": "200 201 401 30m", @@ -777,7 +778,7 @@ http { Expect(). Status(http.StatusOK) - err := f.DeleteDeployment(framework.HTTPBinService) + err := f.DeleteDeployment(framework.HTTPBunService) assert.Nil(ginkgo.GinkgoT(), err) framework.Sleep() @@ -797,7 +798,7 @@ http { Expect(). Status(http.StatusOK) - err := f.DeleteDeployment(framework.HTTPBinService) + err := f.DeleteDeployment(framework.HTTPBunService) assert.Nil(ginkgo.GinkgoT(), err) framework.Sleep() @@ -826,7 +827,7 @@ http { Expect(). Status(http.StatusOK) - err := f.DeleteDeployment(framework.HTTPBinService) + err := f.DeleteDeployment(framework.HTTPBunService) assert.Nil(ginkgo.GinkgoT(), err) framework.Sleep() @@ -899,7 +900,8 @@ http { // Auth error func buildSecret(username, password, name, namespace string) *corev1.Secret { - out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput() + //out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput() + out, err := bcrypt.GenerateFromPassword([]byte(password), 14) encpass := fmt.Sprintf("%v:%s\n", username, out) assert.Nil(ginkgo.GinkgoT(), err) @@ -917,7 +919,8 @@ func buildSecret(username, password, name, namespace string) *corev1.Secret { } func buildMapSecret(username, password, name, namespace string) *corev1.Secret { - out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput() + //out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput() + out, err := bcrypt.GenerateFromPassword([]byte(password), 14) assert.Nil(ginkgo.GinkgoT(), err) return &corev1.Secret{ diff --git a/test/e2e/annotations/canary.go b/test/e2e/annotations/canary.go index 893a4dc8b..6dd81fdd8 100644 --- a/test/e2e/annotations/canary.go +++ b/test/e2e/annotations/canary.go @@ -830,6 +830,33 @@ var _ = framework.DescribeAnnotation("canary-*", func() { TestMainlineCanaryDistribution(f, host) }) + + ginkgo.It("should route requests split between mainline and canary if canary weight is 100 and weight total is 200", func() { + host := "foo" + annotations := map[string]string{} + + ing := framework.NewSingleIngress(host, "/", host, + f.Namespace, framework.EchoService, 80, annotations) + f.EnsureIngress(ing) + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, "server_name foo") + }) + + canaryIngName := fmt.Sprintf("%v-canary", host) + canaryAnnotations := map[string]string{ + "nginx.ingress.kubernetes.io/canary": "true", + "nginx.ingress.kubernetes.io/canary-weight": "100", + "nginx.ingress.kubernetes.io/canary-weight-total": "200", + } + + canaryIng := framework.NewSingleIngress(canaryIngName, "/", host, + f.Namespace, canaryService, 80, canaryAnnotations) + f.EnsureIngress(canaryIng) + + TestMainlineCanaryDistribution(f, host) + }) }) ginkgo.Context("Single canary Ingress", func() { diff --git a/test/e2e/annotations/fastcgi.go b/test/e2e/annotations/fastcgi.go index 0dc6ae4a4..572eca548 100644 --- a/test/e2e/annotations/fastcgi.go +++ b/test/e2e/annotations/fastcgi.go @@ -21,7 +21,6 @@ import ( "strings" "github.com/onsi/ginkgo/v2" - "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -81,9 +80,7 @@ var _ = framework.DescribeAnnotation("backend-protocol - FastCGI", func() { }, } - cm, err := f.EnsureConfigMap(configuration) - assert.Nil(ginkgo.GinkgoT(), err, "creating configmap") - assert.NotNil(ginkgo.GinkgoT(), cm, "expected a configmap but none returned") + f.EnsureConfigMap(configuration) host := "fastcgi-params-configmap" diff --git a/test/e2e/annotations/grpc.go b/test/e2e/annotations/grpc.go index 39349e701..046191b21 100644 --- a/test/e2e/annotations/grpc.go +++ b/test/e2e/annotations/grpc.go @@ -125,7 +125,7 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() { ginkgo.It("authorization metadata should be overwritten by external auth response headers", func() { f.NewGRPCBinDeployment() - f.NewHttpbinDeployment() + f.NewHttpbunDeployment() host := "echo" @@ -149,19 +149,19 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() { } f.EnsureService(svc) - err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBinService, f.Namespace, 1) + err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBunService, f.Namespace, 1) assert.Nil(ginkgo.GinkgoT(), err) - e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBinService, metav1.GetOptions{}) + e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBunService, metav1.GetOptions{}) assert.Nil(ginkgo.GinkgoT(), err) assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets), 1, "expected at least one endpoint") assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets[0].Addresses), 1, "expected at least one address ready in the endpoint") - httpbinIP := e.Subsets[0].Addresses[0].IP + httpbunIP := e.Subsets[0].Addresses[0].IP annotations := map[string]string{ - "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/response-headers?authorization=foo", httpbinIP), + "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/response-headers?authorization=foo", httpbunIP), "nginx.ingress.kubernetes.io/auth-response-headers": "Authorization", "nginx.ingress.kubernetes.io/backend-protocol": "GRPC", } diff --git a/test/e2e/annotations/influxdb.go b/test/e2e/annotations/influxdb.go deleted file mode 100644 index 7a52730cf..000000000 --- a/test/e2e/annotations/influxdb.go +++ /dev/null @@ -1,186 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package annotations - -import ( - "bytes" - "context" - "fmt" - "net/http" - "os/exec" - "strings" - "time" - - jsoniter "github.com/json-iterator/go" - "github.com/onsi/ginkgo/v2" - "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/apimachinery/pkg/util/wait" - - "k8s.io/ingress-nginx/test/e2e/framework" -) - -var _ = framework.DescribeAnnotation("influxdb-*", func() { - f := framework.NewDefaultFramework("influxdb") - - ginkgo.BeforeEach(func() { - f.NewInfluxDBDeployment() - f.NewEchoDeployment() - }) - - ginkgo.Context("when influxdb is enabled", func() { - ginkgo.It("should send the request metric to the influxdb server", func() { - ifs := createInfluxDBService(f) - - // Ingress configured with InfluxDB annotations - host := "influxdb.e2e.local" - createInfluxDBIngress( - f, - host, - framework.EchoService, - 80, - map[string]string{ - "nginx.ingress.kubernetes.io/enable-influxdb": "true", - "nginx.ingress.kubernetes.io/influxdb-host": ifs.Spec.ClusterIP, - "nginx.ingress.kubernetes.io/influxdb-port": "8089", - "nginx.ingress.kubernetes.io/influxdb-measurement": "requests", - "nginx.ingress.kubernetes.io/influxdb-servername": "e2e-nginx-srv", - }, - ) - - // Do a request to the echo server ingress that sends metrics - // to the InfluxDB backend. - f.HTTPTestClient(). - GET("/"). - WithHeader("Host", host). - Expect(). - Status(http.StatusOK) - - framework.Sleep(10 * time.Second) - - var measurements string - var err error - - err = wait.Poll(time.Second, time.Minute, func() (bool, error) { - measurements, err = extractInfluxDBMeasurements(f) - if err != nil { - return false, nil - } - return true, nil - }) - assert.Nil(ginkgo.GinkgoT(), err) - - var results map[string][]map[string]interface{} - _ = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(measurements), &results) - - assert.NotEqual(ginkgo.GinkgoT(), len(measurements), 0) - for _, elem := range results["results"] { - assert.NotEqual(ginkgo.GinkgoT(), len(elem), 0) - } - }) - }) -}) - -func createInfluxDBService(f *framework.Framework) *corev1.Service { - service := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: "influxdb", - Namespace: f.Namespace, - }, - Spec: corev1.ServiceSpec{Ports: []corev1.ServicePort{ - { - Name: "udp", - Port: 8089, - TargetPort: intstr.FromInt(8089), - Protocol: "UDP", - }, - }, - Selector: map[string]string{ - "app": "influxdb", - }, - }, - } - - return f.EnsureService(service) -} - -func createInfluxDBIngress(f *framework.Framework, host, service string, port int, annotations map[string]string) { - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, service, port, annotations) - f.EnsureIngress(ing) - - f.WaitForNginxServer(host, - func(server string) bool { - return strings.Contains(server, fmt.Sprintf("server_name %v", host)) - }) -} - -func extractInfluxDBMeasurements(f *framework.Framework) (string, error) { - l, err := f.KubeClientSet.CoreV1().Pods(f.Namespace).List(context.TODO(), metav1.ListOptions{ - LabelSelector: "app=influxdb", - }) - if err != nil { - return "", err - } - - if len(l.Items) == 0 { - return "", err - } - - cmd := "influx -database 'nginx' -execute 'select * from requests' -format 'json' -pretty" - - var pod *corev1.Pod - for _, p := range l.Items { - pod = &p - break - } - - if pod == nil { - return "", fmt.Errorf("no influxdb pods found") - } - - o, err := execInfluxDBCommand(pod, cmd) - if err != nil { - return "", err - } - - return o, nil -} - -func execInfluxDBCommand(pod *corev1.Pod, command string) (string, error) { - var ( - execOut bytes.Buffer - execErr bytes.Buffer - ) - - cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("%v exec --namespace %s %s -- %s", framework.KubectlPath, pod.Namespace, pod.Name, command)) - cmd.Stdout = &execOut - cmd.Stderr = &execErr - - err := cmd.Run() - - if execErr.Len() > 0 { - return "", fmt.Errorf("stderr: %v", execErr.String()) - } - - if err != nil { - return "", fmt.Errorf("could not execute '%s %s': %v", cmd.Path, cmd.Args, err) - } - - return execOut.String(), nil -} diff --git a/test/e2e/annotations/satisfy.go b/test/e2e/annotations/satisfy.go index e75464a9d..758ad21a4 100644 --- a/test/e2e/annotations/satisfy.go +++ b/test/e2e/annotations/satisfy.go @@ -85,15 +85,15 @@ var _ = framework.DescribeAnnotation("satisfy", func() { host := "auth" // setup external auth - f.NewHttpbinDeployment() + f.NewHttpbunDeployment() - err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBinService, f.Namespace, 1) + err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBunService, f.Namespace, 1) assert.Nil(ginkgo.GinkgoT(), err) - e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBinService, metav1.GetOptions{}) + e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBunService, metav1.GetOptions{}) assert.Nil(ginkgo.GinkgoT(), err) - httpbinIP := e.Subsets[0].Addresses[0].IP + httpbunIP := e.Subsets[0].Addresses[0].IP // create basic auth secret at ingress s := f.EnsureSecret(buildSecret("uname", "pwd", "basic-secret", f.Namespace)) @@ -105,7 +105,7 @@ var _ = framework.DescribeAnnotation("satisfy", func() { "nginx.ingress.kubernetes.io/auth-realm": "test basic auth", // annotations for external auth - "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbinIP), + "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbunIP), "nginx.ingress.kubernetes.io/auth-signin": "http://$host/auth/start", // set satisfy any diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go index 57b047230..614dd166a 100644 --- a/test/e2e/e2e.go +++ b/test/e2e/e2e.go @@ -40,6 +40,7 @@ import ( _ "k8s.io/ingress-nginx/test/e2e/leaks" _ "k8s.io/ingress-nginx/test/e2e/loadbalance" _ "k8s.io/ingress-nginx/test/e2e/lua" + _ "k8s.io/ingress-nginx/test/e2e/metrics" _ "k8s.io/ingress-nginx/test/e2e/nginx" _ "k8s.io/ingress-nginx/test/e2e/security" _ "k8s.io/ingress-nginx/test/e2e/servicebackend" diff --git a/test/e2e/endpointslices/topology.go b/test/e2e/endpointslices/topology.go new file mode 100644 index 000000000..7cc67cedb --- /dev/null +++ b/test/e2e/endpointslices/topology.go @@ -0,0 +1,95 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package endpointslices + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strings" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/onsi/ginkgo/v2" + "github.com/stretchr/testify/assert" + + "k8s.io/ingress-nginx/internal/nginx" + "k8s.io/ingress-nginx/test/e2e/framework" +) + +var _ = framework.IngressNginxDescribeSerial("[TopologyHints] topology aware routing", func() { + f := framework.NewDefaultFramework("topology") + host := "topology-svc.foo.com" + + ginkgo.BeforeEach(func() { + f.NewEchoDeployment(framework.WithDeploymentReplicas(2), framework.WithSvcTopologyAnnotations()) + }) + + ginkgo.It("should return 200 when service has topology hints", func() { + + annotations := make(map[string]string) + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) + f.EnsureIngress(ing) + + f.WaitForNginxServer(host, func(server string) bool { + return strings.Contains(server, fmt.Sprintf("server_name %s", host)) + }) + + ginkgo.By("checking if the service is reached") + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", host). + Expect(). + Status(http.StatusOK) + + slices, err := f.KubeClientSet.DiscoveryV1().EndpointSlices(f.Namespace).List(context.TODO(), metav1.ListOptions{ + LabelSelector: "kubernetes.io/service-name=echo", + Limit: 1, + }) + assert.Nil(ginkgo.GinkgoT(), err) + + // check if we have hints, really depends on k8s endpoint slice controller + gotHints := true + for _, ep := range slices.Items[0].Endpoints { + if ep.Hints == nil || len(ep.Hints.ForZones) == 0 { + gotHints = false + break + } + } + + curlCmd := fmt.Sprintf("curl --fail --silent http://localhost:%v/configuration/backends", nginx.StatusPort) + status, err := f.ExecIngressPod(curlCmd) + assert.Nil(ginkgo.GinkgoT(), err) + var backends []map[string]interface{} + json.Unmarshal([]byte(status), &backends) + gotBackends := 0 + for _, bck := range backends { + if strings.Contains(bck["name"].(string), "topology") { + gotBackends = len(bck["endpoints"].([]interface{})) + } + } + + if gotHints { + //we have 2 replics, if there is just one backend it means that we are routing according slices hints to same zone as controller is + assert.Equal(ginkgo.GinkgoT(), 1, gotBackends) + } else { + // two replicas should have two endpoints without topology hints + assert.Equal(ginkgo.GinkgoT(), 2, gotBackends) + } + }) +}) diff --git a/test/e2e/framework/deployment.go b/test/e2e/framework/deployment.go index 3cfe8f360..06dfa0c5e 100644 --- a/test/e2e/framework/deployment.go +++ b/test/e2e/framework/deployment.go @@ -19,6 +19,7 @@ package framework import ( "context" "errors" + "fmt" "os" "time" @@ -36,14 +37,18 @@ const EchoService = "echo" // SlowEchoService name of the deployment for the echo app const SlowEchoService = "slow-echo" -// HTTPBinService name of the deployment for the httpbin app -const HTTPBinService = "httpbin" +// HTTPBunService name of the deployment for the httpbun app +const HTTPBunService = "httpbun" + +// NipService name of external service using nip.io +const NIPService = "external-nip" type deploymentOptions struct { - namespace string - name string - replicas int - image string + namespace string + name string + replicas int + svcAnnotations map[string]string + image string } // WithDeploymentNamespace allows configuring the deployment's namespace @@ -53,6 +58,15 @@ func WithDeploymentNamespace(n string) func(*deploymentOptions) { } } +// WithSvcTopologyAnnotations create svc with topology aware hints sets to auto +func WithSvcTopologyAnnotations() func(*deploymentOptions) { + return func(o *deploymentOptions) { + o.svcAnnotations = map[string]string{ + "service.kubernetes.io/topology-aware-hints": "auto", + } + } +} + // WithDeploymentName allows configuring the deployment's names func WithDeploymentName(n string) func(*deploymentOptions) { return func(o *deploymentOptions) { @@ -73,18 +87,26 @@ func WithName(n string) func(*deploymentOptions) { } } +// WithImage allows configuring the image for the deployments +func WithImage(i string) func(*deploymentOptions) { + return func(o *deploymentOptions) { + o.image = i + } +} + // NewEchoDeployment creates a new single replica deployment of the echo server image in a particular namespace func (f *Framework) NewEchoDeployment(opts ...func(*deploymentOptions)) { options := &deploymentOptions{ namespace: f.Namespace, name: EchoService, replicas: 1, + image: "registry.k8s.io/ingress-nginx/e2e-test-echo@sha256:4938d1d91a2b7d19454460a8c1b010b89f6ff92d2987fd889ac3e8fc3b70d91a", } for _, o := range opts { o(options) } - deployment := newDeployment(options.name, options.namespace, "registry.k8s.io/ingress-nginx/e2e-test-echo@sha256:778ac6d1188c8de8ecabeddd3c37b72c8adc8c712bad2bd7a81fb23a3514934c", 80, int32(options.replicas), + deployment := newDeployment(options.name, options.namespace, options.image, 80, int32(options.replicas), nil, nil, nil, []corev1.VolumeMount{}, []corev1.Volume{}, @@ -95,8 +117,9 @@ func (f *Framework) NewEchoDeployment(opts ...func(*deploymentOptions)) { service := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: options.name, - Namespace: options.namespace, + Name: options.name, + Namespace: options.namespace, + Annotations: options.svcAnnotations, }, Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ @@ -119,6 +142,85 @@ func (f *Framework) NewEchoDeployment(opts ...func(*deploymentOptions)) { assert.Nil(ginkgo.GinkgoT(), err, "waiting for endpoints to become ready") } +// BuildNipHost used to generate a nip host for DNS resolving +func BuildNIPHost(ip string) string { + return fmt.Sprintf("%s.nip.io", ip) +} + +// BuildNIPExternalNameService used to generate a service pointing to nip.io to +// help resolve to an IP address +func BuildNIPExternalNameService(f *Framework, ip, portName string) *corev1.Service { + return &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: NIPService, + Namespace: f.Namespace, + }, + Spec: corev1.ServiceSpec{ + ExternalName: BuildNIPHost(ip), + Type: corev1.ServiceTypeExternalName, + Ports: []corev1.ServicePort{ + { + Name: portName, + Port: 80, + TargetPort: intstr.FromInt(80), + Protocol: "TCP", + }, + }, + }, + } +} + +// NewHttpbunDeployment creates a new single replica deployment of the httpbun +// server image in a particular namespace we return the ip for testing purposes +func (f *Framework) NewHttpbunDeployment(opts ...func(*deploymentOptions)) string { + options := &deploymentOptions{ + namespace: f.Namespace, + name: HTTPBunService, + replicas: 1, + image: "registry.k8s.io/ingress-nginx/e2e-test-httpbun:v20230505-v0.0.1", + } + for _, o := range opts { + o(options) + } + + deployment := newDeployment(options.name, options.namespace, options.image, 80, int32(options.replicas), + nil, nil, nil, + []corev1.VolumeMount{}, + []corev1.Volume{}, + true, + ) + + f.EnsureDeployment(deployment) + + service := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: options.name, + Namespace: options.namespace, + Annotations: options.svcAnnotations, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "http", + Port: 80, + TargetPort: intstr.FromInt(80), + Protocol: corev1.ProtocolTCP, + }, + }, + Selector: map[string]string{ + "app": options.name, + }, + }, + } + + s := f.EnsureService(service) + + err := WaitForEndpoints(f.KubeClientSet, DefaultTimeout, options.name, options.namespace, options.replicas) + assert.Nil(ginkgo.GinkgoT(), err, "waiting for endpoints to become ready") + + return s.Spec.ClusterIPs[0] +} + // NewSlowEchoDeployment creates a new deployment of the slow echo server image in a particular namespace. func (f *Framework) NewSlowEchoDeployment() { cfg := `# @@ -408,11 +510,6 @@ func newDeployment(name, namespace, image string, port int32, replicas int32, co return d } -// NewHttpbinDeployment creates a new single replica deployment of the httpbin image in a particular namespace. -func (f *Framework) NewHttpbinDeployment() { - f.NewDeployment(HTTPBinService, "registry.k8s.io/ingress-nginx/e2e-test-httpbin@sha256:c6372ef57a775b95f18e19d4c735a9819f2e7bb4641e5e3f27287d831dfeb7e8", 80, 1) -} - func (f *Framework) NewDeployment(name, image string, port int32, replicas int32) { f.NewDeploymentWithOpts(name, image, port, replicas, nil, nil, nil, nil, nil, true) } diff --git a/test/e2e/framework/exec.go b/test/e2e/framework/exec.go index 8c8c7ddb0..d91d36551 100644 --- a/test/e2e/framework/exec.go +++ b/test/e2e/framework/exec.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "io" + "os" "os/exec" "regexp" "strconv" @@ -111,7 +112,11 @@ func (f *Framework) NamespaceContent() (string, error) { // newIngressController deploys a new NGINX Ingress controller in a namespace func (f *Framework) newIngressController(namespace string, namespaceOverlay string) error { // Creates an nginx deployment - cmd := exec.Command("./wait-for-nginx.sh", namespace, namespaceOverlay) + isChroot, ok := os.LookupEnv("IS_CHROOT") + if !ok { + isChroot = "false" + } + cmd := exec.Command("./wait-for-nginx.sh", namespace, namespaceOverlay, isChroot) out, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("unexpected error waiting for ingress controller deployment: %v.\nLogs:\n%v", err, string(out)) @@ -152,6 +157,16 @@ func (f *Framework) KubectlProxy(port int) (int, *exec.Cmd, error) { return -1, cmd, fmt.Errorf("failed to parse port from proxy stdout: %s", output) } +func (f *Framework) UninstallChart() error { + cmd := exec.Command("helm", "uninstall", "--namespace", f.Namespace, "nginx-ingress") + _, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("unexpected error uninstalling ingress-nginx release: %v", err) + } + + return nil +} + func startCmdAndStreamOutput(cmd *exec.Cmd) (stdout, stderr io.ReadCloser, err error) { stdout, err = cmd.StdoutPipe() if err != nil { diff --git a/test/e2e/framework/fastcgi_helloserver.go b/test/e2e/framework/fastcgi_helloserver.go index c3e89c7f5..719048c06 100644 --- a/test/e2e/framework/fastcgi_helloserver.go +++ b/test/e2e/framework/fastcgi_helloserver.go @@ -58,7 +58,7 @@ func (f *Framework) NewNewFastCGIHelloServerDeploymentWithReplicas(replicas int3 Containers: []corev1.Container{ { Name: "fastcgi-helloserver", - Image: "registry.k8s.io/ingress-nginx/e2e-test-fastcgi-helloserver@sha256:723b8187e1768d199b93fd939c37c1ce9427dcbca72ec6415f4d890bca637fcc", + Image: "registry.k8s.io/ingress-nginx/e2e-test-fastcgi-helloserver@sha256:0e08c836cc58f1ea862578de99b13bc4264fe071e816f96dc1d79857bfba7473", Env: []corev1.EnvVar{}, Ports: []corev1.ContainerPort{ { diff --git a/test/e2e/framework/framework.go b/test/e2e/framework/framework.go index 662cd0879..cac6dfd20 100644 --- a/test/e2e/framework/framework.go +++ b/test/e2e/framework/framework.go @@ -150,7 +150,11 @@ func (f *Framework) AfterEach() { defer func(kubeClient kubernetes.Interface, ingressclass string) { defer ginkgo.GinkgoRecover() - err := deleteIngressClass(kubeClient, ingressclass) + + err := f.UninstallChart() + assert.Nil(ginkgo.GinkgoT(), err, "uninstalling helm chart") + + err = deleteIngressClass(kubeClient, ingressclass) assert.Nil(ginkgo.GinkgoT(), err, "deleting IngressClass") }(f.KubeClientSet, f.IngressClass) @@ -192,6 +196,11 @@ func IngressNginxDescribe(text string, body func()) bool { return ginkgo.Describe(text, body) } +// IngressNginxDescribeSerial wrapper function for ginkgo describe. Adds namespacing. +func IngressNginxDescribeSerial(text string, body func()) bool { + return ginkgo.Describe(text, ginkgo.Serial, body) +} + // DescribeAnnotation wrapper function for ginkgo describe. Adds namespacing. func DescribeAnnotation(text string, body func()) bool { return ginkgo.Describe("[Annotations] "+text, body) @@ -202,11 +211,6 @@ func DescribeSetting(text string, body func()) bool { return ginkgo.Describe("[Setting] "+text, body) } -// MemoryLeakIt is wrapper function for ginkgo It. Adds "[MemoryLeak]" tag and makes static analysis easier. -func MemoryLeakIt(text string, body interface{}) bool { - return ginkgo.It(text+" [MemoryLeak]", body) -} - // GetNginxIP returns the number of TCP port where NGINX is running func (f *Framework) GetNginxIP() string { s, err := f.KubeClientSet. @@ -387,7 +391,7 @@ func (f *Framework) UpdateNginxConfigMapData(key string, value string) { } // WaitForReload calls the passed function and -// asser it has caused at least 1 reload. +// asserts it has caused at least 1 reload. func (f *Framework) WaitForReload(fn func()) { initialReloadCount := getReloadCount(f.pod, f.Namespace, f.KubeClientSet) diff --git a/test/e2e/framework/healthz.go b/test/e2e/framework/healthz.go index bef093355..b52c3ffde 100644 --- a/test/e2e/framework/healthz.go +++ b/test/e2e/framework/healthz.go @@ -26,7 +26,7 @@ func (f *Framework) VerifyHealthz(ip string, statusCode int) error { url := fmt.Sprintf("http://%v:10254/healthz", ip) client := &http.Client{} - req, err := http.NewRequest("GET", url, nil) + req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { return fmt.Errorf("creating GET request for URL %q failed: %v", url, err) } diff --git a/test/e2e/framework/influxdb.go b/test/e2e/framework/influxdb.go deleted file mode 100644 index c3c0e3421..000000000 --- a/test/e2e/framework/influxdb.go +++ /dev/null @@ -1,143 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package framework - -import ( - "github.com/onsi/ginkgo/v2" - "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/apimachinery/pkg/fields" -) - -const influxConfig = ` -reporting-disabled = true -bind-address = "0.0.0.0:8088" - -[meta] - dir = "/var/lib/influxdb/meta" - retention-autocreate = true - logging-enabled = true - -[data] - dir = "/var/lib/influxdb/data" - index-version = "inmem" - wal-dir = "/var/lib/influxdb/wal" - wal-fsync-delay = "0s" - query-log-enabled = true - cache-max-memory-size = 1073741824 - cache-snapshot-memory-size = 26214400 - cache-snapshot-write-cold-duration = "10m0s" - compact-full-write-cold-duration = "4h0m0s" - max-series-per-database = 1000000 - max-values-per-tag = 100000 - max-concurrent-compactions = 0 - trace-logging-enabled = false - -[[udp]] - enabled = true - bind-address = ":8089" - database = "nginx" -` - -// NewInfluxDBDeployment creates an InfluxDB server configured to reply -// on 8086/tcp and 8089/udp -func (f *Framework) NewInfluxDBDeployment() { - configuration := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "influxdb-config", - Namespace: f.Namespace, - }, - Data: map[string]string{ - "influxd.conf": influxConfig, - }, - } - - cm, err := f.EnsureConfigMap(configuration) - assert.Nil(ginkgo.GinkgoT(), err, "creating an Influxdb deployment") - assert.NotNil(ginkgo.GinkgoT(), cm, "expected a configmap but none returned") - - deployment := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "influxdb", - Namespace: f.Namespace, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: NewInt32(1), - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "app": "influxdb", - }, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - "app": "influxdb", - }, - }, - Spec: corev1.PodSpec{ - TerminationGracePeriodSeconds: NewInt64(0), - Volumes: []corev1.Volume{ - { - Name: "influxdb-config", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "influxdb-config", - }, - }, - }, - }, - }, - Containers: []corev1.Container{ - { - Name: "influxdb", - Image: "docker.io/influxdb:1.5", - Env: []corev1.EnvVar{}, - Command: []string{"influxd", "-config", "/influxdb-config/influxd.conf"}, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "influxdb-config", - ReadOnly: true, - MountPath: "/influxdb-config", - }, - }, - Ports: []corev1.ContainerPort{ - { - Name: "http", - ContainerPort: 8086, - }, - { - Name: "udp", - ContainerPort: 8089, - }, - }, - }, - }, - }, - }, - }, - } - - d := f.EnsureDeployment(deployment) - - err = waitForPodsReady(f.KubeClientSet, DefaultTimeout, 1, f.Namespace, metav1.ListOptions{ - LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(), - }) - assert.Nil(ginkgo.GinkgoT(), err, "waiting for influxdb pod to become ready") -} diff --git a/test/e2e/framework/k8s.go b/test/e2e/framework/k8s.go index ef9c522d6..fc3e59b08 100644 --- a/test/e2e/framework/k8s.go +++ b/test/e2e/framework/k8s.go @@ -25,9 +25,7 @@ import ( "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/assert" appsv1 "k8s.io/api/apps/v1" - api "k8s.io/api/core/v1" core "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" networking "k8s.io/api/networking/v1" k8sErrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -36,8 +34,8 @@ import ( "k8s.io/client-go/kubernetes" ) -// EnsureSecret creates a Secret object or returns it if it already exists. -func (f *Framework) EnsureSecret(secret *api.Secret) *api.Secret { +// EnsureSecret creates a Secret object or returns it. +func (f *Framework) EnsureSecret(secret *core.Secret) *core.Secret { err := createSecretWithRetries(f.KubeClientSet, secret.Namespace, secret) assert.Nil(ginkgo.GinkgoT(), err, "creating secret") @@ -48,17 +46,30 @@ func (f *Framework) EnsureSecret(secret *api.Secret) *api.Secret { return s } -// EnsureConfigMap creates a ConfigMap object or returns it if it already exists. -func (f *Framework) EnsureConfigMap(configMap *api.ConfigMap) (*api.ConfigMap, error) { - cm, err := f.KubeClientSet.CoreV1().ConfigMaps(configMap.Namespace).Create(context.TODO(), configMap, metav1.CreateOptions{}) - if err != nil { - if k8sErrors.IsAlreadyExists(err) { - return f.KubeClientSet.CoreV1().ConfigMaps(configMap.Namespace).Update(context.TODO(), configMap, metav1.UpdateOptions{}) - } - return nil, err +// GetConfigMap gets a ConfigMap object from the given namespace, name and returns it, throws error if it does not exist. +func (f *Framework) GetConfigMap(namespace string, name string) *core.ConfigMap { + cm, err := f.KubeClientSet.CoreV1().ConfigMaps(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + assert.Nil(ginkgo.GinkgoT(), err, "getting configmap") + assert.NotNil(ginkgo.GinkgoT(), cm, "expected a configmap but none returned") + return cm +} + +// EnsureConfigMap creates or updates an existing ConfigMap object or returns it. +func (f *Framework) EnsureConfigMap(configMap *core.ConfigMap) *core.ConfigMap { + cm := configMap.DeepCopy() + // Clean out ResourceVersion field if present + if cm.ObjectMeta.ResourceVersion != "" { + cm.ObjectMeta.ResourceVersion = "" } - return cm, nil + res, err := f.KubeClientSet.CoreV1().ConfigMaps(configMap.Namespace).Create(context.TODO(), cm, metav1.CreateOptions{}) + if k8sErrors.IsAlreadyExists(err) { + res, err = f.KubeClientSet.CoreV1().ConfigMaps(configMap.Namespace).Update(context.TODO(), cm, metav1.UpdateOptions{}) + } + assert.Nil(ginkgo.GinkgoT(), err, "updating configmap") + assert.NotNil(ginkgo.GinkgoT(), res, "updating configmap") + + return res } // GetIngress gets an Ingress object from the given namespace, name and returns it, throws error if it does not exists. @@ -293,7 +304,7 @@ func createDeploymentWithRetries(c kubernetes.Interface, namespace string, obj * return retryWithExponentialBackOff(createFunc) } -func createSecretWithRetries(c kubernetes.Interface, namespace string, obj *v1.Secret) error { +func createSecretWithRetries(c kubernetes.Interface, namespace string, obj *core.Secret) error { if obj == nil { return fmt.Errorf("Object provided to create is empty") } @@ -313,7 +324,7 @@ func createSecretWithRetries(c kubernetes.Interface, namespace string, obj *v1.S return retryWithExponentialBackOff(createFunc) } -func createServiceWithRetries(c kubernetes.Interface, namespace string, obj *v1.Service) error { +func createServiceWithRetries(c kubernetes.Interface, namespace string, obj *core.Service) error { if obj == nil { return fmt.Errorf("Object provided to create is empty") } diff --git a/test/e2e/framework/metrics.go b/test/e2e/framework/metrics.go index 349eb4dc3..830237540 100644 --- a/test/e2e/framework/metrics.go +++ b/test/e2e/framework/metrics.go @@ -29,7 +29,7 @@ func (f *Framework) GetMetric(metricName, ip string) (*dto.MetricFamily, error) url := fmt.Sprintf("http://%v:10254/metrics", ip) client := &http.Client{} - req, err := http.NewRequest("GET", url, nil) + req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { return nil, fmt.Errorf("creating GET request for URL %q failed: %v", url, err) } diff --git a/test/e2e/kind.yaml b/test/e2e/kind.yaml index 97dc7082d..07a56dae8 100644 --- a/test/e2e/kind.yaml +++ b/test/e2e/kind.yaml @@ -2,8 +2,14 @@ kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane + labels: + topology.kubernetes.io/zone: zone-1 - role: worker + labels: + topology.kubernetes.io/zone: zone-1 - role: worker + labels: + topology.kubernetes.io/zone: zone-2 kubeadmConfigPatches: - | kind: ClusterConfiguration diff --git a/test/e2e/leaks/lua_ssl.go b/test/e2e/leaks/lua_ssl.go index 8ebd05ccb..e63a1e353 100644 --- a/test/e2e/leaks/lua_ssl.go +++ b/test/e2e/leaks/lua_ssl.go @@ -39,7 +39,7 @@ var _ = framework.IngressNginxDescribe("[Memory Leak] Dynamic Certificates", fun f.NewEchoDeployment() }) - framework.MemoryLeakIt("should not leak memory from ingress SSL certificates or configuration updates", func() { + ginkgo.It("should not leak memory from ingress SSL certificates or configuration updates", func() { hostCount := 1000 iterations := 10 diff --git a/test/e2e/metrics/metrics.go b/test/e2e/metrics/metrics.go new file mode 100644 index 000000000..907b53732 --- /dev/null +++ b/test/e2e/metrics/metrics.go @@ -0,0 +1,94 @@ +/* +Copyright 2023 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 defaultbackend + +import ( + "context" + "fmt" + "net/http" + "strings" + "time" + + "github.com/onsi/ginkgo/v2" + "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 waitForMetrics = 2 * time.Second + +var _ = framework.IngressNginxDescribe("[metrics] exported prometheus metrics", func() { + f := framework.NewDefaultFramework("metrics") + host := "foo.com" + + ginkgo.BeforeEach(func() { + f.NewEchoDeployment() + f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil)) + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, fmt.Sprintf("server_name %s ;", host)) && + strings.Contains(server, "proxy_pass http://upstream_balancer;") + }) + }) + + ginkgo.It("exclude socket request metrics are absent", func() { + err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { + args := deployment.Spec.Template.Spec.Containers[0].Args + args = append(args, "--exclude-socket-metrics=nginx_ingress_controller_request_size,nginx_ingress_controller_header_duration_seconds") + 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 deployment") + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", host). + Expect(). + Status(http.StatusOK) + time.Sleep(waitForMetrics) + + ip := f.GetNginxPodIP() + mf, err := f.GetMetric("nginx_ingress_controller_request_size", ip) + assert.ErrorContains(ginkgo.GinkgoT(), err, "nginx_ingress_controller_request_size") + assert.Nil(ginkgo.GinkgoT(), mf) + }) + ginkgo.It("exclude socket request metrics are present", func() { + err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { + args := deployment.Spec.Template.Spec.Containers[0].Args + args = append(args, "--exclude-socket-metrics=non_existing_metric_does_not_affect_existing_metrics") + 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 deployment") + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", host). + Expect(). + Status(http.StatusOK) + time.Sleep(waitForMetrics) + + ip := f.GetNginxPodIP() + mf, err := f.GetMetric("nginx_ingress_controller_request_size", ip) + assert.Nil(ginkgo.GinkgoT(), err) + assert.NotNil(ginkgo.GinkgoT(), mf) + }) +}) diff --git a/test/e2e/run-chart-test.sh b/test/e2e/run-chart-test.sh index e501ca6fe..6efa63eb2 100755 --- a/test/e2e/run-chart-test.sh +++ b/test/e2e/run-chart-test.sh @@ -62,7 +62,7 @@ export KUBECONFIG="${KUBECONFIG:-$HOME/.kube/kind-config-$KIND_CLUSTER_NAME}" if [ "${SKIP_CLUSTER_CREATION:-false}" = "false" ]; then echo "[dev-env] creating Kubernetes cluster with kind" - export K8S_VERSION=${K8S_VERSION:-v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6} + export K8S_VERSION=${K8S_VERSION:-v1.26.3@sha256:61b92f38dff6ccc29969e7aa154d34e38b89443af1a2c14e6cfbd2df6419c66f} kind create cluster \ --verbosity=${KIND_LOG_LEVEL} \ @@ -78,7 +78,7 @@ fi if [ "${SKIP_IMAGE_CREATION:-false}" = "false" ]; then if ! command -v ginkgo &> /dev/null; then - go get github.com/onsi/ginkgo/v2/ginkgo@v2.6.1 + go install github.com/onsi/ginkgo/v2/ginkgo@v2.9.0 fi echo "[dev-env] building image" make -C ${DIR}/../../ clean-image build image @@ -91,9 +91,16 @@ echo "[dev-env] copying docker images to cluster..." kind load docker-image --name="${KIND_CLUSTER_NAME}" --nodes=${KIND_WORKERS} ${REGISTRY}/controller:${TAG} if [ "${SKIP_CERT_MANAGER_CREATION:-false}" = "false" ]; then + curl -fsSL -o cmctl.tar.gz https://github.com/cert-manager/cert-manager/releases/download/v1.11.1/cmctl-linux-amd64.tar.gz + tar xzf cmctl.tar.gz + chmod +x cmctl + ./cmctl help echo "[dev-env] apply cert-manager ..." - kubectl apply --wait -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.0/cert-manager.yaml - sleep 10 + kubectl apply --wait -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml + kubectl wait --timeout=30s --for=condition=available deployment/cert-manager -n cert-manager + kubectl get validatingwebhookconfigurations cert-manager-webhook -ojson | jq '.webhooks[].clientConfig' + kubectl get endpoints -n cert-manager cert-manager-webhook + ./cmctl check api --wait=2m fi echo "[dev-env] running helm chart e2e tests..." diff --git a/build/run-e2e-suite.sh b/test/e2e/run-e2e-suite.sh similarity index 54% rename from build/run-e2e-suite.sh rename to test/e2e/run-e2e-suite.sh index ae38b5fcc..a3bf589cd 100755 --- a/build/run-e2e-suite.sh +++ b/test/e2e/run-e2e-suite.sh @@ -14,10 +14,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -if ! [ -z "$DEBUG" ]; then +if [ -n "$DEBUG" ]; then set -x +else + trap cleanup EXIT fi +function cleanup { + kubectl delete pod e2e 2>/dev/null || true +} + set -o errexit set -o nounset set -o pipefail @@ -43,19 +49,8 @@ if [ "$missing" = true ]; then exit 1 fi -function cleanup { - kubectl delete pod e2e 2>/dev/null || true -} -trap cleanup EXIT - -E2E_CHECK_LEAKS=${E2E_CHECK_LEAKS:-} -FOCUS=${FOCUS:-.*} - BASEDIR=$(dirname "$0") -NGINX_BASE_IMAGE=$(cat $BASEDIR/../NGINX_BASE) - -export E2E_CHECK_LEAKS -export FOCUS +NGINX_BASE_IMAGE=$(cat $BASEDIR/../../NGINX_BASE) echo -e "${BGREEN}Granting permissions to ingress-nginx e2e service account...${NC}" kubectl create serviceaccount ingress-nginx-e2e || true @@ -65,7 +60,6 @@ kubectl create clusterrolebinding permissive-binding \ --user=kubelet \ --serviceaccount=default:ingress-nginx-e2e || true - VER=$(kubectl version --client=false -o json |jq '.serverVersion.minor |tonumber') if [ $VER -lt 24 ]; then echo -e "${BGREEN}Waiting service account...${NC}"; \ @@ -75,7 +69,6 @@ if [ $VER -lt 24 ]; then done fi - echo -e "Starting the e2e test pod" kubectl run --rm \ @@ -83,44 +76,17 @@ kubectl run --rm \ --restart=Never \ --env="E2E_NODES=${E2E_NODES}" \ --env="FOCUS=${FOCUS}" \ + --env="IS_CHROOT=${IS_CHROOT:-false}"\ --env="E2E_CHECK_LEAKS=${E2E_CHECK_LEAKS}" \ --env="NGINX_BASE_IMAGE=${NGINX_BASE_IMAGE}" \ --overrides='{ "apiVersion": "v1", "spec":{"serviceAccountName": "ingress-nginx-e2e"}}' \ e2e --image=nginx-ingress-controller:e2e # Get the junit-reports stored in the configMaps created during e2etests -echo "Getting the report files out now.." +echo "Getting the report file out now.." reportsDir="test/junitreports" -reportFileName="report-e2e-test-suite" -[ ! -e ${reportsDir} ] && mkdir $reportsDir +reportFile="report-e2e-test-suite.xml.gz" +mkdir -p $reportsDir cd $reportsDir - -# TODO: Seeking Rikatz help here to extract in a loop. Tried things like below without success -#for cmName in `k get cm -l junitreport=true -o json | jq '.items[].binaryData | keys[]' | tr '\"' ' '` -#do -# -# -# kubectl get cm -l junitreport=true -o json | jq -r '[.items[].binaryData | to_entries[] | {"key": .key, "value": .value }] | from_entries' -# - -# Below lines successfully extract the report but they are one line per report. -# We only have 3 ginkgo reports so its ok for now -# But still, ideally this should be a loop as talked about in comments a few lines above -kubectl get cm $reportFileName.xml.gz -o "jsonpath={.binaryData['report-e2e-test-suite\.xml\.gz']}" > $reportFileName.xml.gz.base64 -kubectl get cm $reportFileName-serial.xml.gz -o "jsonpath={.binaryData['report-e2e-test-suite-serial\.xml\.gz']}" > $reportFileName-serial.xml.gz.base64 - -cat $reportFileName.xml.gz.base64 | base64 -d > $reportFileName.xml.gz -cat $reportFileName-serial.xml.gz.base64 | base64 -d > $reportFileName-serial.xml.gz - -gzip -d $reportFileName.xml.gz -gzip -d $reportFileName-serial.xml.gz - -rm *.base64 -cd ../.. - -# TODO Temporary: if condition to check if the memleak cm exists and only then try the extract for the memleak report -# -#kubectl get cm $reportFileName-serial -o "jsonpath={.data['report-e2e-test-suite-memleak\.xml\.gz']}" > $reportFileName-memleak.base64 -#cat $reportFileName-memleak.base64 | base64 -d > $reportFileName-memleak.xml.gz -#gzip -d $reportFileName-memleak.xml.gz -echo "done getting the reports files out.." +kubectl get cm $reportFile -o "jsonpath={.binaryData['${reportFile//\./\\.}']}" | base64 -d | gunzip > ${reportFile%\.gz} +echo "done getting the report file out.." diff --git a/test/e2e/run.sh b/test/e2e/run-kind-e2e.sh similarity index 58% rename from test/e2e/run.sh rename to test/e2e/run-kind-e2e.sh index 17dad6c39..fe7550360 100755 --- a/test/e2e/run.sh +++ b/test/e2e/run-kind-e2e.sh @@ -14,13 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -KIND_LOG_LEVEL="1" - -if ! [ -z $DEBUG ]; then - set -x - KIND_LOG_LEVEL="6" -fi - set -o errexit set -o nounset set -o pipefail @@ -31,45 +24,56 @@ cleanup() { fi kind delete cluster \ - --verbosity=${KIND_LOG_LEVEL} \ - --name ${KIND_CLUSTER_NAME} + --verbosity="${KIND_LOG_LEVEL}" \ + --name "${KIND_CLUSTER_NAME}" } -trap cleanup EXIT +DEBUG=${DEBUG:=false} +if [ "${DEBUG}" = "true" ]; then + set -x + KIND_LOG_LEVEL="6" +else + trap cleanup EXIT +fi + +KIND_LOG_LEVEL="1" +IS_CHROOT="${IS_CHROOT:-false}" export KIND_CLUSTER_NAME=${KIND_CLUSTER_NAME:-ingress-nginx-dev} +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +# 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 +NGINX_BASE_IMAGE=$(cat "$DIR"/../../NGINX_BASE) +export NGINX_BASE_IMAGE=$NGINX_BASE_IMAGE +export DOCKER_CLI_EXPERIMENTAL=enabled +export KUBECONFIG="${KUBECONFIG:-$HOME/.kube/kind-config-$KIND_CLUSTER_NAME}" +SKIP_INGRESS_IMAGE_CREATION="${SKIP_INGRESS_IMAGE_CREATION:-false}" +SKIP_E2E_IMAGE_CREATION="${SKIP_E2E_IMAGE_CREATION:=false}" +SKIP_CLUSTER_CREATION="${SKIP_CLUSTER_CREATION:-false}" if ! command -v kind --version &> /dev/null; then echo "kind is not installed. Use the package manager or visit the official site https://kind.sigs.k8s.io/" exit 1 fi -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -# 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 - -NGINX_BASE_IMAGE=$(cat $DIR/../../NGINX_BASE) - echo "Running e2e with nginx base image ${NGINX_BASE_IMAGE}" -export NGINX_BASE_IMAGE=$NGINX_BASE_IMAGE - -export DOCKER_CLI_EXPERIMENTAL=enabled - -export KUBECONFIG="${KUBECONFIG:-$HOME/.kube/kind-config-$KIND_CLUSTER_NAME}" - -if [ "${SKIP_CLUSTER_CREATION:-false}" = "false" ]; then +if [ "${SKIP_CLUSTER_CREATION}" = "false" ]; then echo "[dev-env] creating Kubernetes cluster with kind" - export K8S_VERSION=${K8S_VERSION:-v1.25.2@sha256:9be91e9e9cdf116809841fc77ebdb8845443c4c72fe5218f3ae9eb57fdb4bace} + export K8S_VERSION=${K8S_VERSION:-v1.26.3@sha256:61b92f38dff6ccc29969e7aa154d34e38b89443af1a2c14e6cfbd2df6419c66f} + + # delete the cluster if it exists + if kind get clusters | grep "${KIND_CLUSTER_NAME}"; then + kind delete cluster --name "${KIND_CLUSTER_NAME}" + fi kind create cluster \ - --verbosity=${KIND_LOG_LEVEL} \ - --name ${KIND_CLUSTER_NAME} \ - --config ${DIR}/kind.yaml \ + --verbosity="${KIND_LOG_LEVEL}" \ + --name "${KIND_CLUSTER_NAME}" \ + --config "${DIR}"/kind.yaml \ --retain \ --image "kindest/node:${K8S_VERSION}" @@ -77,16 +81,26 @@ if [ "${SKIP_CLUSTER_CREATION:-false}" = "false" ]; then 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/v2/ginkgo@v2.6.1 +if [ "${SKIP_INGRESS_IMAGE_CREATION}" = "false" ]; then + echo "[dev-env] building image" + if [ "${IS_CHROOT}" = "true" ]; then + make -C "${DIR}"/../../ clean-image build image-chroot + docker tag ${REGISTRY}/controller-chroot:${TAG} ${REGISTRY}/controller:${TAG} + else + make -C "${DIR}"/../../ clean-image build image + fi + + echo "[dev-env] .. done building controller images" +fi + +if [ "${SKIP_E2E_IMAGE_CREATION}" = "false" ]; then + if ! command -v ginkgo &> /dev/null; then + go install github.com/onsi/ginkgo/v2/ginkgo@v2.9.0 fi - echo "[dev-env] building image" - make -C ${DIR}/../../ clean-image build image image-chroot echo "[dev-env] .. done building controller images" echo "[dev-env] now building e2e-image.." - make -C ${DIR}/../e2e-image image + make -C "${DIR}"/../e2e-image image echo "[dev-env] ..done building e2e-image" fi @@ -95,13 +109,7 @@ KIND_WORKERS=$(kind get nodes --name="${KIND_CLUSTER_NAME}" | grep worker | awk echo "[dev-env] copying docker images to cluster..." -kind load docker-image --name="${KIND_CLUSTER_NAME}" --nodes=${KIND_WORKERS} nginx-ingress-controller:e2e - -if [ "${IS_CHROOT:-false}" = "true" ]; then - docker tag ${REGISTRY}/controller-chroot:${TAG} ${REGISTRY}/controller:${TAG} -fi - -kind load docker-image --name="${KIND_CLUSTER_NAME}" --nodes=${KIND_WORKERS} ${REGISTRY}/controller:${TAG} - +kind load docker-image --name="${KIND_CLUSTER_NAME}" --nodes="${KIND_WORKERS}" nginx-ingress-controller:e2e +kind load docker-image --name="${KIND_CLUSTER_NAME}" --nodes="${KIND_WORKERS}" "${REGISTRY}"/controller:"${TAG}" echo "[dev-env] running e2e tests..." -make -C ${DIR}/../../ e2e-test +make -C "${DIR}"/../../ e2e-test diff --git a/test/e2e/security/invalid_paths.go b/test/e2e/security/invalid_paths.go deleted file mode 100644 index d75aefc2c..000000000 --- a/test/e2e/security/invalid_paths.go +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package security - -import ( - "fmt" - "net/http" - "strings" - - "github.com/onsi/ginkgo/v2" - - "k8s.io/ingress-nginx/test/e2e/framework" -) - -const ( - validPath = "/xpto/~user/t-e_st.exe" - invalidPath = "/foo/bar/;xpto" - regexPath = "/foo/bar/(.+)" - host = "securitytest.com" -) - -var ( - annotationRegex = map[string]string{ - "nginx.ingress.kubernetes.io/use-regex": "true", - } -) - -var _ = framework.IngressNginxDescribe("[Security] validate path fields", func() { - f := framework.NewDefaultFramework("validate-path") - - ginkgo.BeforeEach(func() { - f.NewEchoDeployment() - }) - - ginkgo.It("should accept an ingress with valid path", func() { - - ing := framework.NewSingleIngress(host, validPath, host, f.Namespace, framework.EchoService, 80, nil) - - f.EnsureIngress(ing) - - f.WaitForNginxServer(host, - func(server string) bool { - return strings.Contains(server, fmt.Sprintf("server_name %s ;", host)) - }) - - f.HTTPTestClient(). - GET(validPath). - WithHeader("Host", host). - Expect(). - Status(http.StatusOK) - }) - - ginkgo.It("should drop an ingress with invalid path", func() { - - ing := framework.NewSingleIngress(host, invalidPath, host, f.Namespace, framework.EchoService, 80, nil) - f.EnsureIngress(ing) - - f.WaitForNginxServer(host, - func(server string) bool { - return !strings.Contains(server, fmt.Sprintf("server_name %s ;", host)) - }) - - f.HTTPTestClient(). - GET(invalidPath). - WithHeader("Host", host). - Expect(). - Status(http.StatusNotFound) - }) - - ginkgo.It("should drop an ingress with regex path and regex disabled", func() { - - ing := framework.NewSingleIngress(host, regexPath, host, f.Namespace, framework.EchoService, 80, nil) - f.EnsureIngress(ing) - - f.WaitForNginxServer(host, - func(server string) bool { - return !strings.Contains(server, fmt.Sprintf("server_name %s ;", host)) - }) - - f.HTTPTestClient(). - GET("/foo/bar/lalala"). - WithHeader("Host", host). - Expect(). - Status(http.StatusNotFound) - }) - - ginkgo.It("should accept an ingress with regex path and regex enabled", func() { - - ing := framework.NewSingleIngress(host, regexPath, host, f.Namespace, framework.EchoService, 80, annotationRegex) - f.EnsureIngress(ing) - - f.WaitForNginxServer(host, - func(server string) bool { - return strings.Contains(server, fmt.Sprintf("server_name %s ;", host)) - }) - - f.HTTPTestClient(). - GET("/foo/bar/lalala"). - WithHeader("Host", host). - Expect(). - Status(http.StatusOK) - }) - - ginkgo.It("should reject an ingress with invalid path and regex enabled", func() { - - ing := framework.NewSingleIngress(host, invalidPath, host, f.Namespace, framework.EchoService, 80, annotationRegex) - f.EnsureIngress(ing) - - f.WaitForNginxServer(host, - func(server string) bool { - return !strings.Contains(server, fmt.Sprintf("server_name %s ;", host)) - }) - - f.HTTPTestClient(). - GET(invalidPath). - WithHeader("Host", host). - Expect(). - Status(http.StatusNotFound) - }) -}) diff --git a/test/e2e/security/request_smuggling.go b/test/e2e/security/request_smuggling.go index 9891480dc..786a7a397 100644 --- a/test/e2e/security/request_smuggling.go +++ b/test/e2e/security/request_smuggling.go @@ -50,9 +50,12 @@ server { f.UpdateNginxConfigMapData("http-snippet", snippet) + //TODO: currently using a self hosted HTTPBun instance results in a 499, we + //should move away from using httpbun.com once we have the httpbun + //deployment as part of the framework ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, map[string]string{ - "nginx.ingress.kubernetes.io/auth-signin": "https://httpbin.org/uuid", - "nginx.ingress.kubernetes.io/auth-url": "https://httpbin.org/basic-auth/user/passwd", + "nginx.ingress.kubernetes.io/auth-signin": "https://httpbun.com/bearer/d4bcba7a-0def-4a31-91a7-47e420adf44b", + "nginx.ingress.kubernetes.io/auth-url": "https://httpbun.com/basic-auth/user/passwd", }) f.EnsureIngress(ing) diff --git a/test/e2e/servicebackend/service_externalname.go b/test/e2e/servicebackend/service_externalname.go index 0d121c671..2fd6cd080 100644 --- a/test/e2e/servicebackend/service_externalname.go +++ b/test/e2e/servicebackend/service_externalname.go @@ -29,44 +29,21 @@ import ( 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" "k8s.io/ingress-nginx/internal/nginx" "k8s.io/ingress-nginx/test/e2e/framework" ) -func buildHTTPBinExternalNameService(f *framework.Framework, portName string) *corev1.Service { - return &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: framework.HTTPBinService, - Namespace: f.Namespace, - }, - Spec: corev1.ServiceSpec{ - ExternalName: "httpbin.org", - Type: corev1.ServiceTypeExternalName, - Ports: []corev1.ServicePort{ - { - Name: portName, - Port: 80, - TargetPort: intstr.FromInt(80), - Protocol: "TCP", - }, - }, - }, - } -} - var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { f := framework.NewDefaultFramework("type-externalname") ginkgo.It("works with external name set to incomplete fqdn", func() { f.NewEchoDeployment() - host := "echo" svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: framework.HTTPBinService, + Name: framework.HTTPBunService, Namespace: f.Namespace, }, Spec: corev1.ServiceSpec{ @@ -77,7 +54,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { f.EnsureService(svc) - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, nil) + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBunService, 80, nil) f.EnsureIngress(ing) f.WaitForNginxServer(host, @@ -93,15 +70,19 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { }) ginkgo.It("should return 200 for service type=ExternalName without a port defined", func() { + // This is a workaround so we only depend on a self hosted instance of + // httpbun + ip := f.NewHttpbunDeployment() + host := "echo" svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: framework.HTTPBinService, + Name: framework.NIPService, Namespace: f.Namespace, }, Spec: corev1.ServiceSpec{ - ExternalName: "httpbin.org", + ExternalName: framework.BuildNIPHost(ip), Type: corev1.ServiceTypeExternalName, }, } @@ -109,9 +90,9 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { f.EnsureService(svc) annotations := map[string]string{ - "nginx.ingress.kubernetes.io/upstream-vhost": "httpbin.org", + "nginx.ingress.kubernetes.io/upstream-vhost": framework.BuildNIPHost(ip), } - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, annotations) + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBunService, 80, annotations) f.EnsureIngress(ing) f.WaitForNginxServer(host, @@ -127,15 +108,19 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { }) ginkgo.It("should return 200 for service type=ExternalName with a port defined", func() { + // This is a workaround so we only depend on a self hosted instance of + // httpbun + ip := f.NewHttpbunDeployment() + host := "echo" - svc := buildHTTPBinExternalNameService(f, host) + svc := framework.BuildNIPExternalNameService(f, ip, host) f.EnsureService(svc) annotations := map[string]string{ - "nginx.ingress.kubernetes.io/upstream-vhost": "httpbin.org", + "nginx.ingress.kubernetes.io/upstream-vhost": framework.BuildNIPHost(ip), } - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, annotations) + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBunService, 80, annotations) f.EnsureIngress(ing) f.WaitForNginxServer(host, @@ -155,7 +140,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: framework.HTTPBinService, + Name: framework.HTTPBunService, Namespace: f.Namespace, }, Spec: corev1.ServiceSpec{ @@ -166,7 +151,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { f.EnsureService(svc) - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, nil) + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBunService, 80, nil) f.EnsureIngress(ing) f.WaitForNginxServer(host, @@ -182,18 +167,22 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { }) ginkgo.It("should return 200 for service type=ExternalName using a port name", func() { + // This is a workaround so we only depend on a self hosted instance of + // httpbun + ip := f.NewHttpbunDeployment() + host := "echo" - svc := buildHTTPBinExternalNameService(f, host) + svc := framework.BuildNIPExternalNameService(f, ip, host) f.EnsureService(svc) annotations := map[string]string{ - "nginx.ingress.kubernetes.io/upstream-vhost": "httpbin.org", + "nginx.ingress.kubernetes.io/upstream-vhost": framework.BuildNIPHost(ip), } - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, annotations) + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBunService, 80, annotations) namedBackend := networking.IngressBackend{ Service: &networking.IngressServiceBackend{ - Name: framework.HTTPBinService, + Name: framework.NIPService, Port: networking.ServiceBackendPort{ Name: host, }, @@ -215,22 +204,26 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { }) ginkgo.It("should return 200 for service type=ExternalName using FQDN with trailing dot", func() { + // This is a workaround so we only depend on a self hosted instance of + // httpbun + ip := f.NewHttpbunDeployment() + host := "echo" svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: framework.HTTPBinService, + Name: framework.NIPService, Namespace: f.Namespace, }, Spec: corev1.ServiceSpec{ - ExternalName: "httpbin.org.", + ExternalName: framework.BuildNIPHost(ip), Type: corev1.ServiceTypeExternalName, }, } f.EnsureService(svc) - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, nil) + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBunService, 80, nil) f.EnsureIngress(ing) f.WaitForNginxServer(host, @@ -246,18 +239,23 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { }) ginkgo.It("should update the external name after a service update", func() { + // This is a workaround so we only depend on a self hosted instance of + // httpbun + ip := f.NewHttpbunDeployment() + host := "echo" - svc := buildHTTPBinExternalNameService(f, host) + svc := framework.BuildNIPExternalNameService(f, ip, host) f.EnsureService(svc) annotations := map[string]string{ - "nginx.ingress.kubernetes.io/upstream-vhost": "httpbin.org", + "nginx.ingress.kubernetes.io/upstream-vhost": framework.BuildNIPHost(ip), } - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, annotations) + + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBunService, 80, annotations) namedBackend := networking.IngressBackend{ Service: &networking.IngressServiceBackend{ - Name: framework.HTTPBinService, + Name: framework.NIPService, Port: networking.ServiceBackendPort{ Name: host, }, @@ -281,13 +279,15 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { assert.Contains(ginkgo.GinkgoT(), body, `"X-Forwarded-Host": "echo"`) - svc, err := f.KubeClientSet.CoreV1().Services(f.Namespace).Get(context.TODO(), framework.HTTPBinService, metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "unexpected error obtaining httpbin service") + svc, err := f.KubeClientSet.CoreV1().Services(f.Namespace).Get(context.TODO(), framework.NIPService, metav1.GetOptions{}) + assert.Nil(ginkgo.GinkgoT(), err, "unexpected error obtaining external service") - svc.Spec.ExternalName = "eu.httpbin.org" + ip = f.NewHttpbunDeployment(framework.WithDeploymentName("eu-server")) + + svc.Spec.ExternalName = framework.BuildNIPHost(ip) _, err = f.KubeClientSet.CoreV1().Services(f.Namespace).Update(context.Background(), svc, metav1.UpdateOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "unexpected error updating httpbin service") + assert.Nil(ginkgo.GinkgoT(), err, "unexpected error updating external service") framework.Sleep() @@ -301,18 +301,22 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { assert.Contains(ginkgo.GinkgoT(), body, `"X-Forwarded-Host": "echo"`) - ginkgo.By("checking the service is updated to use eu.httpbin.org") + ginkgo.By("checking the service is updated to use new host") curlCmd := fmt.Sprintf("curl --fail --silent http://localhost:%v/configuration/backends", nginx.StatusPort) output, err := f.ExecIngressPod(curlCmd) assert.Nil(ginkgo.GinkgoT(), err) - assert.Contains(ginkgo.GinkgoT(), output, `{"address":"eu.httpbin.org"`) + assert.Contains(ginkgo.GinkgoT(), output, fmt.Sprintf("{\"address\":\"%s\"", framework.BuildNIPHost(ip))) }) ginkgo.It("should sync ingress on external name service addition/deletion", func() { + // This is a workaround so we only depend on a self hosted instance of + // httpbun + ip := f.NewHttpbunDeployment() + host := "echo" // Create the Ingress first - ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, nil) + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.NIPService, 80, nil) f.EnsureIngress(ing) f.WaitForNginxServer(host, @@ -328,7 +332,7 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { Status(http.StatusServiceUnavailable) // Now create the service - svc := buildHTTPBinExternalNameService(f, host) + svc := framework.BuildNIPExternalNameService(f, ip, host) f.EnsureService(svc) framework.Sleep() @@ -341,9 +345,8 @@ var _ = framework.IngressNginxDescribe("[Service] Type ExternalName", func() { Status(http.StatusOK) // And back to 503 after deleting the service - - err := f.KubeClientSet.CoreV1().Services(f.Namespace).Delete(context.TODO(), framework.HTTPBinService, metav1.DeleteOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "unexpected error deleting httpbin service") + err := f.KubeClientSet.CoreV1().Services(f.Namespace).Delete(context.TODO(), framework.NIPService, metav1.DeleteOptions{}) + assert.Nil(ginkgo.GinkgoT(), err, "unexpected error deleting external service") framework.Sleep() diff --git a/test/e2e/settings/brotli.go b/test/e2e/settings/brotli.go index a07eb6c09..a13678f66 100644 --- a/test/e2e/settings/brotli.go +++ b/test/e2e/settings/brotli.go @@ -33,7 +33,7 @@ var _ = framework.IngressNginxDescribe("brotli", func() { host := "brotli" ginkgo.BeforeEach(func() { - f.NewHttpbinDeployment() + f.NewHttpbunDeployment() }) ginkgo.It("should only compress responses that meet the `brotli-min-length` condition", func() { @@ -43,7 +43,7 @@ var _ = framework.IngressNginxDescribe("brotli", func() { f.UpdateNginxConfigMapData("brotli-types", contentEncoding) f.UpdateNginxConfigMapData("brotli-min-length", strconv.Itoa(brotliMinLength)) - f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBinService, 80, nil)) + f.EnsureIngress(framework.NewSingleIngress(host, "/", host, f.Namespace, framework.HTTPBunService, 80, nil)) f.WaitForNginxConfiguration( func(server string) bool { diff --git a/test/e2e/settings/configmap_change.go b/test/e2e/settings/configmap_change.go index be3ab0b11..3e37b62cd 100644 --- a/test/e2e/settings/configmap_change.go +++ b/test/e2e/settings/configmap_change.go @@ -73,5 +73,9 @@ var _ = framework.DescribeSetting("Configmap change", func() { return strings.ContainsAny(cfg, "error_log /var/log/nginx/error.log debug;") }) assert.NotEqual(ginkgo.GinkgoT(), checksum, newChecksum) + + logs, err := f.NginxLogs() + assert.Nil(ginkgo.GinkgoT(), err, "obtaining nginx logs") + assert.Contains(ginkgo.GinkgoT(), logs, "Backend successfully reloaded") }) }) diff --git a/test/e2e/settings/disable_service_external_name.go b/test/e2e/settings/disable_service_external_name.go index a24cfebde..7f03e5355 100644 --- a/test/e2e/settings/disable_service_external_name.go +++ b/test/e2e/settings/disable_service_external_name.go @@ -50,17 +50,21 @@ var _ = framework.IngressNginxDescribe("[Flag] disable-service-external-name", f }) ginkgo.It("should ignore services of external-name type", func() { - nonexternalhost := "echo-svc.com" externalhost := "echo-external-svc.com" + + ip := f.NewHttpbunDeployment() + svc := framework.BuildNIPExternalNameService(f, ip, "echo") + f.EnsureService(svc) + svcexternal := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "external", Namespace: f.Namespace, }, Spec: corev1.ServiceSpec{ - ExternalName: "httpbin.org", + ExternalName: framework.BuildNIPHost(ip), Type: corev1.ServiceTypeExternalName, }, } diff --git a/test/e2e/settings/global_external_auth.go b/test/e2e/settings/global_external_auth.go index c70b5a9b1..c5964299f 100644 --- a/test/e2e/settings/global_external_auth.go +++ b/test/e2e/settings/global_external_auth.go @@ -50,13 +50,13 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() { ginkgo.BeforeEach(func() { f.NewEchoDeployment() - f.NewHttpbinDeployment() + f.NewHttpbunDeployment() }) ginkgo.Context("when global external authentication is configured", func() { ginkgo.BeforeEach(func() { - globalExternalAuthURL := fmt.Sprintf("http://%s.%s.svc.cluster.local:80/status/401", framework.HTTPBinService, f.Namespace) + globalExternalAuthURL := fmt.Sprintf("http://%s.%s.svc.cluster.local:80/status/401", framework.HTTPBunService, f.Namespace) ginkgo.By("Adding an ingress rule for /foo") fooIng := framework.NewSingleIngress("foo-ingress", fooPath, host, f.Namespace, echoServiceName, 80, nil) @@ -158,7 +158,7 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() { globalExternalAuthCacheKey := "foo" globalExternalAuthCacheDurationSetting := "global-auth-cache-duration" globalExternalAuthCacheDuration := "200 201 401 30m" - globalExternalAuthURL := fmt.Sprintf("http://%s.%s.svc.cluster.local:80/status/200", framework.HTTPBinService, f.Namespace) + globalExternalAuthURL := fmt.Sprintf("http://%s.%s.svc.cluster.local:80/status/200", framework.HTTPBunService, f.Namespace) ginkgo.By("Adding a global-auth-cache-key to configMap") f.SetNginxConfigMapData(map[string]string{ @@ -182,7 +182,7 @@ var _ = framework.DescribeSetting("[Security] global-auth-url", func() { Expect(). Status(http.StatusOK) - err := f.DeleteDeployment(framework.HTTPBinService) + err := f.DeleteDeployment(framework.HTTPBunService) assert.Nil(ginkgo.GinkgoT(), err) framework.Sleep() @@ -307,9 +307,9 @@ http { assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets), 1, "expected at least one endpoint") assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets[0].Addresses), 1, "expected at least one address ready in the endpoint") - httpbinIP := e.Subsets[0].Addresses[0].IP + httpbunIP := e.Subsets[0].Addresses[0].IP - f.UpdateNginxConfigMapData(globalExternalAuthURLSetting, fmt.Sprintf("http://%s/cookies/set/alma/armud", httpbinIP)) + f.UpdateNginxConfigMapData(globalExternalAuthURLSetting, fmt.Sprintf("http://%s/cookies/set/alma/armud", httpbunIP)) ing1 = framework.NewSingleIngress(host, "/", host, f.Namespace, "http-cookie-with-error", 80, nil) f.EnsureIngress(ing1) diff --git a/test/e2e/settings/gzip.go b/test/e2e/settings/gzip.go new file mode 100644 index 000000000..68e80d3a0 --- /dev/null +++ b/test/e2e/settings/gzip.go @@ -0,0 +1,99 @@ +/* +Copyright 2023 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" + + "github.com/onsi/ginkgo/v2" + + "k8s.io/ingress-nginx/internal/ingress/controller/config" + "k8s.io/ingress-nginx/test/e2e/framework" +) + +var _ = framework.DescribeSetting("gzip", func() { + f := framework.NewDefaultFramework("gzip") + + ginkgo.It("should be disabled by default", func() { + f.WaitForNginxConfiguration( + func(cfg string) bool { + return !strings.Contains(cfg, "gzip on;") + }) + }) + + ginkgo.It("should be enabled with default settings", func() { + f.UpdateNginxConfigMapData("use-gzip", "true") + + f.WaitForNginxConfiguration( + func(cfg string) bool { + defaultCfg := config.NewDefault() + return strings.Contains(cfg, "gzip on;") && + strings.Contains(cfg, fmt.Sprintf("gzip_comp_level %d;", defaultCfg.GzipLevel)) && + !strings.Contains(cfg, "gzip_disable") && + strings.Contains(cfg, "gzip_http_version 1.1;") && + strings.Contains(cfg, fmt.Sprintf("gzip_min_length %d;", defaultCfg.GzipMinLength)) && + strings.Contains(cfg, fmt.Sprintf("gzip_types %s;", defaultCfg.GzipTypes)) && + strings.Contains(cfg, "gzip_proxied any;") && + strings.Contains(cfg, "gzip_vary on;") + }) + }) + + ginkgo.It("should set gzip_comp_level to 4", func() { + f.UpdateNginxConfigMapData("use-gzip", "true") + f.UpdateNginxConfigMapData("gzip-level", "4") + + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, "gzip on;") && + strings.Contains(cfg, "gzip_comp_level 4;") + }) + }) + + ginkgo.It("should set gzip_disable to msie6", func() { + f.UpdateNginxConfigMapData("use-gzip", "true") + f.UpdateNginxConfigMapData("gzip-disable", "msie6") + + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, "gzip on;") && + strings.Contains(cfg, `gzip_disable "msie6";`) + }) + }) + + ginkgo.It("should set gzip_min_length to 100", func() { + f.UpdateNginxConfigMapData("use-gzip", "true") + f.UpdateNginxConfigMapData("gzip-min-length", "100") + + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, "gzip on;") && + strings.Contains(cfg, "gzip_min_length 100;") + }) + }) + + ginkgo.It("should set gzip_types to application/javascript", func() { + f.UpdateNginxConfigMapData("use-gzip", "true") + f.UpdateNginxConfigMapData("gzip-types", "application/javascript") + + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, "gzip on;") && + strings.Contains(cfg, "gzip_types application/javascript;") + }) + }) +}) diff --git a/test/e2e/settings/listen_nondefault_ports.go b/test/e2e/settings/listen_nondefault_ports.go index 61a128040..8b5d22f6e 100644 --- a/test/e2e/settings/listen_nondefault_ports.go +++ b/test/e2e/settings/listen_nondefault_ports.go @@ -98,21 +98,21 @@ var _ = framework.IngressNginxDescribe("[Flag] custom HTTP and HTTPS ports", fun ginkgo.Context("when external authentication is configured", func() { ginkgo.It("should set the X-Forwarded-Port header to 443", func() { - f.NewHttpbinDeployment() + f.NewHttpbunDeployment() - err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBinService, f.Namespace, 1) + err := framework.WaitForEndpoints(f.KubeClientSet, framework.DefaultTimeout, framework.HTTPBunService, f.Namespace, 1) assert.Nil(ginkgo.GinkgoT(), err) - e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBinService, metav1.GetOptions{}) + e, err := f.KubeClientSet.CoreV1().Endpoints(f.Namespace).Get(context.TODO(), framework.HTTPBunService, metav1.GetOptions{}) assert.Nil(ginkgo.GinkgoT(), err) assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets), 1, "expected at least one endpoint") assert.GreaterOrEqual(ginkgo.GinkgoT(), len(e.Subsets[0].Addresses), 1, "expected at least one address ready in the endpoint") - httpbinIP := e.Subsets[0].Addresses[0].IP + httpbunIP := e.Subsets[0].Addresses[0].IP annotations := map[string]string{ - "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbinIP), + "nginx.ingress.kubernetes.io/auth-url": fmt.Sprintf("http://%s/basic-auth/user/password", httpbunIP), "nginx.ingress.kubernetes.io/auth-signin": "http://$host/auth/start", } diff --git a/test/e2e/settings/namespace_selector.go b/test/e2e/settings/namespace_selector.go index a23514dca..3bf856566 100644 --- a/test/e2e/settings/namespace_selector.go +++ b/test/e2e/settings/namespace_selector.go @@ -27,7 +27,7 @@ import ( "k8s.io/ingress-nginx/test/e2e/framework" ) -var _ = framework.IngressNginxDescribe("[Flag] watch namespace selector", func() { +var _ = framework.IngressNginxDescribeSerial("[Flag] watch namespace selector", func() { f := framework.NewDefaultFramework("namespace-selector") notMatchedHost, matchedHost := "bar", "foo" var notMatchedNs string @@ -45,7 +45,7 @@ var _ = framework.IngressNginxDescribe("[Flag] watch namespace selector", func() cleanupNamespace := func(ns string) { err := framework.DeleteKubeNamespace(f.KubeClientSet, ns) - assert.Nil(ginkgo.GinkgoT(), err, "deleting temporarily crated namespace") + assert.Nil(ginkgo.GinkgoT(), err, "deleting temporarily created namespace") } ginkgo.BeforeEach(func() { @@ -56,13 +56,6 @@ var _ = framework.IngressNginxDescribe("[Flag] watch namespace selector", func() ginkgo.AfterEach(func() { cleanupNamespace(notMatchedNs) cleanupNamespace(matchedNs) - - // cleanup clusterrole/clusterrolebinding created by installing chart with controller.scope.enabled=false - err := f.KubeClientSet.RbacV1().ClusterRoles().Delete(context.TODO(), "nginx-ingress", metav1.DeleteOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "deleting clusterrole nginx-ingress") - - err = f.KubeClientSet.RbacV1().ClusterRoleBindings().Delete(context.TODO(), "nginx-ingress", metav1.DeleteOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "deleting clusterrolebinging nginx-ingress") }) ginkgo.Context("With specific watch-namespace-selector flags", func() { diff --git a/test/e2e/settings/no_auth_locations.go b/test/e2e/settings/no_auth_locations.go index 70ec3be8f..2fc4b6455 100644 --- a/test/e2e/settings/no_auth_locations.go +++ b/test/e2e/settings/no_auth_locations.go @@ -18,8 +18,8 @@ package settings import ( "fmt" + "golang.org/x/crypto/bcrypt" "net/http" - "os/exec" "strings" "github.com/onsi/ginkgo/v2" @@ -147,7 +147,8 @@ func buildBasicAuthIngressWithSecondPath(host, namespace, secretName, pathName s } func buildSecret(username, password, name, namespace string) *corev1.Secret { - out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput() + //out, err := exec.Command("openssl", "passwd", "-crypt", password).CombinedOutput() + out, err := bcrypt.GenerateFromPassword([]byte(password), 14) assert.Nil(ginkgo.GinkgoT(), err, "creating password") encpass := fmt.Sprintf("%v:%s\n", username, out) diff --git a/test/e2e/settings/ocsp/ocsp.go b/test/e2e/settings/ocsp/ocsp.go index ea137aeb1..483013f59 100644 --- a/test/e2e/settings/ocsp/ocsp.go +++ b/test/e2e/settings/ocsp/ocsp.go @@ -85,7 +85,7 @@ var _ = framework.DescribeSetting("OCSP", func() { cfsslDB, err := os.ReadFile("empty.db") assert.Nil(ginkgo.GinkgoT(), err) - cmap, err := f.EnsureConfigMap(&corev1.ConfigMap{ + f.EnsureConfigMap(&corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "ocspserve", Namespace: f.Namespace, @@ -95,8 +95,6 @@ var _ = framework.DescribeSetting("OCSP", func() { "db-config.json": []byte(`{"driver":"sqlite3","data_source":"/data/empty.db"}`), }, }) - assert.Nil(ginkgo.GinkgoT(), err) - assert.NotNil(ginkgo.GinkgoT(), cmap) d, s := ocspserveDeployment(f.Namespace) f.EnsureDeployment(d) @@ -292,7 +290,7 @@ func ocspserveDeployment(namespace string) (*appsv1.Deployment, *corev1.Service) Containers: []corev1.Container{ { Name: name, - Image: "registry.k8s.io/ingress-nginx/e2e-test-cfssl@sha256:c1b273763048944dd7d22d37adfc65be4fa6a5f6068204292573c6cdc5ea3457", + Image: "registry.k8s.io/ingress-nginx/e2e-test-cfssl@sha256:d02c1e18f573449966999fc850f1fed3d37621bf77797562cbe77ebdb06a66ea", Command: []string{ "/bin/bash", "-c", diff --git a/test/e2e/settings/opentelemetry.go b/test/e2e/settings/opentelemetry.go new file mode 100644 index 000000000..92d202cb3 --- /dev/null +++ b/test/e2e/settings/opentelemetry.go @@ -0,0 +1,119 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package settings + +import ( + "strings" + + "github.com/onsi/ginkgo/v2" + + "k8s.io/ingress-nginx/test/e2e/framework" +) + +const ( + enableOpentelemetry = "enable-opentelemetry" + opentelemetryTrustIncomingSpan = "opentelemetry-trust-incoming-span" + + opentelemetryOperationName = "opentelemetry-operation-name" + opentelemetryLocationOperationName = "opentelemetry-location-operation-name" + opentelemetryConfig = "opentelemetry-config" + opentelemetryConfigPath = "/etc/nginx/opentelemetry.toml" +) + +var _ = framework.IngressNginxDescribe("Configure Opentelemetry", func() { + f := framework.NewDefaultFramework("enable-opentelemetry") + + ginkgo.BeforeEach(func() { + f.NewEchoDeployment() + }) + + ginkgo.AfterEach(func() { + }) + + ginkgo.It("should not exists opentelemetry directive", func() { + config := map[string]string{} + config[enableOpentelemetry] = "false" + f.SetNginxConfigMapData(config) + + f.EnsureIngress(framework.NewSingleIngress(enableOpentelemetry, "/", enableOpentelemetry, f.Namespace, "http-svc", 80, nil)) + + f.WaitForNginxConfiguration( + func(cfg string) bool { + return !strings.Contains(cfg, "opentelemetry on") + }) + }) + + ginkgo.It("should exists opentelemetry directive when is enabled", func() { + config := map[string]string{} + config[enableOpentelemetry] = "true" + config[opentelemetryConfig] = opentelemetryConfigPath + f.SetNginxConfigMapData(config) + + f.EnsureIngress(framework.NewSingleIngress(enableOpentelemetry, "/", enableOpentelemetry, f.Namespace, "http-svc", 80, nil)) + + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, "opentelemetry on") + }) + }) + + ginkgo.It("should include opentelemetry_trust_incoming_spans on directive when enabled", func() { + config := map[string]string{} + config[enableOpentelemetry] = "true" + config[opentelemetryConfig] = opentelemetryConfigPath + config[opentelemetryTrustIncomingSpan] = "true" + f.SetNginxConfigMapData(config) + + f.EnsureIngress(framework.NewSingleIngress(enableOpentelemetry, "/", enableOpentelemetry, f.Namespace, "http-svc", 80, nil)) + + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, "opentelemetry_trust_incoming_spans on") + }) + }) + + ginkgo.It("should not exists opentelemetry_operation_name directive when is empty", func() { + config := map[string]string{} + config[enableOpentelemetry] = "true" + config[opentelemetryConfig] = opentelemetryConfigPath + config[opentelemetryOperationName] = "" + f.SetNginxConfigMapData(config) + + f.EnsureIngress(framework.NewSingleIngress(enableOpentelemetry, "/", enableOpentelemetry, f.Namespace, "http-svc", 80, nil)) + + f.WaitForNginxConfiguration( + func(cfg string) bool { + return !strings.Contains(cfg, "opentelemetry_operation_name") + }) + }) + + ginkgo.It("should exists opentelemetry_operation_name directive when is configured", func() { + config := map[string]string{} + config[enableOpentelemetry] = "true" + config[opentelemetryConfig] = opentelemetryConfigPath + config[opentelemetryOperationName] = "HTTP $request_method $uri" + f.SetNginxConfigMapData(config) + + f.EnsureIngress(framework.NewSingleIngress(enableOpentelemetry, "/", enableOpentelemetry, f.Namespace, "http-svc", 80, nil)) + + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, `opentelemetry_operation_name "HTTP $request_method $uri"`) + }) + }) + +}) diff --git a/test/e2e/settings/ssl_passthrough.go b/test/e2e/settings/ssl_passthrough.go index 77a3c990e..a906a2d11 100644 --- a/test/e2e/settings/ssl_passthrough.go +++ b/test/e2e/settings/ssl_passthrough.go @@ -81,7 +81,7 @@ var _ = framework.IngressNginxDescribe("[Flag] enable-ssl-passthrough", func() { host := "testpassthrough.com" echoName := "echopass" - /* Even with enable-ssl-passthrough enabled, only annotated ingresses may receive the trafic */ + /* Even with enable-ssl-passthrough enabled, only annotated ingresses may receive the traffic */ annotations := map[string]string{ "nginx.ingress.kubernetes.io/ssl-passthrough": "true", } diff --git a/test/e2e/status/update.go b/test/e2e/status/update.go index c9c6ef333..5c6ea4977 100644 --- a/test/e2e/status/update.go +++ b/test/e2e/status/update.go @@ -28,7 +28,7 @@ import ( "github.com/stretchr/testify/assert" appsv1 "k8s.io/api/apps/v1" - apiv1 "k8s.io/api/core/v1" + v1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" @@ -87,7 +87,7 @@ var _ = framework.IngressNginxDescribe("[Status] status update", func() { 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{} + ing.Status.LoadBalancer.Ingress = []v1.IngressLoadBalancerIngress{} _, 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) @@ -121,9 +121,9 @@ var _ = framework.IngressNginxDescribe("[Status] status update", func() { return true, nil }) assert.Nil(ginkgo.GinkgoT(), err, "unexpected error waiting for ingress status") - assert.Equal(ginkgo.GinkgoT(), ing.Status.LoadBalancer.Ingress, ([]apiv1.LoadBalancerIngress{ + assert.Equal(ginkgo.GinkgoT(), ing.Status.LoadBalancer.Ingress, []v1.IngressLoadBalancerIngress{ {IP: "1.1.0.0"}, - })) + }) }) }) diff --git a/test/e2e/tcpudp/tcp.go b/test/e2e/tcpudp/tcp.go index b62134a03..16a633b63 100644 --- a/test/e2e/tcpudp/tcp.go +++ b/test/e2e/tcpudp/tcp.go @@ -21,6 +21,7 @@ import ( "fmt" "net" "net/http" + "regexp" "strings" "time" @@ -36,58 +37,39 @@ import ( var _ = framework.IngressNginxDescribe("[TCP] tcp-services", func() { f := framework.NewDefaultFramework("tcp") + var ip string + + ginkgo.BeforeEach(func() { + ip = f.GetNginxIP() + }) ginkgo.It("should expose a TCP service", func() { f.NewEchoDeployment() - config, err := f.KubeClientSet. - CoreV1(). - ConfigMaps(f.Namespace). - Get(context.TODO(), "tcp-services", metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "unexpected error obtaining tcp-services configmap") - assert.NotNil(ginkgo.GinkgoT(), config, "expected a configmap but none returned") - - if config.Data == nil { - config.Data = map[string]string{} + cm := f.GetConfigMap(f.Namespace, "tcp-services") + cm.Data = map[string]string{ + "8080": fmt.Sprintf("%v/%v:80", f.Namespace, framework.EchoService), } + f.EnsureConfigMap(cm) - config.Data["8080"] = fmt.Sprintf("%v/%v:80", f.Namespace, framework.EchoService) - - _, err = f.KubeClientSet. - CoreV1(). - ConfigMaps(f.Namespace). - Update(context.TODO(), config, metav1.UpdateOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "unexpected error updating configmap") - - svc, err := f.KubeClientSet. - CoreV1(). - Services(f.Namespace). - Get(context.TODO(), "nginx-ingress-controller", metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "unexpected error obtaining ingress-nginx service") - assert.NotNil(ginkgo.GinkgoT(), svc, "expected a service but none returned") - + svc := f.GetService(f.Namespace, "nginx-ingress-controller") svc.Spec.Ports = append(svc.Spec.Ports, corev1.ServicePort{ Name: framework.EchoService, Port: 8080, TargetPort: intstr.FromInt(8080), }) - _, err = f.KubeClientSet. + _, err := f.KubeClientSet. CoreV1(). Services(f.Namespace). Update(context.TODO(), svc, metav1.UpdateOptions{}) assert.Nil(ginkgo.GinkgoT(), err, "unexpected error updating service") - // wait for update and nginx reload and new endpoint is available - framework.Sleep() - f.WaitForNginxConfiguration( func(cfg string) bool { return strings.Contains(cfg, fmt.Sprintf(`ngx.var.proxy_upstream_name="tcp-%v-%v-80"`, f.Namespace, framework.EchoService)) }) - ip := f.GetNginxIP() - f.HTTPTestClient(). GET("/"). WithURL(fmt.Sprintf("http://%v:8080", ip)). @@ -122,44 +104,25 @@ var _ = framework.IngressNginxDescribe("[TCP] tcp-services", func() { } f.EnsureService(externalService) - // Expose the `external name` port on the `ingress-nginx` service - svc, err := f.KubeClientSet. - CoreV1(). - Services(f.Namespace). - Get(context.TODO(), "nginx-ingress-controller", metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "unexpected error obtaining ingress-nginx service") - assert.NotNil(ginkgo.GinkgoT(), svc, "expected a service but none returned") - + // Expose the `external name` port on the `ingress-nginx-controller` service + svc := f.GetService(f.Namespace, "nginx-ingress-controller") svc.Spec.Ports = append(svc.Spec.Ports, corev1.ServicePort{ Name: "dns-svc", Port: 5353, TargetPort: intstr.FromInt(5353), }) - _, err = f.KubeClientSet. + _, err := f.KubeClientSet. CoreV1(). Services(f.Namespace). Update(context.TODO(), svc, metav1.UpdateOptions{}) assert.Nil(ginkgo.GinkgoT(), err, "unexpected error updating service") // Update the TCP configmap to link port 5353 to the DNS external name service - config, err := f.KubeClientSet. - CoreV1(). - ConfigMaps(f.Namespace). - Get(context.TODO(), "tcp-services", metav1.GetOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "unexpected error obtaining tcp-services configmap") - assert.NotNil(ginkgo.GinkgoT(), config, "expected a configmap but none returned") - - if config.Data == nil { - config.Data = map[string]string{} + config := f.GetConfigMap(f.Namespace, "tcp-services") + config.Data = map[string]string{ + "5353": fmt.Sprintf("%v/dns-external-name-svc:5353", f.Namespace), } - - config.Data["5353"] = fmt.Sprintf("%v/dns-external-name-svc:5353", f.Namespace) - - _, err = f.KubeClientSet. - CoreV1(). - ConfigMaps(f.Namespace). - Update(context.TODO(), config, metav1.UpdateOptions{}) - assert.Nil(ginkgo.GinkgoT(), err, "unexpected error updating configmap") + f.EnsureConfigMap(config) // Validate that the generated nginx config contains the expected `proxy_upstream_name` value f.WaitForNginxConfiguration( @@ -168,7 +131,6 @@ var _ = framework.IngressNginxDescribe("[TCP] tcp-services", func() { }) // Execute the test. Use the `external name` service to resolve a domain name. - ip := f.GetNginxIP() resolver := net.Resolver{ PreferGo: true, Dial: func(ctx context.Context, network, address string) (net.Conn, error) { @@ -203,4 +165,57 @@ var _ = framework.IngressNginxDescribe("[TCP] tcp-services", func() { assert.Nil(ginkgo.GinkgoT(), err, "unexpected error from DNS resolver") assert.Contains(ginkgo.GinkgoT(), ips, "8.8.4.4") }) + + ginkgo.It("should reload after an update in the configuration", func() { + + ginkgo.By("setting up a first deployment") + f.NewEchoDeployment(framework.WithDeploymentName("first-service")) + + cm := f.GetConfigMap(f.Namespace, "tcp-services") + cm.Data = map[string]string{ + "8080": fmt.Sprintf("%v/first-service:80", f.Namespace), + } + f.EnsureConfigMap(cm) + + checksumRegex := regexp.MustCompile(`Configuration checksum:\s+(\d+)`) + checksum := "" + + f.WaitForNginxConfiguration( + func(cfg string) bool { + // before returning, extract the current checksum + match := checksumRegex.FindStringSubmatch(cfg) + if len(match) > 0 { + checksum = match[1] + } + + return strings.Contains(cfg, fmt.Sprintf(`ngx.var.proxy_upstream_name="tcp-%v-first-service-80"`, + f.Namespace)) + }) + assert.NotEmpty(ginkgo.GinkgoT(), checksum) + + ginkgo.By("updating the tcp service to a second deployment") + f.NewEchoDeployment(framework.WithDeploymentName("second-service")) + + cm = f.GetConfigMap(f.Namespace, "tcp-services") + cm.Data["8080"] = fmt.Sprintf("%v/second-service:80", f.Namespace) + f.EnsureConfigMap(cm) + + newChecksum := "" + f.WaitForNginxConfiguration( + func(cfg string) bool { + match := checksumRegex.FindStringSubmatch(cfg) + if len(match) > 0 { + newChecksum = match[1] + } + + return strings.Contains(cfg, fmt.Sprintf(`ngx.var.proxy_upstream_name="tcp-%v-second-service-80"`, + f.Namespace)) + }) + assert.NotEqual(ginkgo.GinkgoT(), checksum, newChecksum) + + logs, err := f.NginxLogs() + assert.Nil(ginkgo.GinkgoT(), err, "obtaining nginx logs") + assert.Contains(ginkgo.GinkgoT(), logs, "Backend successfully reloaded") + }) + }) diff --git a/test/e2e/wait-for-nginx.sh b/test/e2e/wait-for-nginx.sh index 190f71e6d..153d348c2 100755 --- a/test/e2e/wait-for-nginx.sh +++ b/test/e2e/wait-for-nginx.sh @@ -23,6 +23,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" export NAMESPACE=$1 export NAMESPACE_OVERLAY=$2 +export IS_CHROOT=$3 echo "deploying NGINX Ingress controller in namespace $NAMESPACE" @@ -46,6 +47,16 @@ metadata: EOF +OTEL_MODULE=$(cat <