diff --git a/.github/workflows/conformance.yml b/.github/workflows/conformance.yml index 9c5eaf9c7f..dc1074899c 100644 --- a/.github/workflows/conformance.yml +++ b/.github/workflows/conformance.yml @@ -24,6 +24,7 @@ jobs: conformance-tests: name: Run Tests runs-on: ubuntu-24.04 + if: ${{ !github.event.pull_request.head.repo.fork || inputs.image != 'plus' }} permissions: contents: write # needed for uploading release artifacts env: @@ -76,6 +77,7 @@ jobs: ngf_prefix=ghcr.io/nginxinc/nginx-gateway-fabric ngf_tag=${{ steps.ngf-meta.outputs.version }} if [ ${{ inputs.enable-experimental }} == "true" ]; then export ENABLE_EXPERIMENTAL=true; fi + export PLUS_USAGE_ENDPOINT=${{ secrets.JWT_PLUS_REPORTING_ENDPOINT }} make generate-static-deployment PLUS_ENABLED=${{ inputs.image == 'plus' && 'true' || 'false' }} PREFIX=${ngf_prefix} TAG=${ngf_tag} working-directory: ./tests @@ -138,7 +140,7 @@ jobs: - name: Setup license file for plus if: ${{ inputs.image == 'plus' }} env: - PLUS_LICENSE: ${{ secrets.JWT_PLUS_REGISTRY }} + PLUS_LICENSE: ${{ secrets.JWT_PLUS_REPORTING }} run: echo "${PLUS_LICENSE}" > license.jwt - name: Setup conformance tests @@ -147,6 +149,7 @@ jobs: ngf_tag=${{ steps.ngf-meta.outputs.version }} if [ ${{ github.event_name }} == "schedule" ]; then export GW_API_VERSION=main; fi if [ ${{ inputs.enable-experimental }} == "true" ]; then export ENABLE_EXPERIMENTAL=true; fi + export PLUS_USAGE_ENDPOINT=${{ secrets.JWT_PLUS_REPORTING_ENDPOINT }} make helm-install-local${{ inputs.image == 'plus' && '-with-plus' || ''}} PREFIX=${ngf_prefix} TAG=${ngf_tag} make deploy-updated-provisioner PREFIX=${ngf_prefix} TAG=${ngf_tag} working-directory: ./tests diff --git a/.github/workflows/docs-build-push.yml b/.github/workflows/docs-build-push.yml index f5f3529579..90bdf6b50a 100644 --- a/.github/workflows/docs-build-push.yml +++ b/.github/workflows/docs-build-push.yml @@ -1,4 +1,4 @@ -name: Build and deploy docs +name: Build and deploy documentation on: workflow_dispatch: inputs: @@ -12,12 +12,23 @@ on: - dev - staging - prod + hugo_theme_override: + description: "Hugo theme version (Leave blank for latest)" + required: false + default: "" + type: string pull_request: branches: - "*" paths: - "site/**" + push: + branches: + - release-1.5 + paths: + - "site/**" + concurrency: group: ${{ github.ref_name }}-docs-push cancel-in-progress: true @@ -43,7 +54,7 @@ jobs: if: ${{ github.event.repository.fork == false && needs.vars.outputs.azure_creds == 'true' }} uses: nginxinc/docs-actions/.github/workflows/docs-build-push.yml@9c59fab05a8131f4d691ba6ea2b6a119f3ef832a # v1.0.7 permissions: - pull-requests: write # needed to write preview url comment to PR + pull-requests: write # Required to add the preview URL comment contents: read with: production_url_path: "/nginx-gateway-fabric" @@ -52,6 +63,9 @@ jobs: docs_build_path: "./site" doc_type: "hugo" environment: ${{ inputs.environment }} + force_hugo_theme_version: ${{ inputs.hugo_theme_override }} + auto_deploy_branch: "release-1.5" + auto_deploy_env: "prod" secrets: AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS_DOCS }} AZURE_KEY_VAULT: ${{ secrets.AZURE_KEY_VAULT_DOCS }} diff --git a/.github/workflows/functional.yml b/.github/workflows/functional.yml index 4e3921a0ce..223a0c4112 100644 --- a/.github/workflows/functional.yml +++ b/.github/workflows/functional.yml @@ -21,6 +21,7 @@ jobs: functional-tests: name: Run Tests runs-on: ubuntu-24.04 + if: ${{ !github.event.pull_request.head.repo.fork || inputs.image != 'plus' }} env: DOCKER_BUILD_SUMMARY: false steps: @@ -103,7 +104,7 @@ jobs: - name: Setup license file for plus if: ${{ inputs.image == 'plus' }} env: - PLUS_LICENSE: ${{ secrets.JWT_PLUS_REGISTRY }} + PLUS_LICENSE: ${{ secrets.JWT_PLUS_REPORTING }} run: echo "${PLUS_LICENSE}" > license.jwt - name: Install cloud-provider-kind @@ -124,6 +125,7 @@ jobs: run: | ngf_prefix=ghcr.io/nginxinc/nginx-gateway-fabric ngf_tag=${{ steps.ngf-meta.outputs.version }} + export PLUS_USAGE_ENDPOINT=${{ secrets.JWT_PLUS_REPORTING_ENDPOINT }} make test${{ inputs.image == 'plus' && '-with-plus' || ''}} PREFIX=${ngf_prefix} TAG=${ngf_tag} GINKGO_LABEL=telemetry GW_SERVICE_TYPE=LoadBalancer CLUSTER_NAME=${{ github.run_id }} CI=true working-directory: ./tests @@ -131,6 +133,7 @@ jobs: run: | ngf_prefix=ghcr.io/nginxinc/nginx-gateway-fabric ngf_tag=${{ steps.ngf-meta.outputs.version }} + export PLUS_USAGE_ENDPOINT=${{ secrets.JWT_PLUS_REPORTING_ENDPOINT }} make test${{ inputs.image == 'plus' && '-with-plus' || ''}} PREFIX=${ngf_prefix} TAG=${ngf_tag} GINKGO_LABEL=graceful-recovery GW_SERVICE_TYPE=LoadBalancer CLUSTER_NAME=${{ github.run_id }} CI=true working-directory: ./tests @@ -138,5 +141,6 @@ jobs: run: | ngf_prefix=ghcr.io/nginxinc/nginx-gateway-fabric ngf_tag=${{ steps.ngf-meta.outputs.version }} + export PLUS_USAGE_ENDPOINT=${{ secrets.JWT_PLUS_REPORTING_ENDPOINT }} make test${{ inputs.image == 'plus' && '-with-plus' || ''}} PREFIX=${ngf_prefix} TAG=${ngf_tag} GW_SERVICE_TYPE=LoadBalancer CLUSTER_NAME=${{ github.run_id }} CI=true working-directory: ./tests diff --git a/.github/workflows/helm.yml b/.github/workflows/helm.yml index f789df7514..dfdfaa644f 100644 --- a/.github/workflows/helm.yml +++ b/.github/workflows/helm.yml @@ -17,7 +17,7 @@ jobs: helm-tests-local: name: Helm Tests Local runs-on: ubuntu-24.04 - if: ${{ github.event_name != 'schedule' }} + if: ${{ github.event_name != 'schedule' && (!github.event.pull_request.head.repo.fork || inputs.image != 'plus') }} steps: - name: Checkout Repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -103,7 +103,7 @@ jobs: - name: Create plus secret if: ${{ inputs.image == 'plus' }} env: - PLUS_LICENSE: ${{ secrets.JWT_PLUS_REGISTRY }} + PLUS_LICENSE: ${{ secrets.JWT_PLUS_REPORTING }} run: | echo "${PLUS_LICENSE}" > license.jwt kubectl create secret generic nplus-license --from-file license.jwt -n nginx-gateway @@ -155,7 +155,7 @@ jobs: - name: Create plus secrets if: ${{ inputs.image == 'plus' }} env: - PLUS_LICENSE: ${{ secrets.JWT_PLUS_REGISTRY }} + PLUS_LICENSE: ${{ secrets.JWT_PLUS_REPORTING }} run: | echo "${PLUS_LICENSE}" > license.jwt kubectl create secret docker-registry nginx-plus-registry-secret --docker-server=private-registry.nginx.com --docker-username=${{ secrets.JWT_PLUS_REGISTRY }} --docker-password=none -n nginx-gateway diff --git a/.github/workflows/nfr.yml b/.github/workflows/nfr.yml index 6ed48670c8..8334270bc6 100644 --- a/.github/workflows/nfr.yml +++ b/.github/workflows/nfr.yml @@ -114,7 +114,7 @@ jobs: - name: Setup license file for plus if: matrix.type == 'plus' env: - PLUS_LICENSE: ${{ secrets.JWT_PLUS_REGISTRY }} + PLUS_LICENSE: ${{ secrets.JWT_PLUS_REPORTING }} run: echo "${PLUS_LICENSE}" > license.jwt - name: Create GKE cluster diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index a3a6af47b4..27e1f3e071 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -73,8 +73,8 @@ jobs: - name: Find and Replace uses: jacobtomlinson/gha-find-replace@f1069b438f125e5395d84d1c6fd3b559a7880cb5 # 3.0.5 with: - find: "Always" - replace: "IfNotPresent" + find: ": Always" + replace: ": IfNotPresent" include: "charts/nginx-gateway-fabric/*.yaml" regex: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 6838f8dab9..04fda67608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,33 @@ This document includes a curated changelog for each release. We also publish a c a [GitHub release](https://github.com/nginxinc/nginx-gateway-fabric/releases), which, by contrast, is auto-generated and includes links to all PRs that went into the release. +## Release 1.5.1 + +_December 16, 2024_ + +BUG FIXES: + +- Write NGINX Plus R33 deployment context in init container. [2905](https://github.com/nginxinc/nginx-gateway-fabric/pull/2905) +- SnippetsFilter CRD missing from CRDs manifest. [2822](https://github.com/nginxinc/nginx-gateway-fabric/pull/2822) +- Omit empty deployment context fields in NGINX Plus R33 reporting. [2910](https://github.com/nginxinc/nginx-gateway-fabric/pull/2910) + +HELM CHART: + +- The version of the Helm chart is now 1.5.1 + +COMPATIBILITY: + +- Gateway API version: `1.2.0` +- NGINX version: `1.27.2` +- NGINX Plus version: `R33` +- Kubernetes version: `1.25+` + +CONTAINER IMAGES: + +- Control plane: `ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1` +- Data plane: `ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.1` +- Data plane with NGINX Plus: `private-registry.nginx.com/nginx-gateway-fabric/nginx-plus:1.5.1` + ## Release 1.5.0 _November 20, 2024_ diff --git a/Makefile b/Makefile index 168599d9a6..aa07ae23aa 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # variables that should not be overridden by the user -VERSION = 1.5.0 +VERSION = 1.5.1 SELF_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) CHART_DIR = $(SELF_DIR)charts/nginx-gateway-fabric NGINX_CONF_DIR = internal/mode/static/nginx/conf @@ -50,6 +50,8 @@ GOARCH ?= amd64## The architecture of the image and/or binary. For example: amd6 GOOS ?= linux## The OS of the image and/or binary. For example: linux or darwin PLUS_ENABLED ?= false PLUS_LICENSE_FILE ?= $(SELF_DIR)license.jwt +PLUS_USAGE_ENDPOINT ?=## The N+ usage endpoint. For development, please set to the N1 staging endpoint. + override NGINX_DOCKER_BUILD_OPTIONS += --build-arg NJS_DIR=$(NJS_DIR) --build-arg NGINX_CONF_DIR=$(NGINX_CONF_DIR) --build-arg BUILD_AGENT=$(BUILD_AGENT) .DEFAULT_GOAL := help @@ -220,17 +222,23 @@ load-images-with-plus: ## Load NGF and NGINX Plus images on configured kind clus install-ngf-local-build: build-images load-images helm-install-local ## Install NGF from local build on configured kind cluster. .PHONY: install-ngf-local-build-with-plus -install-ngf-local-build-with-plus: build-images-with-plus load-images-with-plus helm-install-local-with-plus ## Install NGF with NGINX Plus from local build on configured kind cluster. +install-ngf-local-build-with-plus: check-for-plus-usage-endpoint build-images-with-plus load-images-with-plus helm-install-local-with-plus ## Install NGF with NGINX Plus from local build on configured kind cluster. .PHONY: helm-install-local helm-install-local: install-gateway-crds ## Helm install NGF on configured kind cluster with local images. To build, load, and install with helm run make install-ngf-local-build. helm install nginx-gateway $(CHART_DIR) --set nginx.image.repository=$(NGINX_PREFIX) --create-namespace --wait --set nginxGateway.image.pullPolicy=Never --set service.type=NodePort --set nginxGateway.image.repository=$(PREFIX) --set nginxGateway.image.tag=$(TAG) --set nginx.image.tag=$(TAG) --set nginx.image.pullPolicy=Never --set nginxGateway.gwAPIExperimentalFeatures.enable=$(ENABLE_EXPERIMENTAL) -n nginx-gateway $(HELM_PARAMETERS) .PHONY: helm-install-local-with-plus -helm-install-local-with-plus: install-gateway-crds ## Helm install NGF with NGINX Plus on configured kind cluster with local images. To build, load, and install with helm run make install-ngf-local-build-with-plus. +helm-install-local-with-plus: check-for-plus-usage-endpoint install-gateway-crds ## Helm install NGF with NGINX Plus on configured kind cluster with local images. To build, load, and install with helm run make install-ngf-local-build-with-plus. kubectl create namespace nginx-gateway || true kubectl -n nginx-gateway create secret generic nplus-license --from-file $(PLUS_LICENSE_FILE) || true - helm install nginx-gateway $(CHART_DIR) --set nginx.image.repository=$(NGINX_PLUS_PREFIX) --wait --set nginxGateway.image.pullPolicy=Never --set service.type=NodePort --set nginxGateway.image.repository=$(PREFIX) --set nginxGateway.image.tag=$(TAG) --set nginx.image.tag=$(TAG) --set nginx.image.pullPolicy=Never --set nginxGateway.gwAPIExperimentalFeatures.enable=$(ENABLE_EXPERIMENTAL) -n nginx-gateway --set nginx.plus=true $(HELM_PARAMETERS) + helm install nginx-gateway $(CHART_DIR) --set nginx.image.repository=$(NGINX_PLUS_PREFIX) --wait --set nginxGateway.image.pullPolicy=Never --set service.type=NodePort --set nginxGateway.image.repository=$(PREFIX) --set nginxGateway.image.tag=$(TAG) --set nginx.image.tag=$(TAG) --set nginx.image.pullPolicy=Never --set nginxGateway.gwAPIExperimentalFeatures.enable=$(ENABLE_EXPERIMENTAL) -n nginx-gateway --set nginx.plus=true --set nginx.usage.endpoint=$(PLUS_USAGE_ENDPOINT) $(HELM_PARAMETERS) + +.PHONY: check-for-plus-usage-endpoint +check-for-plus-usage-endpoint: ## Checks that the PLUS_USAGE_ENDPOINT is set in the environment. This env var is required when deploying or testing with N+. +ifndef PLUS_USAGE_ENDPOINT + $(error PLUS_USAGE_ENDPOINT must be defined in your environment) +endif # Debug Targets .PHONY: debug-build diff --git a/README.md b/README.md index 5a4111acb4..3cdc00a095 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ You can find the comprehensive NGINX Gateway Fabric user documentation on the [N We publish NGINX Gateway Fabric releases on GitHub. See our [releases page](https://github.com/nginxinc/nginx-gateway-fabric/releases). -The latest release is [1.5.0](https://github.com/nginxinc/nginx-gateway-fabric/releases/tag/v1.5.0). +The latest release is [1.5.1](https://github.com/nginxinc/nginx-gateway-fabric/releases/tag/v1.5.1). The edge version is useful for experimenting with new features that are not yet published in a release. To use, choose the _edge_ version built from the [latest commit](https://github.com/nginxinc/nginx-gateway-fabric/commits/main) @@ -45,7 +45,7 @@ to the correct versions: | Version | Description | Installation Manifests | Documentation and Examples | |----------------|------------------------------------------|-----------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Latest release | For production use | [Manifests](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.0/deploy). | [Documentation](https://docs.nginx.com/nginx-gateway-fabric). [Examples](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.0/examples). | +| Latest release | For production use | [Manifests](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.1/deploy). | [Documentation](https://docs.nginx.com/nginx-gateway-fabric). [Examples](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.1/examples). | | Edge | For experimental use and latest features | [Manifests](https://github.com/nginxinc/nginx-gateway-fabric/tree/main/deploy). | [Documentation](https://github.com/nginxinc/nginx-gateway-fabric/tree/main/site/content). [Examples](https://github.com/nginxinc/nginx-gateway-fabric/tree/main/examples). | ### Versioning @@ -67,6 +67,7 @@ The following table lists the software versions NGINX Gateway Fabric supports. | NGINX Gateway Fabric | Gateway API | Kubernetes | NGINX OSS | NGINX Plus | |----------------------|-------------|------------|-----------|------------| | Edge | 1.2.0 | 1.25+ | 1.27.2 | R33 | +| 1.5.1 | 1.2.0 | 1.25+ | 1.27.2 | R33 | | 1.5.0 | 1.2.0 | 1.25+ | 1.27.2 | R33 | | 1.4.0 | 1.1.0 | 1.25+ | 1.27.1 | R32 | | 1.3.0 | 1.1.0 | 1.25+ | 1.27.0 | R32 | diff --git a/charts/nginx-gateway-fabric/Chart.yaml b/charts/nginx-gateway-fabric/Chart.yaml index 63d87f8e94..305f28a430 100644 --- a/charts/nginx-gateway-fabric/Chart.yaml +++ b/charts/nginx-gateway-fabric/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: nginx-gateway-fabric description: NGINX Gateway Fabric type: application -version: 1.5.0 -appVersion: "1.5.0" +version: 1.5.1 +appVersion: "1.5.1" kubeVersion: ">= 1.25.0-0" home: https://github.com/nginxinc/nginx-gateway-fabric icon: https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/main/charts/nginx-gateway-fabric/chart-icon.png diff --git a/charts/nginx-gateway-fabric/README.md b/charts/nginx-gateway-fabric/README.md index cc7a845139..181715740a 100644 --- a/charts/nginx-gateway-fabric/README.md +++ b/charts/nginx-gateway-fabric/README.md @@ -1,7 +1,7 @@ # NGINX Gateway Fabric Helm Chart -![Version: 1.5.0](https://img.shields.io/badge/Version-1.5.0-informational?style=flat-square) ![AppVersion: 1.5.0](https://img.shields.io/badge/AppVersion-1.5.0-informational?style=flat-square) +![Version: 1.5.1](https://img.shields.io/badge/Version-1.5.1-informational?style=flat-square) ![AppVersion: 1.5.1](https://img.shields.io/badge/AppVersion-1.5.1-informational?style=flat-square) - [NGINX Gateway Fabric Helm Chart](#nginx-gateway-fabric-helm-chart) - [Introduction](#introduction) @@ -265,7 +265,7 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri | `nginx.extraVolumeMounts` | extraVolumeMounts are the additional volume mounts for the nginx container. | list | `[]` | | `nginx.image.pullPolicy` | | string | `"IfNotPresent"` | | `nginx.image.repository` | The NGINX image to use. | string | `"ghcr.io/nginxinc/nginx-gateway-fabric/nginx"` | -| `nginx.image.tag` | | string | `"1.5.0"` | +| `nginx.image.tag` | | string | `"1.5.1"` | | `nginx.lifecycle` | The lifecycle of the nginx container. | object | `{}` | | `nginx.plus` | Is NGINX Plus image being used | bool | `false` | | `nginx.usage.caSecretName` | The name of the Secret containing the NGINX Instance Manager CA certificate. Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway). | string | `""` | @@ -283,7 +283,7 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri | `nginxGateway.gwAPIExperimentalFeatures.enable` | Enable the experimental features of Gateway API which are supported by NGINX Gateway Fabric. Requires the Gateway APIs installed from the experimental channel. | bool | `false` | | `nginxGateway.image.pullPolicy` | | string | `"IfNotPresent"` | | `nginxGateway.image.repository` | The NGINX Gateway Fabric image to use | string | `"ghcr.io/nginxinc/nginx-gateway-fabric"` | -| `nginxGateway.image.tag` | | string | `"1.5.0"` | +| `nginxGateway.image.tag` | | string | `"1.5.1"` | | `nginxGateway.kind` | The kind of the NGINX Gateway Fabric installation - currently, only deployment is supported. | string | `"deployment"` | | `nginxGateway.leaderElection.enable` | Enable leader election. Leader election is used to avoid multiple replicas of the NGINX Gateway Fabric reporting the status of the Gateway API resources. If not enabled, all replicas of NGINX Gateway Fabric will update the statuses of the Gateway API resources. | bool | `true` | | `nginxGateway.leaderElection.lockName` | The name of the leader election lock. A Lease object with this name will be created in the same Namespace as the controller. | string | Autogenerated if not set or set to "". | diff --git a/charts/nginx-gateway-fabric/chart-icon.png b/charts/nginx-gateway-fabric/chart-icon.png index 52961c9a6f..129815d913 100644 Binary files a/charts/nginx-gateway-fabric/chart-icon.png and b/charts/nginx-gateway-fabric/chart-icon.png differ diff --git a/charts/nginx-gateway-fabric/templates/configmap.yaml b/charts/nginx-gateway-fabric/templates/configmap.yaml index 69586d5ec3..8b99c60650 100644 --- a/charts/nginx-gateway-fabric/templates/configmap.yaml +++ b/charts/nginx-gateway-fabric/templates/configmap.yaml @@ -29,5 +29,6 @@ data: ssl_certificate_key /etc/nginx/certs-bootstrap/tls.key; {{- end }} enforce_initial_report off; + deployment_context /etc/nginx/main-includes/deployment_ctx.json; } {{- end }} diff --git a/charts/nginx-gateway-fabric/templates/deployment.yaml b/charts/nginx-gateway-fabric/templates/deployment.yaml index 0985a5bc21..4149bdf587 100644 --- a/charts/nginx-gateway-fabric/templates/deployment.yaml +++ b/charts/nginx-gateway-fabric/templates/deployment.yaml @@ -34,20 +34,26 @@ spec: {{- toYaml .Values.topologySpreadConstraints | nindent 8 }} {{- end }} initContainers: - - name: copy-nginx-config + - name: init image: {{ .Values.nginxGateway.image.repository }}:{{ default .Chart.AppVersion .Values.nginxGateway.image.tag }} imagePullPolicy: {{ .Values.nginxGateway.image.pullPolicy }} command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf {{- if .Values.nginx.plus }} - --source - /includes/mgmt.conf + - --nginx-plus {{- end }} - --destination - /etc/nginx/main-includes + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid securityContext: seccompProfile: type: RuntimeDefault @@ -132,6 +138,10 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid image: {{ .Values.nginxGateway.image.repository }}:{{ default .Chart.AppVersion .Values.nginxGateway.image.tag }} imagePullPolicy: {{ .Values.nginxGateway.image.pullPolicy }} name: nginx-gateway diff --git a/charts/nginx-gateway-fabric/values.schema.json b/charts/nginx-gateway-fabric/values.schema.json index 0e284594a9..a2e3d705cd 100644 --- a/charts/nginx-gateway-fabric/values.schema.json +++ b/charts/nginx-gateway-fabric/values.schema.json @@ -236,7 +236,7 @@ "type": "string" }, "tag": { - "default": "1.5.0", + "default": "1.5.1", "required": [], "title": "tag", "type": "string" @@ -411,7 +411,7 @@ "type": "string" }, "tag": { - "default": "1.5.0", + "default": "1.5.1", "required": [], "title": "tag", "type": "string" diff --git a/charts/nginx-gateway-fabric/values.yaml b/charts/nginx-gateway-fabric/values.yaml index 7af279f290..ba3de8900e 100644 --- a/charts/nginx-gateway-fabric/values.yaml +++ b/charts/nginx-gateway-fabric/values.yaml @@ -82,7 +82,7 @@ nginxGateway: image: # -- The NGINX Gateway Fabric image to use repository: ghcr.io/nginxinc/nginx-gateway-fabric - tag: 1.5.0 + tag: 1.5.1 # @schema # enum: # - Always @@ -122,7 +122,7 @@ nginx: image: # -- The NGINX image to use. repository: ghcr.io/nginxinc/nginx-gateway-fabric/nginx - tag: 1.5.0 + tag: 1.5.1 # @schema # enum: # - Always diff --git a/cmd/gateway/commands.go b/cmd/gateway/commands.go index 72b64db403..34c595f455 100644 --- a/cmd/gateway/commands.go +++ b/cmd/gateway/commands.go @@ -3,9 +3,7 @@ package main import ( "errors" "fmt" - "io" "os" - "path/filepath" "runtime/debug" "strconv" "time" @@ -16,14 +14,20 @@ import ( "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/klog/v2" + ctlr "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" ctlrZap "sigs.k8s.io/controller-runtime/pkg/log/zap" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/provisioner" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing" + ngxConfig "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" ) +// These flags are shared by multiple commands. const ( domain = "gateway.nginx.org" gatewayClassFlag = "gatewayclass" @@ -32,6 +36,7 @@ const ( gatewayCtlrNameFlag = "gateway-ctlr-name" gatewayCtlrNameUsageFmt = `The name of the Gateway controller. ` + `The controller name must be of the form: DOMAIN/PATH. The controller's domain is '%s'` + plusFlag = "nginx-plus" ) func createRootCommand() *cobra.Command { @@ -47,7 +52,6 @@ func createRootCommand() *cobra.Command { return rootCmd } -//nolint:gocyclo func createStaticModeCommand() *cobra.Command { // flag names const ( @@ -63,7 +67,6 @@ func createStaticModeCommand() *cobra.Command { leaderElectionDisableFlag = "leader-election-disable" leaderElectionLockNameFlag = "leader-election-lock-name" productTelemetryDisableFlag = "product-telemetry-disable" - plusFlag = "nginx-plus" gwAPIExperimentalFlag = "gateway-api-experimental-features" usageReportSecretFlag = "usage-report-secret" usageReportEndpointFlag = "usage-report-endpoint" @@ -159,21 +162,6 @@ func createStaticModeCommand() *cobra.Command { return fmt.Errorf("error validating ports: %w", err) } - podIP := os.Getenv("POD_IP") - if err := validateIP(podIP); err != nil { - return fmt.Errorf("error validating POD_IP environment variable: %w", err) - } - - namespace := os.Getenv("POD_NAMESPACE") - if namespace == "" { - return errors.New("POD_NAMESPACE environment variable must be set") - } - - podName := os.Getenv("POD_NAME") - if podName == "" { - return errors.New("POD_NAME environment variable must be set") - } - imageSource := os.Getenv("BUILD_AGENT") if imageSource != "gha" && imageSource != "local" { imageSource = "unknown" @@ -218,6 +206,11 @@ func createStaticModeCommand() *cobra.Command { flagKeys, flagValues := parseFlags(cmd.Flags()) + podConfig, err := createGatewayPodConfig(serviceName.value) + if err != nil { + return fmt.Errorf("error creating gateway pod config: %w", err) + } + conf := config.Config{ GatewayCtlrName: gatewayCtlrName.value, ConfigName: configName.String(), @@ -226,12 +219,7 @@ func createStaticModeCommand() *cobra.Command { GatewayClassName: gatewayClassName.value, GatewayNsName: gwNsName, UpdateGatewayClassStatus: updateGCStatus, - GatewayPodConfig: config.GatewayPodConfig{ - PodIP: podIP, - ServiceName: serviceName.value, - Namespace: namespace, - Name: podName, - }, + GatewayPodConfig: podConfig, HealthConfig: config.HealthConfig{ Enabled: !disableHealth, Port: healthListenPort.value, @@ -244,7 +232,7 @@ func createStaticModeCommand() *cobra.Command { LeaderElection: config.LeaderElectionConfig{ Enabled: !disableLeaderElection, LockName: leaderElectionLockName.String(), - Identity: podName, + Identity: podConfig.Name, }, UsageReportConfig: usageReportConfig, ProductTelemetryConfig: config.ProductTelemetryConfig{ @@ -524,29 +512,63 @@ func createSleepCommand() *cobra.Command { return cmd } -func createCopyCommand() *cobra.Command { +func createInitializeCommand() *cobra.Command { // flag names const srcFlag = "source" const destFlag = "destination" + // flag values var srcFiles []string var dest string + var plus bool cmd := &cobra.Command{ - Use: "copy", - Short: "Copy files to another directory", + Use: "initialize", + Short: "Write initial configuration files", RunE: func(_ *cobra.Command, _ []string) error { - if err := validateSleepArgs(srcFiles, dest); err != nil { + if err := validateCopyArgs(srcFiles, dest); err != nil { return err } - for _, src := range srcFiles { - if err := copyFile(src, dest); err != nil { - return err - } + podUID, err := getValueFromEnv("POD_UID") + if err != nil { + return fmt.Errorf("could not get pod UID: %w", err) } - return nil + clusterCfg := ctlr.GetConfigOrDie() + k8sReader, err := client.New(clusterCfg, client.Options{}) + if err != nil { + return fmt.Errorf("unable to initialize k8s client: %w", err) + } + + logger := ctlrZap.New() + klog.SetLogger(logger) + logger.Info( + "Starting init container", + "source filenames to copy", srcFiles, + "destination directory", dest, + "nginx-plus", + plus, + ) + log.SetLogger(logger) + + dcc := licensing.NewDeploymentContextCollector(licensing.DeploymentContextCollectorConfig{ + K8sClientReader: k8sReader, + PodUID: podUID, + Logger: logger.WithName("deployCtxCollector"), + }) + + return initialize(initializeConfig{ + fileManager: file.NewStdLibOSFileManager(), + fileGenerator: ngxConfig.NewGeneratorImpl(plus, nil, logger.WithName("generator")), + logger: logger, + plus: plus, + collector: dcc, + copy: copyFiles{ + srcFileNames: srcFiles, + destDirName: dest, + }, + }) }, } @@ -564,31 +586,18 @@ func createCopyCommand() *cobra.Command { "The destination directory for the source files to be copied to", ) + cmd.Flags().BoolVar( + &plus, + plusFlag, + false, + "Use NGINX Plus", + ) + cmd.MarkFlagsRequiredTogether(srcFlag, destFlag) return cmd } -func copyFile(src, dest string) error { - srcFile, err := os.Open(src) - if err != nil { - return fmt.Errorf("error opening source file: %w", err) - } - defer srcFile.Close() - - destFile, err := os.Create(filepath.Join(dest, filepath.Base(src))) - if err != nil { - return fmt.Errorf("error creating destination file: %w", err) - } - defer destFile.Close() - - if _, err := io.Copy(destFile, srcFile); err != nil { - return fmt.Errorf("error copying file contents: %w", err) - } - - return nil -} - func parseFlags(flags *pflag.FlagSet) ([]string, []string) { var flagKeys, flagValues []string @@ -634,3 +643,44 @@ func getBuildInfo() (commitHash string, commitTime string, dirtyBuild string) { return } + +func createGatewayPodConfig(svcName string) (config.GatewayPodConfig, error) { + podIP, err := getValueFromEnv("POD_IP") + if err != nil { + return config.GatewayPodConfig{}, err + } + + podUID, err := getValueFromEnv("POD_UID") + if err != nil { + return config.GatewayPodConfig{}, err + } + + ns, err := getValueFromEnv("POD_NAMESPACE") + if err != nil { + return config.GatewayPodConfig{}, err + } + + name, err := getValueFromEnv("POD_NAME") + if err != nil { + return config.GatewayPodConfig{}, err + } + + c := config.GatewayPodConfig{ + PodIP: podIP, + ServiceName: svcName, + Namespace: ns, + Name: name, + UID: podUID, + } + + return c, nil +} + +func getValueFromEnv(key string) (string, error) { + val := os.Getenv(key) + if val == "" { + return "", fmt.Errorf("environment variable %s not set", key) + } + + return val, nil +} diff --git a/cmd/gateway/commands_test.go b/cmd/gateway/commands_test.go index 832c44358e..a714004bff 100644 --- a/cmd/gateway/commands_test.go +++ b/cmd/gateway/commands_test.go @@ -1,15 +1,17 @@ package main import ( + "errors" "io" "os" - "path/filepath" "testing" . "github.com/onsi/gomega" "github.com/spf13/cobra" "github.com/spf13/pflag" "k8s.io/apimachinery/pkg/types" + + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" ) type flagTestCase struct { @@ -474,7 +476,7 @@ func TestSleepCmdFlagValidation(t *testing.T) { } } -func TestCopyCmdFlagValidation(t *testing.T) { +func TestInitializeCmdFlagValidation(t *testing.T) { t.Parallel() tests := []flagTestCase{ { @@ -482,6 +484,7 @@ func TestCopyCmdFlagValidation(t *testing.T) { args: []string{ "--source=/my/file", "--destination=dest/file", + "--nginx-plus", }, wantErr: false, }, @@ -513,29 +516,12 @@ func TestCopyCmdFlagValidation(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { t.Parallel() - cmd := createCopyCommand() + cmd := createInitializeCommand() testFlag(t, cmd, test) }) } } -func TestCopyFile(t *testing.T) { - t.Parallel() - g := NewWithT(t) - - src, err := os.CreateTemp(os.TempDir(), "testfile") - g.Expect(err).ToNot(HaveOccurred()) - defer os.Remove(src.Name()) - - dest, err := os.MkdirTemp(os.TempDir(), "testdir") - g.Expect(err).ToNot(HaveOccurred()) - defer os.RemoveAll(dest) - - g.Expect(copyFile(src.Name(), dest)).To(Succeed()) - _, err = os.Stat(filepath.Join(dest, filepath.Base(src.Name()))) - g.Expect(err).ToNot(HaveOccurred()) -} - func TestParseFlags(t *testing.T) { t.Parallel() g := NewWithT(t) @@ -676,3 +662,50 @@ func TestGetBuildInfo(t *testing.T) { g.Expect(commitTime).To(Not(Equal("unknown"))) g.Expect(dirtyBuild).To(Not(Equal("unknown"))) } + +func TestCreateGatewayPodConfig(t *testing.T) { + t.Parallel() + g := NewWithT(t) + + // Order matters here + // We start with all env vars set + g.Expect(os.Setenv("POD_IP", "10.0.0.0")).To(Succeed()) + g.Expect(os.Setenv("POD_UID", "1234")).To(Succeed()) + g.Expect(os.Setenv("POD_NAMESPACE", "default")).To(Succeed()) + g.Expect(os.Setenv("POD_NAME", "my-pod")).To(Succeed()) + + expCfg := config.GatewayPodConfig{ + PodIP: "10.0.0.0", + ServiceName: "svc", + Namespace: "default", + Name: "my-pod", + UID: "1234", + } + cfg, err := createGatewayPodConfig("svc") + g.Expect(err).To(Not(HaveOccurred())) + g.Expect(cfg).To(Equal(expCfg)) + + // unset name + g.Expect(os.Unsetenv("POD_NAME")).To(Succeed()) + cfg, err = createGatewayPodConfig("svc") + g.Expect(err).To(MatchError(errors.New("environment variable POD_NAME not set"))) + g.Expect(cfg).To(Equal(config.GatewayPodConfig{})) + + // unset namespace + g.Expect(os.Unsetenv("POD_NAMESPACE")).To(Succeed()) + cfg, err = createGatewayPodConfig("svc") + g.Expect(err).To(MatchError(errors.New("environment variable POD_NAMESPACE not set"))) + g.Expect(cfg).To(Equal(config.GatewayPodConfig{})) + + // unset pod UID + g.Expect(os.Unsetenv("POD_UID")).To(Succeed()) + cfg, err = createGatewayPodConfig("svc") + g.Expect(err).To(MatchError(errors.New("environment variable POD_UID not set"))) + g.Expect(cfg).To(Equal(config.GatewayPodConfig{})) + + // unset IP + g.Expect(os.Unsetenv("POD_IP")).To(Succeed()) + cfg, err = createGatewayPodConfig("svc") + g.Expect(err).To(MatchError(errors.New("environment variable POD_IP not set"))) + g.Expect(cfg).To(Equal(config.GatewayPodConfig{})) +} diff --git a/cmd/gateway/initialize.go b/cmd/gateway/initialize.go new file mode 100644 index 0000000000..1aa01f923e --- /dev/null +++ b/cmd/gateway/initialize.go @@ -0,0 +1,88 @@ +package main + +import ( + "context" + "fmt" + "path/filepath" + "time" + + "github.com/go-logr/logr" + + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" +) + +const ( + collectDeployCtxTimeout = 10 * time.Second +) + +type copyFiles struct { + destDirName string + srcFileNames []string +} + +type initializeConfig struct { + collector licensing.Collector + fileManager file.OSFileManager + fileGenerator config.Generator + logger logr.Logger + copy copyFiles + plus bool +} + +func initialize(cfg initializeConfig) error { + for _, src := range cfg.copy.srcFileNames { + if err := copyFile(cfg.fileManager, src, cfg.copy.destDirName); err != nil { + return err + } + } + + if !cfg.plus { + cfg.logger.Info("Finished initializing configuration") + return nil + } + + ctx, cancel := context.WithTimeout(context.Background(), collectDeployCtxTimeout) + defer cancel() + + depCtx, err := cfg.collector.Collect(ctx) + if err != nil { + cfg.logger.Error(err, "error collecting deployment context") + } + + cfg.logger.Info("Deployment context collected", "deployment context", depCtx) + + depCtxFile, err := cfg.fileGenerator.GenerateDeploymentContext(depCtx) + if err != nil { + return fmt.Errorf("failed to generate deployment context file: %w", err) + } + + if err := file.WriteFile(cfg.fileManager, depCtxFile); err != nil { + return fmt.Errorf("failed to write deployment context file: %w", err) + } + + cfg.logger.Info("Finished initializing configuration") + + return nil +} + +func copyFile(osFileManager file.OSFileManager, src, dest string) error { + srcFile, err := osFileManager.Open(src) + if err != nil { + return fmt.Errorf("error opening source file: %w", err) + } + defer srcFile.Close() + + destFile, err := osFileManager.Create(filepath.Join(dest, filepath.Base(src))) + if err != nil { + return fmt.Errorf("error creating destination file: %w", err) + } + defer destFile.Close() + + if err := osFileManager.Copy(destFile, srcFile); err != nil { + return fmt.Errorf("error copying file contents: %w", err) + } + + return nil +} diff --git a/cmd/gateway/initialize_test.go b/cmd/gateway/initialize_test.go new file mode 100644 index 0000000000..507acc6fa0 --- /dev/null +++ b/cmd/gateway/initialize_test.go @@ -0,0 +1,209 @@ +package main + +import ( + "context" + "errors" + "io" + "os" + "path/filepath" + "testing" + + . "github.com/onsi/gomega" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing/licensingfakes" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/configfakes" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file/filefakes" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane" +) + +func TestInitialize_OSS(t *testing.T) { + t.Parallel() + g := NewGomegaWithT(t) + + fakeFileMgr := &filefakes.FakeOSFileManager{} + + ic := initializeConfig{ + fileManager: fakeFileMgr, + logger: zap.New(), + copy: copyFiles{ + destDirName: "destDir", + srcFileNames: []string{"src1", "src2"}, + }, + plus: false, + } + + err := initialize(ic) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(fakeFileMgr.CreateCallCount()).To(Equal(2)) + g.Expect(fakeFileMgr.OpenCallCount()).To(Equal(2)) + g.Expect(fakeFileMgr.CopyCallCount()).To(Equal(2)) +} + +func TestInitialize_OSS_Error(t *testing.T) { + t.Parallel() + g := NewGomegaWithT(t) + + openErr := errors.New("open error") + fakeFileMgr := &filefakes.FakeOSFileManager{ + OpenStub: func(_ string) (*os.File, error) { + return nil, openErr + }, + } + + ic := initializeConfig{ + fileManager: fakeFileMgr, + logger: zap.New(), + copy: copyFiles{ + destDirName: "destDir", + srcFileNames: []string{"src1", "src2"}, + }, + plus: false, + } + + err := initialize(ic) + g.Expect(err).To(HaveOccurred()) + g.Expect(err).To(MatchError(openErr)) +} + +func TestInitialize_Plus(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + collectErr error + depCtx dataplane.DeploymentContext + }{ + { + name: "normal", + collectErr: nil, + depCtx: dataplane.DeploymentContext{ + Integration: "ngf", + ClusterID: helpers.GetPointer("cluster-id"), + InstallationID: helpers.GetPointer("install-id"), + ClusterNodeCount: helpers.GetPointer(2), + }, + }, + { + name: "collecting deployment context errors", + collectErr: errors.New("collect error"), + depCtx: dataplane.DeploymentContext{ + Integration: "ngf", + InstallationID: helpers.GetPointer("install-id"), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + g := NewWithT(t) + + fakeFileMgr := &filefakes.FakeOSFileManager{} + fakeCollector := &licensingfakes.FakeCollector{ + CollectStub: func(_ context.Context) (dataplane.DeploymentContext, error) { + return test.depCtx, test.collectErr + }, + } + fakeGenerator := &configfakes.FakeGenerator{} + + ic := initializeConfig{ + fileManager: fakeFileMgr, + logger: zap.New(), + collector: fakeCollector, + fileGenerator: fakeGenerator, + copy: copyFiles{ + destDirName: "destDir", + srcFileNames: []string{"src1", "src2"}, + }, + plus: true, + } + + g.Expect(initialize(ic)).To(Succeed()) + // copies + g.Expect(fakeFileMgr.OpenCallCount()).To(Equal(2)) + g.Expect(fakeFileMgr.CopyCallCount()).To(Equal(2)) + + // 2 copies, 1 write deploy ctx + g.Expect(fakeFileMgr.CreateCallCount()).To(Equal(3)) + // write deploy ctx + g.Expect(fakeGenerator.GenerateDeploymentContextCallCount()).To(Equal(1)) + g.Expect(fakeGenerator.GenerateDeploymentContextArgsForCall(0)).To(Equal(test.depCtx)) + g.Expect(fakeCollector.CollectCallCount()).To(Equal(1)) + g.Expect(fakeFileMgr.WriteCallCount()).To(Equal(1)) + g.Expect(fakeFileMgr.ChmodCallCount()).To(Equal(1)) + }) + } +} + +func TestCopyFile(t *testing.T) { + t.Parallel() + g := NewWithT(t) + + src, err := os.CreateTemp(os.TempDir(), "testfile") + g.Expect(err).ToNot(HaveOccurred()) + defer os.Remove(src.Name()) + + dest, err := os.MkdirTemp(os.TempDir(), "testdir") + g.Expect(err).ToNot(HaveOccurred()) + defer os.RemoveAll(dest) + + g.Expect(copyFile(file.NewStdLibOSFileManager(), src.Name(), dest)).To(Succeed()) + _, err = os.Stat(filepath.Join(dest, filepath.Base(src.Name()))) + g.Expect(err).ToNot(HaveOccurred()) +} + +func TestCopyFileErrors(t *testing.T) { + t.Parallel() + + openErr := errors.New("open error") + createErr := errors.New("create error") + copyErr := errors.New("copy error") + + tests := []struct { + fileMgr *filefakes.FakeOSFileManager + expErr error + name string + }{ + { + name: "can't open src file", + fileMgr: &filefakes.FakeOSFileManager{ + OpenStub: func(_ string) (*os.File, error) { + return nil, openErr + }, + }, + expErr: openErr, + }, + { + name: "can't create dest file", + fileMgr: &filefakes.FakeOSFileManager{ + CreateStub: func(_ string) (*os.File, error) { + return nil, createErr + }, + }, + expErr: createErr, + }, + { + name: "can't copy contents", + fileMgr: &filefakes.FakeOSFileManager{ + CopyStub: func(_ io.Writer, _ io.Reader) error { + return copyErr + }, + }, + expErr: copyErr, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + g := NewWithT(t) + err := copyFile(test.fileMgr, "source", "destDir") + + g.Expect(err).To(MatchError(test.expErr)) + }) + } +} diff --git a/cmd/gateway/main.go b/cmd/gateway/main.go index 104bed6673..fc2a5949c7 100644 --- a/cmd/gateway/main.go +++ b/cmd/gateway/main.go @@ -23,7 +23,7 @@ func main() { rootCmd.AddCommand( createStaticModeCommand(), createProvisionerModeCommand(), - createCopyCommand(), + createInitializeCommand(), createSleepCommand(), ) diff --git a/cmd/gateway/validation.go b/cmd/gateway/validation.go index 7d5d0f3a5d..26d80b487a 100644 --- a/cmd/gateway/validation.go +++ b/cmd/gateway/validation.go @@ -206,8 +206,8 @@ func ensureNoPortCollisions(ports ...int) error { return nil } -// validateSleepArgs ensures that arguments to the sleep command are set. -func validateSleepArgs(srcFiles []string, dest string) error { +// validateCopyArgs ensures that arguments to the sleep command are set. +func validateCopyArgs(srcFiles []string, dest string) error { if len(srcFiles) == 0 { return errors.New("source must not be empty") } diff --git a/cmd/gateway/validation_test.go b/cmd/gateway/validation_test.go index 28fbfbf3c3..1774f13619 100644 --- a/cmd/gateway/validation_test.go +++ b/cmd/gateway/validation_test.go @@ -588,7 +588,7 @@ func TestValidateSleepArgs(t *testing.T) { t.Parallel() g := NewWithT(t) - err := validateSleepArgs(tc.srcFiles, tc.dest) + err := validateCopyArgs(tc.srcFiles, tc.dest) if !tc.expErr { g.Expect(err).ToNot(HaveOccurred()) } else { diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 0128a189cb..0258b9baaa 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -5,3 +5,4 @@ resources: - bases/gateway.nginx.org_nginxgateways.yaml - bases/gateway.nginx.org_nginxproxies.yaml - bases/gateway.nginx.org_observabilitypolicies.yaml + - bases/gateway.nginx.org_snippetsfilters.yaml diff --git a/config/tests/static-deployment.yaml b/config/tests/static-deployment.yaml index 9d4d4beb1d..b6d25ce6c5 100644 --- a/config/tests/static-deployment.yaml +++ b/config/tests/static-deployment.yaml @@ -8,7 +8,7 @@ metadata: labels: app.kubernetes.io/name: nginx-gateway app.kubernetes.io/instance: nginx-gateway - app.kubernetes.io/version: "1.5.0" + app.kubernetes.io/version: "1.5.1" spec: replicas: 1 selector: @@ -22,16 +22,21 @@ spec: app.kubernetes.io/instance: nginx-gateway spec: initContainers: - - name: copy-nginx-config - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: init + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --destination - /etc/nginx/main-includes + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid securityContext: seccompProfile: type: RuntimeDefault @@ -72,7 +77,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -109,7 +118,7 @@ spec: mountPath: /var/run/nginx - name: nginx-includes mountPath: /etc/nginx/includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.0 + - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: diff --git a/deploy/aws-nlb/deploy.yaml b/deploy/aws-nlb/deploy.yaml index 5c4f34b22e..d71dc61da3 100644 --- a/deploy/aws-nlb/deploy.yaml +++ b/deploy/aws-nlb/deploy.yaml @@ -9,7 +9,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway --- @@ -19,7 +19,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway rules: - apiGroups: @@ -131,7 +131,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway roleRef: apiGroup: rbac.authorization.k8s.io @@ -151,7 +151,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-includes-bootstrap namespace: nginx-gateway --- @@ -164,7 +164,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -189,7 +189,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -230,7 +230,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -269,7 +273,7 @@ spec: name: nginx-run - mountPath: /etc/nginx/includes name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.0 + - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: @@ -306,14 +310,19 @@ spec: initContainers: - command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --destination - /etc/nginx/main-includes - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent - name: copy-nginx-config + name: init securityContext: capabilities: add: @@ -361,7 +370,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller @@ -372,7 +381,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway-config namespace: nginx-gateway spec: diff --git a/deploy/azure/deploy.yaml b/deploy/azure/deploy.yaml index 79635f1ed3..3b0e3cd91c 100644 --- a/deploy/azure/deploy.yaml +++ b/deploy/azure/deploy.yaml @@ -9,7 +9,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway --- @@ -19,7 +19,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway rules: - apiGroups: @@ -131,7 +131,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway roleRef: apiGroup: rbac.authorization.k8s.io @@ -151,7 +151,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-includes-bootstrap namespace: nginx-gateway --- @@ -161,7 +161,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -186,7 +186,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -227,7 +227,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -266,7 +270,7 @@ spec: name: nginx-run - mountPath: /etc/nginx/includes name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.0 + - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: @@ -303,14 +307,19 @@ spec: initContainers: - command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --destination - /etc/nginx/main-includes - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent - name: copy-nginx-config + name: init securityContext: capabilities: add: @@ -360,7 +369,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller @@ -371,7 +380,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway-config namespace: nginx-gateway spec: diff --git a/deploy/crds.yaml b/deploy/crds.yaml index 1e87d74771..a5cd2f7a7d 100644 --- a/deploy/crds.yaml +++ b/deploy/crds.yaml @@ -1292,3 +1292,192 @@ spec: storage: true subresources: status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.5 + name: snippetsfilters.gateway.nginx.org +spec: + group: gateway.nginx.org + names: + categories: + - nginx-gateway-fabric + kind: SnippetsFilter + listKind: SnippetsFilterList + plural: snippetsfilters + shortNames: + - snippetsfilter + singular: snippetsfilter + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + SnippetsFilter is a filter that allows inserting NGINX configuration into the + generated NGINX config for HTTPRoute and GRPCRoute resources. + properties: + apiVersion: + description: |- + 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 + type: string + kind: + description: |- + 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 + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of the SnippetsFilter. + properties: + snippets: + description: |- + Snippets is a list of NGINX configuration snippets. + There can only be one snippet per context. + Allowed contexts: main, http, http.server, http.server.location. + items: + description: Snippet represents an NGINX configuration snippet. + properties: + context: + description: Context is the NGINX context to insert the snippet + into. + enum: + - main + - http + - http.server + - http.server.location + type: string + value: + description: Value is the NGINX configuration snippet. + minLength: 1 + type: string + required: + - context + - value + type: object + maxItems: 4 + minItems: 1 + type: array + x-kubernetes-validations: + - message: Only one snippet allowed per context + rule: self.all(s1, self.exists_one(s2, s1.context == s2.context)) + required: + - snippets + type: object + status: + description: Status defines the state of the SnippetsFilter. + properties: + controllers: + description: |- + Controllers is a list of Gateway API controllers that processed the SnippetsFilter + and the status of the SnippetsFilter with respect to each controller. + items: + properties: + conditions: + description: Conditions describe the status of the SnippetsFilter. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + required: + - controllerName + type: object + maxItems: 16 + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy/default/deploy.yaml b/deploy/default/deploy.yaml index 0c2eb963f0..73d77ea85a 100644 --- a/deploy/default/deploy.yaml +++ b/deploy/default/deploy.yaml @@ -9,7 +9,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway --- @@ -19,7 +19,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway rules: - apiGroups: @@ -131,7 +131,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway roleRef: apiGroup: rbac.authorization.k8s.io @@ -151,7 +151,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-includes-bootstrap namespace: nginx-gateway --- @@ -161,7 +161,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -186,7 +186,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -227,7 +227,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -266,7 +270,7 @@ spec: name: nginx-run - mountPath: /etc/nginx/includes name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.0 + - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: @@ -303,14 +307,19 @@ spec: initContainers: - command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --destination - /etc/nginx/main-includes - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent - name: copy-nginx-config + name: init securityContext: capabilities: add: @@ -358,7 +367,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller @@ -369,7 +378,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway-config namespace: nginx-gateway spec: diff --git a/deploy/experimental-nginx-plus/deploy.yaml b/deploy/experimental-nginx-plus/deploy.yaml index 4da464b0d7..89ff88d4da 100644 --- a/deploy/experimental-nginx-plus/deploy.yaml +++ b/deploy/experimental-nginx-plus/deploy.yaml @@ -11,7 +11,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway --- @@ -21,7 +21,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway rules: - apiGroups: @@ -144,7 +144,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway roleRef: apiGroup: rbac.authorization.k8s.io @@ -162,13 +162,14 @@ data: mgmt.conf: | mgmt { enforce_initial_report off; + deployment_context /etc/nginx/main-includes/deployment_ctx.json; } kind: ConfigMap metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-includes-bootstrap namespace: nginx-gateway --- @@ -178,7 +179,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -203,7 +204,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -247,7 +248,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -286,7 +291,7 @@ spec: name: nginx-run - mountPath: /etc/nginx/includes name: nginx-includes - - image: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus:1.5.0 + - image: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: @@ -328,16 +333,22 @@ spec: initContainers: - command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --source - /includes/mgmt.conf + - --nginx-plus - --destination - /etc/nginx/main-includes - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent - name: copy-nginx-config + name: init securityContext: capabilities: add: @@ -390,7 +401,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller @@ -401,7 +412,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway-config namespace: nginx-gateway spec: diff --git a/deploy/experimental/deploy.yaml b/deploy/experimental/deploy.yaml index 33a6359ccb..d826589664 100644 --- a/deploy/experimental/deploy.yaml +++ b/deploy/experimental/deploy.yaml @@ -9,7 +9,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway --- @@ -19,7 +19,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway rules: - apiGroups: @@ -136,7 +136,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway roleRef: apiGroup: rbac.authorization.k8s.io @@ -156,7 +156,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-includes-bootstrap namespace: nginx-gateway --- @@ -166,7 +166,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -191,7 +191,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -233,7 +233,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -272,7 +276,7 @@ spec: name: nginx-run - mountPath: /etc/nginx/includes name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.0 + - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: @@ -309,14 +313,19 @@ spec: initContainers: - command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --destination - /etc/nginx/main-includes - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent - name: copy-nginx-config + name: init securityContext: capabilities: add: @@ -364,7 +373,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller @@ -375,7 +384,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway-config namespace: nginx-gateway spec: diff --git a/deploy/nginx-plus/deploy.yaml b/deploy/nginx-plus/deploy.yaml index 4816576b9b..24d3b4ff24 100644 --- a/deploy/nginx-plus/deploy.yaml +++ b/deploy/nginx-plus/deploy.yaml @@ -11,7 +11,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway --- @@ -21,7 +21,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway rules: - apiGroups: @@ -139,7 +139,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway roleRef: apiGroup: rbac.authorization.k8s.io @@ -157,13 +157,14 @@ data: mgmt.conf: | mgmt { enforce_initial_report off; + deployment_context /etc/nginx/main-includes/deployment_ctx.json; } kind: ConfigMap metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-includes-bootstrap namespace: nginx-gateway --- @@ -173,7 +174,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -198,7 +199,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -241,7 +242,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -280,7 +285,7 @@ spec: name: nginx-run - mountPath: /etc/nginx/includes name: nginx-includes - - image: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus:1.5.0 + - image: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: @@ -322,16 +327,22 @@ spec: initContainers: - command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --source - /includes/mgmt.conf + - --nginx-plus - --destination - /etc/nginx/main-includes - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent - name: copy-nginx-config + name: init securityContext: capabilities: add: @@ -384,7 +395,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller @@ -395,7 +406,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway-config namespace: nginx-gateway spec: diff --git a/deploy/nodeport/deploy.yaml b/deploy/nodeport/deploy.yaml index 5ddc8f4890..593f2b2407 100644 --- a/deploy/nodeport/deploy.yaml +++ b/deploy/nodeport/deploy.yaml @@ -9,7 +9,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway --- @@ -19,7 +19,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway rules: - apiGroups: @@ -131,7 +131,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway roleRef: apiGroup: rbac.authorization.k8s.io @@ -151,7 +151,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-includes-bootstrap namespace: nginx-gateway --- @@ -161,7 +161,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -186,7 +186,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -227,7 +227,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -266,7 +270,7 @@ spec: name: nginx-run - mountPath: /etc/nginx/includes name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.0 + - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: @@ -303,14 +307,19 @@ spec: initContainers: - command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --destination - /etc/nginx/main-includes - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent - name: copy-nginx-config + name: init securityContext: capabilities: add: @@ -358,7 +367,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller @@ -369,7 +378,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway-config namespace: nginx-gateway spec: diff --git a/deploy/openshift/deploy.yaml b/deploy/openshift/deploy.yaml index d538cf48c1..d73948cce7 100644 --- a/deploy/openshift/deploy.yaml +++ b/deploy/openshift/deploy.yaml @@ -9,7 +9,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway --- @@ -19,7 +19,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway rules: - apiGroups: @@ -139,7 +139,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway roleRef: apiGroup: rbac.authorization.k8s.io @@ -159,7 +159,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-includes-bootstrap namespace: nginx-gateway --- @@ -169,7 +169,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -194,7 +194,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -235,7 +235,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -274,7 +278,7 @@ spec: name: nginx-run - mountPath: /etc/nginx/includes name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.0 + - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: @@ -311,14 +315,19 @@ spec: initContainers: - command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --destination - /etc/nginx/main-includes - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent - name: copy-nginx-config + name: init securityContext: capabilities: add: @@ -366,7 +375,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller @@ -377,7 +386,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway-config namespace: nginx-gateway spec: diff --git a/deploy/snippets-filters-nginx-plus/deploy.yaml b/deploy/snippets-filters-nginx-plus/deploy.yaml index 8773cb5cc2..b9946ad310 100644 --- a/deploy/snippets-filters-nginx-plus/deploy.yaml +++ b/deploy/snippets-filters-nginx-plus/deploy.yaml @@ -11,7 +11,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway --- @@ -21,7 +21,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway rules: - apiGroups: @@ -141,7 +141,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway roleRef: apiGroup: rbac.authorization.k8s.io @@ -159,13 +159,14 @@ data: mgmt.conf: | mgmt { enforce_initial_report off; + deployment_context /etc/nginx/main-includes/deployment_ctx.json; } kind: ConfigMap metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-includes-bootstrap namespace: nginx-gateway --- @@ -175,7 +176,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -200,7 +201,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -244,7 +245,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -283,7 +288,7 @@ spec: name: nginx-run - mountPath: /etc/nginx/includes name: nginx-includes - - image: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus:1.5.0 + - image: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: @@ -325,16 +330,22 @@ spec: initContainers: - command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --source - /includes/mgmt.conf + - --nginx-plus - --destination - /etc/nginx/main-includes - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent - name: copy-nginx-config + name: init securityContext: capabilities: add: @@ -387,7 +398,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller @@ -398,7 +409,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway-config namespace: nginx-gateway spec: diff --git a/deploy/snippets-filters/deploy.yaml b/deploy/snippets-filters/deploy.yaml index f0f0426c18..8490f628b8 100644 --- a/deploy/snippets-filters/deploy.yaml +++ b/deploy/snippets-filters/deploy.yaml @@ -9,7 +9,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway --- @@ -19,7 +19,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway rules: - apiGroups: @@ -133,7 +133,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway roleRef: apiGroup: rbac.authorization.k8s.io @@ -153,7 +153,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-includes-bootstrap namespace: nginx-gateway --- @@ -163,7 +163,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -188,7 +188,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway namespace: nginx-gateway spec: @@ -230,7 +230,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent name: nginx-gateway ports: @@ -269,7 +273,7 @@ spec: name: nginx-run - mountPath: /etc/nginx/includes name: nginx-includes - - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.0 + - image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:1.5.1 imagePullPolicy: IfNotPresent name: nginx ports: @@ -306,14 +310,19 @@ spec: initContainers: - command: - /usr/bin/gateway - - copy + - initialize - --source - /includes/main.conf - --destination - /etc/nginx/main-includes - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.0 + env: + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: IfNotPresent - name: copy-nginx-config + name: init securityContext: capabilities: add: @@ -361,7 +370,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx spec: controllerName: gateway.nginx.org/nginx-gateway-controller @@ -372,7 +381,7 @@ metadata: labels: app.kubernetes.io/instance: nginx-gateway app.kubernetes.io/name: nginx-gateway - app.kubernetes.io/version: 1.5.0 + app.kubernetes.io/version: 1.5.1 name: nginx-gateway-config namespace: nginx-gateway spec: diff --git a/docs/developer/quickstart.md b/docs/developer/quickstart.md index 04549906ed..38bad3fbb6 100644 --- a/docs/developer/quickstart.md +++ b/docs/developer/quickstart.md @@ -122,6 +122,7 @@ This will build the docker images `nginx-gateway-fabric:` and `nginx- > Note: You will need a valid NGINX Plus license certificate and key named `nginx-repo.crt` and `nginx-repo.key` in the > root of this repo to build the NGINX Plus image. > You will also need a valid NGINX Plus JSON Web Token (JWT) to deploy NGF with NGINX Plus. That JWT should be stored in the `license.jwt` file in the root of the `nginx-gateway-fabric/` directory. See the [documentation](https://docs.nginx.com/nginx-gateway-fabric/installation/nginx-plus-jwt/) for instructions on how to download and set up the JWT. +> Additionally, you need to set the NGINX Plus usage endpoint in your environment. For development and testing, export `PLUS_USAGE_ENDPOINT=`. To build the NGINX Gateway Fabric and NGINX Plus container images from source run the following make command: diff --git a/internal/mode/static/config/config.go b/internal/mode/static/config/config.go index dbcbfa6b81..82b4238836 100644 --- a/internal/mode/static/config/config.go +++ b/internal/mode/static/config/config.go @@ -60,6 +60,8 @@ type GatewayPodConfig struct { Namespace string // Name is the name of the Pod. Name string + // UID is the UID of the Pod. + UID string } // MetricsConfig specifies the metrics config. diff --git a/internal/mode/static/handler.go b/internal/mode/static/handler.go index 637dc378c7..e09732e7f0 100644 --- a/internal/mode/static/handler.go +++ b/internal/mode/static/handler.go @@ -19,8 +19,8 @@ import ( "github.com/nginxinc/nginx-gateway-fabric/internal/framework/events" "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" frameworkStatus "github.com/nginxinc/nginx-gateway-fabric/internal/framework/status" - ngfConfig "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing" ngxConfig "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" @@ -29,7 +29,6 @@ import ( "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/graph" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/resolver" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/status" - "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/telemetry" ) type handlerMetricsCollector interface { @@ -60,6 +59,8 @@ type eventHandlerConfig struct { logLevelSetter logLevelSetter // eventRecorder records events for Kubernetes resources. eventRecorder record.EventRecorder + // deployCtxCollector collects the deployment context for N+ licensing + deployCtxCollector licensing.Collector // nginxConfiguredOnStartChecker sets the health of the Pod to Ready once we've written out our initial config. nginxConfiguredOnStartChecker *nginxConfiguredOnStartChecker // gatewayPodConfig contains information about this Pod. @@ -173,9 +174,9 @@ func (h *eventHandlerImpl) HandleEventBatch(ctx context.Context, logger logr.Log case state.EndpointsOnlyChange: h.version++ cfg := dataplane.BuildConfiguration(ctx, gr, h.cfg.serviceResolver, h.version) - depCtx, setErr := h.setDeploymentCtx(ctx, logger) - if setErr != nil { - logger.Error(setErr, "error setting deployment context for usage reporting") + depCtx, getErr := h.getDeploymentContext(ctx) + if getErr != nil { + logger.Error(getErr, "error getting deployment context for usage reporting") } cfg.DeploymentContext = depCtx @@ -189,9 +190,9 @@ func (h *eventHandlerImpl) HandleEventBatch(ctx context.Context, logger logr.Log case state.ClusterStateChange: h.version++ cfg := dataplane.BuildConfiguration(ctx, gr, h.cfg.serviceResolver, h.version) - depCtx, setErr := h.setDeploymentCtx(ctx, logger) - if setErr != nil { - logger.Error(setErr, "error setting deployment context for usage reporting") + depCtx, getErr := h.getDeploymentContext(ctx) + if getErr != nil { + logger.Error(getErr, "error getting deployment context for usage reporting") } cfg.DeploymentContext = depCtx @@ -500,45 +501,13 @@ func getGatewayAddresses( return gwAddresses, nil } -// setDeploymentCtx sets the deployment context metadata for nginx plus reporting. -func (h *eventHandlerImpl) setDeploymentCtx( - ctx context.Context, - logger logr.Logger, -) (dataplane.DeploymentContext, error) { +// getDeploymentContext gets the deployment context metadata for N+ reporting. +func (h *eventHandlerImpl) getDeploymentContext(ctx context.Context) (dataplane.DeploymentContext, error) { if !h.cfg.plus { return dataplane.DeploymentContext{}, nil } - podNSName := types.NamespacedName{ - Name: h.cfg.gatewayPodConfig.Name, - Namespace: h.cfg.gatewayPodConfig.Namespace, - } - - clusterInfo, err := telemetry.CollectClusterInformation(ctx, h.cfg.k8sReader) - if err != nil { - return dataplane.DeploymentContext{}, fmt.Errorf("error getting cluster information: %w", err) - } - - var installationID string - // InstallationID is not required by the usage API, so if we can't get it, don't return an error - replicaSet, err := telemetry.GetPodReplicaSet(ctx, h.cfg.k8sReader, podNSName) - if err != nil { - logger.Error(err, "failed to get NGF installationID") - } else { - installationID, err = telemetry.GetDeploymentID(replicaSet) - if err != nil { - logger.Error(err, "failed to get NGF installationID") - } - } - - depCtx := dataplane.DeploymentContext{ - Integration: "ngf", - ClusterID: clusterInfo.ClusterID, - ClusterNodeCount: clusterInfo.NodeCount, - InstallationID: installationID, - } - - return depCtx, nil + return h.cfg.deployCtxCollector.Collect(ctx) } // GetLatestConfiguration gets the latest configuration. diff --git a/internal/mode/static/handler_test.go b/internal/mode/static/handler_test.go index 01fc3c0c54..df82f6d4db 100644 --- a/internal/mode/static/handler_test.go +++ b/internal/mode/static/handler_test.go @@ -8,7 +8,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.uber.org/zap" - appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" discoveryV1 "k8s.io/api/discovery/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -24,6 +23,7 @@ import ( "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" "github.com/nginxinc/nginx-gateway-fabric/internal/framework/status/statusfakes" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing/licensingfakes" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/metrics/collectors" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/configfakes" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" @@ -106,6 +106,7 @@ var _ = Describe("eventHandler", func() { nginxRuntimeMgr: fakeNginxRuntimeMgr, statusUpdater: fakeStatusUpdater, eventRecorder: fakeEventRecorder, + deployCtxCollector: &licensingfakes.FakeCollector{}, nginxConfiguredOnStartChecker: newNginxConfiguredOnStartChecker(), controlConfigNSName: types.NamespacedName{Namespace: namespace, Name: configName}, gatewayPodConfig: config.GatewayPodConfig{ @@ -698,132 +699,54 @@ var _ = Describe("getGatewayAddresses", func() { }) }) -var _ = Describe("setDeploymentCtx", func() { +var _ = Describe("getDeploymentContext", func() { When("nginx plus is false", func() { It("doesn't set the deployment context", func() { handler := eventHandlerImpl{} - depCtx, err := handler.setDeploymentCtx(context.Background(), ctlrZap.New()) + depCtx, err := handler.getDeploymentContext(context.Background()) Expect(err).ToNot(HaveOccurred()) Expect(depCtx).To(Equal(dataplane.DeploymentContext{})) }) }) When("nginx plus is true", func() { - var ( - clusterID = "test-uid" - ngfPod = &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "pod1", - OwnerReferences: []metav1.OwnerReference{ - { - Kind: "ReplicaSet", - Name: "replicaset1", - }, - }, - }, - } - - ngfReplicaSet = &appsv1.ReplicaSet{ - Spec: appsv1.ReplicaSetSpec{ - Replicas: helpers.GetPointer[int32](1), - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "replicaset1", - OwnerReferences: []metav1.OwnerReference{ - { - Kind: "Deployment", - Name: "Deployment1", - UID: "test-uid-replicaSet", - }, - }, - }, - } - - kubeNamespace = &v1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: metav1.NamespaceSystem, - UID: "test-uid", - }, - } - - nodeList = &v1.NodeList{ - Items: []v1.Node{{}}, - } - ) - - It("sets the deployment context", func() { - handler := newEventHandlerImpl(eventHandlerConfig{ - plus: true, - k8sReader: fake.NewFakeClient(ngfPod, ngfReplicaSet, kubeNamespace, nodeList), - gatewayPodConfig: config.GatewayPodConfig{ - Name: ngfPod.Name, - }, - }) - - expCtx := dataplane.DeploymentContext{ + It("returns deployment context", func() { + expDepCtx := dataplane.DeploymentContext{ Integration: "ngf", - ClusterID: clusterID, - InstallationID: "test-uid-replicaSet", - ClusterNodeCount: 1, + ClusterID: helpers.GetPointer("cluster-id"), + InstallationID: helpers.GetPointer("installation-id"), + ClusterNodeCount: helpers.GetPointer(1), } - depCtx, err := handler.setDeploymentCtx(context.Background(), ctlrZap.New()) - Expect(err).ToNot(HaveOccurred()) - Expect(depCtx).To(Equal(expCtx)) - }) - - It("returns an error if cluster info isn't found", func() { - handler := newEventHandlerImpl(eventHandlerConfig{ - plus: true, - k8sReader: fake.NewFakeClient(), - }) - - _, err := handler.setDeploymentCtx(context.Background(), ctlrZap.New()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("error getting cluster information")) - }) - - It("sets the deployment context when the replicaset isn't found", func() { handler := newEventHandlerImpl(eventHandlerConfig{ - plus: true, - k8sReader: fake.NewFakeClient(ngfPod, kubeNamespace, nodeList), - gatewayPodConfig: config.GatewayPodConfig{ - Name: ngfPod.Name, + plus: true, + deployCtxCollector: &licensingfakes.FakeCollector{ + CollectStub: func(_ context.Context) (dataplane.DeploymentContext, error) { + return expDepCtx, nil + }, }, }) - expCtx := dataplane.DeploymentContext{ - Integration: "ngf", - ClusterID: clusterID, - ClusterNodeCount: 1, - } - - depCtx, err := handler.setDeploymentCtx(context.Background(), ctlrZap.New()) + dc, err := handler.getDeploymentContext(context.Background()) Expect(err).ToNot(HaveOccurred()) - Expect(depCtx).To(Equal(expCtx)) + Expect(dc).To(Equal(expDepCtx)) }) - - It("sets the deployment context when the replicaset doesn't have a uid", func() { - ngfReplicaSet.ObjectMeta.OwnerReferences[0].UID = "" + It("returns error if it occurs", func() { + expErr := errors.New("collect error") handler := newEventHandlerImpl(eventHandlerConfig{ - plus: true, - k8sReader: fake.NewFakeClient(ngfPod, ngfReplicaSet, kubeNamespace, nodeList), - gatewayPodConfig: config.GatewayPodConfig{ - Name: ngfPod.Name, + plus: true, + deployCtxCollector: &licensingfakes.FakeCollector{ + CollectStub: func(_ context.Context) (dataplane.DeploymentContext, error) { + return dataplane.DeploymentContext{}, expErr + }, }, }) - expCtx := dataplane.DeploymentContext{ - Integration: "ngf", - ClusterID: clusterID, - ClusterNodeCount: 1, - } - - depCtx, err := handler.setDeploymentCtx(context.Background(), ctlrZap.New()) - Expect(err).ToNot(HaveOccurred()) - Expect(depCtx).To(Equal(expCtx)) + dc, err := handler.getDeploymentContext(context.Background()) + Expect(err).To(MatchError(expErr)) + Expect(dc).To(Equal(dataplane.DeploymentContext{})) }) }) }) diff --git a/internal/mode/static/licensing/collector.go b/internal/mode/static/licensing/collector.go new file mode 100644 index 0000000000..4d4d1a945d --- /dev/null +++ b/internal/mode/static/licensing/collector.go @@ -0,0 +1,66 @@ +package licensing + +import ( + "context" + "fmt" + + "github.com/go-logr/logr" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/telemetry" +) + +//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate + +//counterfeiter:generate . Collector + +// Collector collects licensing information for N+. +type Collector interface { + // Collect collects the licensing information for N+ and returns it in the deployment context. + Collect(ctx context.Context) (dataplane.DeploymentContext, error) +} + +const integrationID = "ngf" + +// DeploymentContextCollectorConfig contains the configuration for the DeploymentContextCollector. +type DeploymentContextCollectorConfig struct { + // K8sClientReader is a Kubernetes API client Reader. + K8sClientReader client.Reader + // PodUID is the UID of the NGF Pod. + PodUID string + // Logger is the logger. + Logger logr.Logger +} + +// DeploymentContextCollector collects the deployment context information needed for N+ licensing. +type DeploymentContextCollector struct { + cfg DeploymentContextCollectorConfig +} + +// NewDeploymentContextCollector returns a new instance of DeploymentContextCollector. +func NewDeploymentContextCollector( + cfg DeploymentContextCollectorConfig, +) *DeploymentContextCollector { + return &DeploymentContextCollector{ + cfg: cfg, + } +} + +// Collect collects all the information needed to create the deployment context for N+ licensing. +func (c *DeploymentContextCollector) Collect(ctx context.Context) (dataplane.DeploymentContext, error) { + depCtx := dataplane.DeploymentContext{ + Integration: integrationID, + InstallationID: &c.cfg.PodUID, + } + + clusterInfo, err := telemetry.CollectClusterInformation(ctx, c.cfg.K8sClientReader) + if err != nil { + return depCtx, fmt.Errorf("error collecting cluster ID and cluster node count: %w", err) + } + + depCtx.ClusterID = &clusterInfo.ClusterID + depCtx.ClusterNodeCount = &clusterInfo.NodeCount + + return depCtx, nil +} diff --git a/internal/mode/static/licensing/collector_suite_test.go b/internal/mode/static/licensing/collector_suite_test.go new file mode 100644 index 0000000000..bae62214d7 --- /dev/null +++ b/internal/mode/static/licensing/collector_suite_test.go @@ -0,0 +1,14 @@ +package licensing + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestDeploymentContextController(t *testing.T) { + t.Parallel() + RegisterFailHandler(Fail) + RunSpecs(t, "Deployment Context Controller Suite") +} diff --git a/internal/mode/static/licensing/collector_test.go b/internal/mode/static/licensing/collector_test.go new file mode 100644 index 0000000000..c01b169615 --- /dev/null +++ b/internal/mode/static/licensing/collector_test.go @@ -0,0 +1,67 @@ +package licensing_test + +import ( + "context" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane" +) + +var _ = Describe("DeploymentContextCollector", func() { + var ( + clusterID = "test-uid" + + kubeNamespace = &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: metav1.NamespaceSystem, + UID: "test-uid", + }, + } + + nodeList = &v1.NodeList{ + Items: []v1.Node{{}}, + } + ) + + It("collects the deployment context", func() { + collector := licensing.NewDeploymentContextCollector(licensing.DeploymentContextCollectorConfig{ + K8sClientReader: fake.NewFakeClient(kubeNamespace, nodeList), + PodUID: "pod-uid", + }) + + expCtx := dataplane.DeploymentContext{ + Integration: "ngf", + ClusterID: &clusterID, + InstallationID: helpers.GetPointer("pod-uid"), + ClusterNodeCount: helpers.GetPointer(1), + } + + depCtx, err := collector.Collect(context.Background()) + Expect(err).ToNot(HaveOccurred()) + Expect(depCtx).To(Equal(expCtx)) + }) + + It("returns an error and default deployment context if cluster info isn't found", func() { + collector := licensing.NewDeploymentContextCollector(licensing.DeploymentContextCollectorConfig{ + K8sClientReader: fake.NewFakeClient(), + PodUID: "pod-uid", + }) + + expCtx := dataplane.DeploymentContext{ + Integration: "ngf", + InstallationID: helpers.GetPointer("pod-uid"), + } + + depCtx, err := collector.Collect(context.Background()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("error collecting cluster ID and cluster node count")) + Expect(depCtx).To(Equal(expCtx)) + }) +}) diff --git a/internal/mode/static/licensing/licensingfakes/fake_collector.go b/internal/mode/static/licensing/licensingfakes/fake_collector.go new file mode 100644 index 0000000000..d801c5a443 --- /dev/null +++ b/internal/mode/static/licensing/licensingfakes/fake_collector.go @@ -0,0 +1,118 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package licensingfakes + +import ( + "context" + "sync" + + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/state/dataplane" +) + +type FakeCollector struct { + CollectStub func(context.Context) (dataplane.DeploymentContext, error) + collectMutex sync.RWMutex + collectArgsForCall []struct { + arg1 context.Context + } + collectReturns struct { + result1 dataplane.DeploymentContext + result2 error + } + collectReturnsOnCall map[int]struct { + result1 dataplane.DeploymentContext + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeCollector) Collect(arg1 context.Context) (dataplane.DeploymentContext, error) { + fake.collectMutex.Lock() + ret, specificReturn := fake.collectReturnsOnCall[len(fake.collectArgsForCall)] + fake.collectArgsForCall = append(fake.collectArgsForCall, struct { + arg1 context.Context + }{arg1}) + stub := fake.CollectStub + fakeReturns := fake.collectReturns + fake.recordInvocation("Collect", []interface{}{arg1}) + fake.collectMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeCollector) CollectCallCount() int { + fake.collectMutex.RLock() + defer fake.collectMutex.RUnlock() + return len(fake.collectArgsForCall) +} + +func (fake *FakeCollector) CollectCalls(stub func(context.Context) (dataplane.DeploymentContext, error)) { + fake.collectMutex.Lock() + defer fake.collectMutex.Unlock() + fake.CollectStub = stub +} + +func (fake *FakeCollector) CollectArgsForCall(i int) context.Context { + fake.collectMutex.RLock() + defer fake.collectMutex.RUnlock() + argsForCall := fake.collectArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeCollector) CollectReturns(result1 dataplane.DeploymentContext, result2 error) { + fake.collectMutex.Lock() + defer fake.collectMutex.Unlock() + fake.CollectStub = nil + fake.collectReturns = struct { + result1 dataplane.DeploymentContext + result2 error + }{result1, result2} +} + +func (fake *FakeCollector) CollectReturnsOnCall(i int, result1 dataplane.DeploymentContext, result2 error) { + fake.collectMutex.Lock() + defer fake.collectMutex.Unlock() + fake.CollectStub = nil + if fake.collectReturnsOnCall == nil { + fake.collectReturnsOnCall = make(map[int]struct { + result1 dataplane.DeploymentContext + result2 error + }) + } + fake.collectReturnsOnCall[i] = struct { + result1 dataplane.DeploymentContext + result2 error + }{result1, result2} +} + +func (fake *FakeCollector) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.collectMutex.RLock() + defer fake.collectMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeCollector) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ licensing.Collector = new(FakeCollector) diff --git a/internal/mode/static/manager.go b/internal/mode/static/manager.go index 4c80fc4260..bc24210318 100644 --- a/internal/mode/static/manager.go +++ b/internal/mode/static/manager.go @@ -47,6 +47,7 @@ import ( "github.com/nginxinc/nginx-gateway-fabric/internal/framework/status" ngftypes "github.com/nginxinc/nginx-gateway-fabric/internal/framework/types" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" + "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/licensing" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/metrics/collectors" ngxcfg "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config/policies" @@ -213,22 +214,18 @@ func StartManager(cfg config.Config) error { ) groupStatusUpdater := status.NewLeaderAwareGroupUpdater(statusUpdater) + deployCtxCollector := licensing.NewDeploymentContextCollector(licensing.DeploymentContextCollectorConfig{ + K8sClientReader: mgr.GetAPIReader(), + PodUID: cfg.GatewayPodConfig.UID, + Logger: cfg.Logger.WithName("deployCtxCollector"), + }) eventHandler := newEventHandlerImpl(eventHandlerConfig{ - k8sClient: mgr.GetClient(), - k8sReader: mgr.GetAPIReader(), - processor: processor, - serviceResolver: resolver.NewServiceResolverImpl(mgr.GetClient()), - generator: ngxcfg.NewGeneratorImpl( - cfg.Plus, - &cfg.UsageReportConfig, - cfg.Logger.WithName("generator"), - ), - logLevelSetter: logLevelSetter, nginxFileMgr: file.NewManagerImpl( cfg.Logger.WithName("nginxFileManager"), file.NewStdLibOSFileManager(), ), + metricsCollector: handlerCollector, nginxRuntimeMgr: ngxruntime.NewManagerImpl( ngxPlusClient, ngxruntimeCollector, @@ -236,12 +233,22 @@ func StartManager(cfg config.Config) error { processHandler, ngxruntime.NewVerifyClient(ngxruntime.NginxReloadTimeout), ), - statusUpdater: groupStatusUpdater, + statusUpdater: groupStatusUpdater, + processor: processor, + serviceResolver: resolver.NewServiceResolverImpl(mgr.GetClient()), + generator: ngxcfg.NewGeneratorImpl( + cfg.Plus, + &cfg.UsageReportConfig, + cfg.Logger.WithName("generator"), + ), + k8sClient: mgr.GetClient(), + k8sReader: mgr.GetAPIReader(), + logLevelSetter: logLevelSetter, eventRecorder: recorder, + deployCtxCollector: deployCtxCollector, nginxConfiguredOnStartChecker: nginxChecker, - controlConfigNSName: controlConfigNSName, gatewayPodConfig: cfg.GatewayPodConfig, - metricsCollector: handlerCollector, + controlConfigNSName: controlConfigNSName, gatewayCtlrName: cfg.GatewayCtlrName, updateGatewayClassStatus: cfg.UpdateGatewayClassStatus, plus: cfg.Plus, diff --git a/internal/mode/static/nginx/config/configfakes/fake_generator.go b/internal/mode/static/nginx/config/configfakes/fake_generator.go index 828e41951b..d2b3a6e7b7 100644 --- a/internal/mode/static/nginx/config/configfakes/fake_generator.go +++ b/internal/mode/static/nginx/config/configfakes/fake_generator.go @@ -21,6 +21,19 @@ type FakeGenerator struct { generateReturnsOnCall map[int]struct { result1 []file.File } + GenerateDeploymentContextStub func(dataplane.DeploymentContext) (file.File, error) + generateDeploymentContextMutex sync.RWMutex + generateDeploymentContextArgsForCall []struct { + arg1 dataplane.DeploymentContext + } + generateDeploymentContextReturns struct { + result1 file.File + result2 error + } + generateDeploymentContextReturnsOnCall map[int]struct { + result1 file.File + result2 error + } invocations map[string][][]interface{} invocationsMutex sync.RWMutex } @@ -86,11 +99,77 @@ func (fake *FakeGenerator) GenerateReturnsOnCall(i int, result1 []file.File) { }{result1} } +func (fake *FakeGenerator) GenerateDeploymentContext(arg1 dataplane.DeploymentContext) (file.File, error) { + fake.generateDeploymentContextMutex.Lock() + ret, specificReturn := fake.generateDeploymentContextReturnsOnCall[len(fake.generateDeploymentContextArgsForCall)] + fake.generateDeploymentContextArgsForCall = append(fake.generateDeploymentContextArgsForCall, struct { + arg1 dataplane.DeploymentContext + }{arg1}) + stub := fake.GenerateDeploymentContextStub + fakeReturns := fake.generateDeploymentContextReturns + fake.recordInvocation("GenerateDeploymentContext", []interface{}{arg1}) + fake.generateDeploymentContextMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeGenerator) GenerateDeploymentContextCallCount() int { + fake.generateDeploymentContextMutex.RLock() + defer fake.generateDeploymentContextMutex.RUnlock() + return len(fake.generateDeploymentContextArgsForCall) +} + +func (fake *FakeGenerator) GenerateDeploymentContextCalls(stub func(dataplane.DeploymentContext) (file.File, error)) { + fake.generateDeploymentContextMutex.Lock() + defer fake.generateDeploymentContextMutex.Unlock() + fake.GenerateDeploymentContextStub = stub +} + +func (fake *FakeGenerator) GenerateDeploymentContextArgsForCall(i int) dataplane.DeploymentContext { + fake.generateDeploymentContextMutex.RLock() + defer fake.generateDeploymentContextMutex.RUnlock() + argsForCall := fake.generateDeploymentContextArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenerator) GenerateDeploymentContextReturns(result1 file.File, result2 error) { + fake.generateDeploymentContextMutex.Lock() + defer fake.generateDeploymentContextMutex.Unlock() + fake.GenerateDeploymentContextStub = nil + fake.generateDeploymentContextReturns = struct { + result1 file.File + result2 error + }{result1, result2} +} + +func (fake *FakeGenerator) GenerateDeploymentContextReturnsOnCall(i int, result1 file.File, result2 error) { + fake.generateDeploymentContextMutex.Lock() + defer fake.generateDeploymentContextMutex.Unlock() + fake.GenerateDeploymentContextStub = nil + if fake.generateDeploymentContextReturnsOnCall == nil { + fake.generateDeploymentContextReturnsOnCall = make(map[int]struct { + result1 file.File + result2 error + }) + } + fake.generateDeploymentContextReturnsOnCall[i] = struct { + result1 file.File + result2 error + }{result1, result2} +} + func (fake *FakeGenerator) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.generateMutex.RLock() defer fake.generateMutex.RUnlock() + fake.generateDeploymentContextMutex.RLock() + defer fake.generateDeploymentContextMutex.RUnlock() copiedInvocations := map[string][][]interface{}{} for key, value := range fake.invocations { copiedInvocations[key] = value diff --git a/internal/mode/static/nginx/config/generator.go b/internal/mode/static/nginx/config/generator.go index 9792eb4d9a..714ade9dd3 100644 --- a/internal/mode/static/nginx/config/generator.go +++ b/internal/mode/static/nginx/config/generator.go @@ -1,6 +1,8 @@ package config import ( + "encoding/json" + "fmt" "path/filepath" "github.com/go-logr/logr" @@ -65,6 +67,8 @@ var ConfigFolders = []string{httpFolder, secretsFolder, includesFolder, mainIncl type Generator interface { // Generate generates NGINX configuration files from internal representation. Generate(configuration dataplane.Configuration) []file.File + // GenerateDeploymentContext generates the deployment context used for N+ licensing. + GenerateDeploymentContext(depCtx dataplane.DeploymentContext) (file.File, error) } // GeneratorImpl is an implementation of Generator. @@ -125,6 +129,23 @@ func (g GeneratorImpl) Generate(conf dataplane.Configuration) []file.File { return files } +// GenerateDeploymentContext generates the deployment_ctx.json file needed for N+ licensing. +// It's exported since it's used by the init container process. +func (g GeneratorImpl) GenerateDeploymentContext(depCtx dataplane.DeploymentContext) (file.File, error) { + depCtxBytes, err := json.Marshal(depCtx) + if err != nil { + return file.File{}, fmt.Errorf("error building deployment context for mgmt block: %w", err) + } + + deploymentCtxFile := file.File{ + Content: depCtxBytes, + Path: mainIncludesFolder + "/deployment_ctx.json", + Type: file.TypeRegular, + } + + return deploymentCtxFile, nil +} + func (g GeneratorImpl) executeConfigTemplates( conf dataplane.Configuration, generator policies.Generator, diff --git a/internal/mode/static/nginx/config/generator_test.go b/internal/mode/static/nginx/config/generator_test.go index f343e3dc42..a0a5670c26 100644 --- a/internal/mode/static/nginx/config/generator_test.go +++ b/internal/mode/static/nginx/config/generator_test.go @@ -9,6 +9,7 @@ import ( "k8s.io/apimachinery/pkg/types" ctlrZap "sigs.k8s.io/controller-runtime/pkg/log/zap" + "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" ngfConfig "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/config" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/config" "github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/file" @@ -121,9 +122,9 @@ func TestGenerate(t *testing.T) { }, DeploymentContext: dataplane.DeploymentContext{ Integration: "ngf", - ClusterID: "test-uid", - InstallationID: "test-uid-replicaSet", - ClusterNodeCount: 1, + ClusterID: helpers.GetPointer("test-uid"), + InstallationID: helpers.GetPointer("test-uid-replicaSet"), + ClusterNodeCount: helpers.GetPointer(1), }, AuxiliarySecrets: map[graph.SecretFileType][]byte{ graph.PlusReportJWTToken: []byte("license"), diff --git a/internal/mode/static/nginx/config/main_config.go b/internal/mode/static/nginx/config/main_config.go index bec292a86f..58cdef68cb 100644 --- a/internal/mode/static/nginx/config/main_config.go +++ b/internal/mode/static/nginx/config/main_config.go @@ -1,7 +1,6 @@ package config import ( - "encoding/json" gotemplate "text/template" "github.com/nginxinc/nginx-gateway-fabric/internal/framework/helpers" @@ -43,7 +42,6 @@ type mgmtConf struct { Endpoint string Resolver string LicenseTokenFile string - DeploymentCtxFile string CACertFile string ClientSSLCertFile string ClientSSLKeyFile string @@ -106,17 +104,10 @@ func (g GeneratorImpl) generateMgmtFiles(conf dataplane.Configuration) []file.Fi files = append(files, keyFile) } - depCtx, err := json.Marshal(conf.DeploymentContext) + deploymentCtxFile, err := g.GenerateDeploymentContext(conf.DeploymentContext) if err != nil { g.logger.Error(err, "error building deployment context for mgmt block") } else { - deploymentCtxFile := file.File{ - Content: depCtx, - Path: mainIncludesFolder + "/deployment_ctx.json", - Type: file.TypeRegular, - } - - cfg.DeploymentCtxFile = deploymentCtxFile.Path files = append(files, deploymentCtxFile) } diff --git a/internal/mode/static/nginx/config/main_config_template.go b/internal/mode/static/nginx/config/main_config_template.go index 895494f7b2..2811a4f77d 100644 --- a/internal/mode/static/nginx/config/main_config_template.go +++ b/internal/mode/static/nginx/config/main_config_template.go @@ -21,9 +21,7 @@ mgmt { resolver {{ .Resolver }}; {{- end }} license_token {{ .LicenseTokenFile }}; - {{- if .DeploymentCtxFile }} - deployment_context {{ .DeploymentCtxFile }}; - {{- end }} + deployment_context /etc/nginx/main-includes/deployment_ctx.json; {{- if .SkipVerify }} ssl_verify off; {{- end }} diff --git a/internal/mode/static/nginx/file/filefakes/fake_osfile_manager.go b/internal/mode/static/nginx/file/filefakes/fake_osfile_manager.go index 7227cf8d4c..733da9a1c4 100644 --- a/internal/mode/static/nginx/file/filefakes/fake_osfile_manager.go +++ b/internal/mode/static/nginx/file/filefakes/fake_osfile_manager.go @@ -2,6 +2,7 @@ package filefakes import ( + "io" "io/fs" "os" "sync" @@ -22,6 +23,18 @@ type FakeOSFileManager struct { chmodReturnsOnCall map[int]struct { result1 error } + CopyStub func(io.Writer, io.Reader) error + copyMutex sync.RWMutex + copyArgsForCall []struct { + arg1 io.Writer + arg2 io.Reader + } + copyReturns struct { + result1 error + } + copyReturnsOnCall map[int]struct { + result1 error + } CreateStub func(string) (*os.File, error) createMutex sync.RWMutex createArgsForCall []struct { @@ -35,6 +48,19 @@ type FakeOSFileManager struct { result1 *os.File result2 error } + OpenStub func(string) (*os.File, error) + openMutex sync.RWMutex + openArgsForCall []struct { + arg1 string + } + openReturns struct { + result1 *os.File + result2 error + } + openReturnsOnCall map[int]struct { + result1 *os.File + result2 error + } ReadDirStub func(string) ([]fs.DirEntry, error) readDirMutex sync.RWMutex readDirArgsForCall []struct { @@ -137,6 +163,68 @@ func (fake *FakeOSFileManager) ChmodReturnsOnCall(i int, result1 error) { }{result1} } +func (fake *FakeOSFileManager) Copy(arg1 io.Writer, arg2 io.Reader) error { + fake.copyMutex.Lock() + ret, specificReturn := fake.copyReturnsOnCall[len(fake.copyArgsForCall)] + fake.copyArgsForCall = append(fake.copyArgsForCall, struct { + arg1 io.Writer + arg2 io.Reader + }{arg1, arg2}) + stub := fake.CopyStub + fakeReturns := fake.copyReturns + fake.recordInvocation("Copy", []interface{}{arg1, arg2}) + fake.copyMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeOSFileManager) CopyCallCount() int { + fake.copyMutex.RLock() + defer fake.copyMutex.RUnlock() + return len(fake.copyArgsForCall) +} + +func (fake *FakeOSFileManager) CopyCalls(stub func(io.Writer, io.Reader) error) { + fake.copyMutex.Lock() + defer fake.copyMutex.Unlock() + fake.CopyStub = stub +} + +func (fake *FakeOSFileManager) CopyArgsForCall(i int) (io.Writer, io.Reader) { + fake.copyMutex.RLock() + defer fake.copyMutex.RUnlock() + argsForCall := fake.copyArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeOSFileManager) CopyReturns(result1 error) { + fake.copyMutex.Lock() + defer fake.copyMutex.Unlock() + fake.CopyStub = nil + fake.copyReturns = struct { + result1 error + }{result1} +} + +func (fake *FakeOSFileManager) CopyReturnsOnCall(i int, result1 error) { + fake.copyMutex.Lock() + defer fake.copyMutex.Unlock() + fake.CopyStub = nil + if fake.copyReturnsOnCall == nil { + fake.copyReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.copyReturnsOnCall[i] = struct { + result1 error + }{result1} +} + func (fake *FakeOSFileManager) Create(arg1 string) (*os.File, error) { fake.createMutex.Lock() ret, specificReturn := fake.createReturnsOnCall[len(fake.createArgsForCall)] @@ -201,6 +289,70 @@ func (fake *FakeOSFileManager) CreateReturnsOnCall(i int, result1 *os.File, resu }{result1, result2} } +func (fake *FakeOSFileManager) Open(arg1 string) (*os.File, error) { + fake.openMutex.Lock() + ret, specificReturn := fake.openReturnsOnCall[len(fake.openArgsForCall)] + fake.openArgsForCall = append(fake.openArgsForCall, struct { + arg1 string + }{arg1}) + stub := fake.OpenStub + fakeReturns := fake.openReturns + fake.recordInvocation("Open", []interface{}{arg1}) + fake.openMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeOSFileManager) OpenCallCount() int { + fake.openMutex.RLock() + defer fake.openMutex.RUnlock() + return len(fake.openArgsForCall) +} + +func (fake *FakeOSFileManager) OpenCalls(stub func(string) (*os.File, error)) { + fake.openMutex.Lock() + defer fake.openMutex.Unlock() + fake.OpenStub = stub +} + +func (fake *FakeOSFileManager) OpenArgsForCall(i int) string { + fake.openMutex.RLock() + defer fake.openMutex.RUnlock() + argsForCall := fake.openArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeOSFileManager) OpenReturns(result1 *os.File, result2 error) { + fake.openMutex.Lock() + defer fake.openMutex.Unlock() + fake.OpenStub = nil + fake.openReturns = struct { + result1 *os.File + result2 error + }{result1, result2} +} + +func (fake *FakeOSFileManager) OpenReturnsOnCall(i int, result1 *os.File, result2 error) { + fake.openMutex.Lock() + defer fake.openMutex.Unlock() + fake.OpenStub = nil + if fake.openReturnsOnCall == nil { + fake.openReturnsOnCall = make(map[int]struct { + result1 *os.File + result2 error + }) + } + fake.openReturnsOnCall[i] = struct { + result1 *os.File + result2 error + }{result1, result2} +} + func (fake *FakeOSFileManager) ReadDir(arg1 string) ([]fs.DirEntry, error) { fake.readDirMutex.Lock() ret, specificReturn := fake.readDirReturnsOnCall[len(fake.readDirArgsForCall)] @@ -398,8 +550,12 @@ func (fake *FakeOSFileManager) Invocations() map[string][][]interface{} { defer fake.invocationsMutex.RUnlock() fake.chmodMutex.RLock() defer fake.chmodMutex.RUnlock() + fake.copyMutex.RLock() + defer fake.copyMutex.RUnlock() fake.createMutex.RLock() defer fake.createMutex.RUnlock() + fake.openMutex.RLock() + defer fake.openMutex.RUnlock() fake.readDirMutex.RLock() defer fake.readDirMutex.RUnlock() fake.removeMutex.RLock() diff --git a/internal/mode/static/nginx/file/folders.go b/internal/mode/static/nginx/file/folders.go index a7b296e1d1..847ca6312a 100644 --- a/internal/mode/static/nginx/file/folders.go +++ b/internal/mode/static/nginx/file/folders.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "slices" ) //counterfeiter:generate io/fs.DirEntry @@ -21,10 +22,13 @@ type ClearFoldersOSFileManager interface { // These files are needed on startup, so skip deleting them. const ( - mainConf = "/etc/nginx/main-includes/main.conf" - mgmtConf = "/etc/nginx/main-includes/mgmt.conf" + mainConf = "/etc/nginx/main-includes/main.conf" + mgmtConf = "/etc/nginx/main-includes/mgmt.conf" + deployCtx = "/etc/nginx/main-includes/deployment_ctx.json" ) +var ignoreFilePaths = []string{mainConf, mgmtConf, deployCtx} + // ClearFolders removes all files in the given folders and returns the removed files' full paths. func ClearFolders(fileMgr ClearFoldersOSFileManager, paths []string) (removedFiles []string, e error) { for _, path := range paths { @@ -36,7 +40,7 @@ func ClearFolders(fileMgr ClearFoldersOSFileManager, paths []string) (removedFil for _, entry := range entries { entryPath := filepath.Join(path, entry.Name()) - if entryPath == mainConf || entryPath == mgmtConf { + if slices.Contains(ignoreFilePaths, entryPath) { continue } diff --git a/internal/mode/static/nginx/file/folders_test.go b/internal/mode/static/nginx/file/folders_test.go index 8a63b12106..beefd76dd1 100644 --- a/internal/mode/static/nginx/file/folders_test.go +++ b/internal/mode/static/nginx/file/folders_test.go @@ -41,6 +41,43 @@ func TestClearFoldersRemoves(t *testing.T) { g.Expect(entries).To(BeEmpty()) } +func TestClearFoldersIgnoresPaths(t *testing.T) { + t.Parallel() + g := NewWithT(t) + + fakeFileMgr := &filefakes.FakeClearFoldersOSFileManager{ + ReadDirStub: func(_ string) ([]os.DirEntry, error) { + return []os.DirEntry{ + &filefakes.FakeDirEntry{ + NameStub: func() string { + return "deployment_ctx.json" + }, + }, + &filefakes.FakeDirEntry{ + NameStub: func() string { + return "mgmt.conf" + }, + }, + &filefakes.FakeDirEntry{ + NameStub: func() string { + return "main.conf" + }, + }, + &filefakes.FakeDirEntry{ + NameStub: func() string { + return "can-be-removed.conf" + }, + }, + }, nil + }, + } + + removed, err := file.ClearFolders(fakeFileMgr, []string{"/etc/nginx/main-includes"}) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(removed).To(HaveLen(1)) + g.Expect(removed[0]).To(Equal("/etc/nginx/main-includes/can-be-removed.conf")) +} + func TestClearFoldersFails(t *testing.T) { t.Parallel() files := []string{"file"} diff --git a/internal/mode/static/nginx/file/manager.go b/internal/mode/static/nginx/file/manager.go index b2726c5b54..6c535ddfc4 100644 --- a/internal/mode/static/nginx/file/manager.go +++ b/internal/mode/static/nginx/file/manager.go @@ -3,6 +3,7 @@ package file import ( "errors" "fmt" + "io" "io/fs" "os" @@ -61,6 +62,10 @@ type OSFileManager interface { Chmod(file *os.File, mode os.FileMode) error // Write writes contents to the file. Write(file *os.File, contents []byte) error + // Open opens the file. + Open(name string) (*os.File, error) + // Copy copies from src to dst. + Copy(dst io.Writer, src io.Reader) error } //counterfeiter:generate . Manager @@ -113,7 +118,7 @@ func (m *ManagerImpl) ReplaceFiles(files []File) error { m.lastWrittenPaths = make([]string, 0, len(files)) for _, file := range files { - if err := writeFile(m.osFileManager, file); err != nil { + if err := WriteFile(m.osFileManager, file); err != nil { return fmt.Errorf("failed to write file %q of type %v: %w", file.Path, file.Type, err) } @@ -124,7 +129,7 @@ func (m *ManagerImpl) ReplaceFiles(files []File) error { return nil } -func writeFile(fileMgr OSFileManager, file File) error { +func WriteFile(fileMgr OSFileManager, file File) error { ensureType(file.Type) f, err := fileMgr.Create(file.Path) diff --git a/internal/mode/static/nginx/file/os_filemanager.go b/internal/mode/static/nginx/file/os_filemanager.go index 05547cb046..4b89768b80 100644 --- a/internal/mode/static/nginx/file/os_filemanager.go +++ b/internal/mode/static/nginx/file/os_filemanager.go @@ -1,6 +1,7 @@ package file import ( + "io" "io/fs" "os" ) @@ -41,3 +42,12 @@ func (s *StdLibOSFileManager) Create(name string) (*os.File, error) { func (s *StdLibOSFileManager) Chmod(file *os.File, mode os.FileMode) error { return file.Chmod(mode) } + +// Open wraps os.Open. +func (s *StdLibOSFileManager) Open(name string) (*os.File, error) { return os.Open(name) } + +// Copy wraps io.Copy. +func (s *StdLibOSFileManager) Copy(dst io.Writer, src io.Reader) error { + _, err := io.Copy(dst, src) + return err +} diff --git a/internal/mode/static/state/dataplane/types.go b/internal/mode/static/state/dataplane/types.go index 274897c007..f9ed79b762 100644 --- a/internal/mode/static/state/dataplane/types.go +++ b/internal/mode/static/state/dataplane/types.go @@ -399,12 +399,12 @@ type Logging struct { // DeploymentContext contains metadata about NGF and the cluster. // This is JSON marshaled into a file created by the generator, hence the json tags. type DeploymentContext struct { - // Integration is "ngf". - Integration string `json:"integration"` // ClusterID is the ID of the kube-system namespace. - ClusterID string `json:"cluster_id"` + ClusterID *string `json:"cluster_id,omitempty"` // InstallationID is the ID of the NGF deployment. - InstallationID string `json:"installation_id"` + InstallationID *string `json:"installation_id,omitempty"` // ClusterNodeCount is the count of nodes in the cluster. - ClusterNodeCount int `json:"cluster_node_count"` + ClusterNodeCount *int `json:"cluster_node_count,omitempty"` + // Integration is "ngf". + Integration string `json:"integration"` } diff --git a/internal/mode/static/telemetry/collector.go b/internal/mode/static/telemetry/collector.go index 0e1eaf06bb..cf58cc3d20 100644 --- a/internal/mode/static/telemetry/collector.go +++ b/internal/mode/static/telemetry/collector.go @@ -148,7 +148,7 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { return Data{}, fmt.Errorf("failed to collect NGF resource counts: %w", err) } - replicaSet, err := GetPodReplicaSet(ctx, c.cfg.K8sClientReader, c.cfg.PodNSName) + replicaSet, err := getPodReplicaSet(ctx, c.cfg.K8sClientReader, c.cfg.PodNSName) if err != nil { return Data{}, fmt.Errorf("failed to get replica set for pod %v: %w", c.cfg.PodNSName, err) } @@ -158,7 +158,7 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { return Data{}, fmt.Errorf("failed to collect NGF replica count: %w", err) } - deploymentID, err := GetDeploymentID(replicaSet) + deploymentID, err := getDeploymentID(replicaSet) if err != nil { return Data{}, fmt.Errorf("failed to get NGF deploymentID: %w", err) } @@ -280,8 +280,8 @@ func computeRouteCount( } } -// GetPodReplicaSet returns the replicaset for the provided Pod. -func GetPodReplicaSet( +// getPodReplicaSet returns the replicaset for the provided Pod. +func getPodReplicaSet( ctx context.Context, k8sClient client.Reader, podNSName types.NamespacedName, @@ -324,8 +324,8 @@ func getReplicas(replicaSet *appsv1.ReplicaSet) (int, error) { return int(*replicaSet.Spec.Replicas), nil } -// GetDeploymentID gets the deployment ID of the provided ReplicaSet. -func GetDeploymentID(replicaSet *appsv1.ReplicaSet) (string, error) { +// getDeploymentID gets the deployment ID of the provided ReplicaSet. +func getDeploymentID(replicaSet *appsv1.ReplicaSet) (string, error) { replicaOwnerRefs := replicaSet.GetOwnerReferences() if len(replicaOwnerRefs) != 1 { return "", fmt.Errorf("expected one owner reference of the NGF ReplicaSet, got %d", len(replicaOwnerRefs)) diff --git a/site/config/_default/config.toml b/site/config/_default/config.toml index 30ec3f734f..a67814f4ff 100644 --- a/site/config/_default/config.toml +++ b/site/config/_default/config.toml @@ -60,7 +60,7 @@ pygmentsUseClasses = true "taxonomy", "taxonomyTerm" ] - logo = "NGINX-product-icon.svg" + logo = "NGINX-Gateway-Fabric-product-icon.svg" sectionPagesMenu = "docs" diff --git a/site/content/get-started.md b/site/content/get-started.md index c9fda29a1b..c68e4a1ed4 100644 --- a/site/content/get-started.md +++ b/site/content/get-started.md @@ -53,6 +53,7 @@ Run the following command: ```shell kind create cluster --config cluster-config.yaml ``` + ```text Creating cluster "kind" ... ✓ Ensuring node image (kindest/node:v1.31.0) 🖼 @@ -75,6 +76,7 @@ If you have cloned [the NGINX Gateway Fabric repository](https://github.com/ngin ```shell make create-kind-cluster ``` + {{< /note >}} --- @@ -86,8 +88,9 @@ make create-kind-cluster Use `kubectl` to add the API resources for NGINX Gateway Fabric with the following command: ```shell -kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.4.0" | kubectl apply -f - +kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.1" | kubectl apply -f - ``` + ```text customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created @@ -100,8 +103,9 @@ customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking To use experimental features, you'll need to install the API resources from the experimental channel instead. ```shell -kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.4.0" | kubectl apply -f - +kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.1" | kubectl apply -f - ``` + {{< /note >}} --- @@ -113,8 +117,9 @@ Use `helm` to install NGINX Gateway Fabric with the following command: ```shell helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric --create-namespace -n nginx-gateway --set service.create=false ``` + ```text -Pulled: ghcr.io/nginxinc/charts/nginx-gateway-fabric:1.4.0 +Pulled: ghcr.io/nginxinc/charts/nginx-gateway-fabric:1.5.1 Digest: sha256:9bbd1a2fcbfd5407ad6be39f796f582e6263512f1f3a8969b427d39063cc6fee NAME: ngf LAST DEPLOYED: Mon Oct 21 14:45:14 2024 @@ -130,6 +135,7 @@ If you installed the API resources from the experimental channel during the last ```shell helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric --create-namespace -n nginx-gateway --set service.create=false --set nginxGateway.gwAPIExperimentalFeatures.enable=true ``` + {{< /note >}} --- @@ -151,7 +157,7 @@ metadata: labels: app.kubernetes.io/name: nginx-gateway-fabric app.kubernetes.io/instance: ngf - app.kubernetes.io/version: "1.4.0" + app.kubernetes.io/version: "1.5.1" spec: type: NodePort selector: @@ -175,6 +181,7 @@ Apply it using `kubectl`: ```shell kubectl apply -f nodeport-config.yaml ``` + ```text service/nginx-gateway created ``` @@ -201,13 +208,14 @@ The YAML code in the following sections can be found in the [cafe-example folder Create the file _cafe.yaml_ with the following contents: -{{< ghcode "https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/refs/heads/main/examples/cafe-example/cafe.yaml">}} +{{< ghcode `https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/refs/heads/main/examples/cafe-example/cafe.yaml`>}} -Apply it: +Apply it using `kubectl`: ```shell kubectl apply -f cafe.yaml ``` + ```text deployment.apps/coffee created service/coffee created @@ -220,6 +228,7 @@ Verify that the new pods are in the `default` namespace: ```shell kubectl -n default get pods ``` + ```text NAME READY STATUS RESTARTS AGE coffee-6db967495b-wk2mm 1/1 Running 0 10s @@ -232,26 +241,28 @@ tea-7b7d6c947d-d4qcf 1/1 Running 0 10s Create the file _gateway.yaml_ with the following contents: -{{< ghcode "https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/refs/heads/main/examples/cafe-example/gateway.yaml">}} +{{< ghcode `https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/refs/heads/main/examples/cafe-example/gateway.yaml`>}} Apply it using `kubectl`: ```shell kubectl apply -f gateway.yaml ``` + ```text gateway.gateway.networking.k8s.io/gateway created ``` Create the file _cafe-routes.yaml_ with the following contents: -{{< ghcode "https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/refs/heads/main/examples/cafe-example/cafe-routes.yaml">}} +{{< ghcode `https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/refs/heads/main/examples/cafe-example/cafe-routes.yaml`>}} Apply it using `kubectl`: ```shell kubectl apply -f cafe-routes.yaml ``` + ```text httproute.gateway.networking.k8s.io/coffee created httproute.gateway.networking.k8s.io/tea created @@ -266,6 +277,7 @@ You can check that all of the expected services are available using `kubectl get ```shell kubectl get service --all-namespaces ``` + ```text NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default coffee ClusterIP 10.96.18.163 80/TCP 2m51s @@ -280,6 +292,7 @@ You can also use `kubectl describe` on the new resources to check their status: ```shell kubectl describe httproutes ``` + ```text Name: coffee Namespace: default @@ -394,6 +407,7 @@ Events: ```shell kubectl describe gateways ``` + ```text Name: gateway Namespace: default @@ -480,6 +494,7 @@ You can use `curl` to test the new services by targeting the hostname (_cafe.exa ```shell curl --resolve cafe.example.com:8080:127.0.0.1 http://cafe.example.com:8080/coffee ``` + ```text Server address: 10.244.0.6:8080 Server name: coffee-6db967495b-wk2mm @@ -491,6 +506,7 @@ Request ID: fb226a54fd94f927b484dd31fb30e747 ```shell curl --resolve cafe.example.com:8080:127.0.0.1 http://cafe.example.com:8080/tea ``` + ```text Server address: 10.244.0.7:8080 Server name: tea-7b7d6c947d-d4qcf diff --git a/site/content/how-to/monitoring/prometheus.md b/site/content/how-to/monitoring/prometheus.md index 20a5c7404d..aca4c3789e 100644 --- a/site/content/how-to/monitoring/prometheus.md +++ b/site/content/how-to/monitoring/prometheus.md @@ -102,11 +102,11 @@ You can configure monitoring metrics for NGINX Gateway Fabric using Helm or Mani ### Using Helm -If you're setting up NGINX Gateway Fabric with Helm, you can adjust the `metrics.*` parameters to fit your needs. For detailed options and instructions, see the [Helm README](https://github.com/nginxinc/nginx-gateway-fabric/blob/v1.5.0/charts/nginx-gateway-fabric/README.md). +If you're setting up NGINX Gateway Fabric with Helm, you can adjust the `metrics.*` parameters to fit your needs. For detailed options and instructions, see the [Helm README](https://github.com/nginxinc/nginx-gateway-fabric/blob/v1.5.1/charts/nginx-gateway-fabric/README.md). ### Using Kubernetes manifests -For setups using Kubernetes manifests, change the metrics configuration by editing the NGINX Gateway Fabric manifest that you want to deploy. You can find some examples in the [deploy](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.0/deploy) directory. +For setups using Kubernetes manifests, change the metrics configuration by editing the NGINX Gateway Fabric manifest that you want to deploy. You can find some examples in the [deploy](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.1/deploy) directory. #### Disabling metrics diff --git a/site/content/how-to/monitoring/troubleshooting.md b/site/content/how-to/monitoring/troubleshooting.md index b5159d73a7..20b96d9c8d 100644 --- a/site/content/how-to/monitoring/troubleshooting.md +++ b/site/content/how-to/monitoring/troubleshooting.md @@ -367,7 +367,7 @@ To **resolve** this issue you will need to set `allowPrivilegeEscalation` to `tr ##### NGINX Plus failure to start or traffic interruptions -Beginning with NGINX Gateway Fabric 1.5.0, NGINX Plus requires a valid JSON Web Token (JWT) to run. If this is not set up properly, or your JWT token has expired, you may see errors in the NGINX logs that look like the following: +Beginning with NGINX Gateway Fabric 1.5.1, NGINX Plus requires a valid JSON Web Token (JWT) to run. If this is not set up properly, or your JWT token has expired, you may see errors in the NGINX logs that look like the following: ```text nginx: [error] invalid license token @@ -469,7 +469,7 @@ If you check your _nginx_ container logs and see the following error: It indicates that `proxy_protocol` is enabled for the gateway listeners, but the request sent to the application endpoint does not contain proxy information. To **resolve** this, you can do one of the following: -- Unassign the field [`rewriteClientIP.mode`](({{< relref "reference/api.md" >}})) in the NginxProxy configuration. +- Unassign the field [`rewriteClientIP.mode`]({{< relref "reference/api.md" >}}) in the NginxProxy configuration. - Send valid proxy information with requests being handled by your application. diff --git a/site/content/how-to/traffic-management/advanced-routing.md b/site/content/how-to/traffic-management/advanced-routing.md index 37cc5c2554..06198334f7 100644 --- a/site/content/how-to/traffic-management/advanced-routing.md +++ b/site/content/how-to/traffic-management/advanced-routing.md @@ -36,7 +36,7 @@ The goal is to create a set of rules that will result in client requests being s Begin by deploying the `coffee-v1` and `coffee-v2` applications: ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/advanced-routing/coffee.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/advanced-routing/coffee.yaml ``` ### Deploy the Gateway API Resources for the Coffee applications @@ -156,7 +156,7 @@ Let's deploy a different set of applications now called `tea` and `tea-post`. Th ### Deploy the Tea applications ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/advanced-routing/tea.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/advanced-routing/tea.yaml ``` ### Deploy the HTTPRoute for the Tea services diff --git a/site/content/how-to/traffic-management/client-settings.md b/site/content/how-to/traffic-management/client-settings.md index 9bf21f0764..ecd92c9afb 100644 --- a/site/content/how-to/traffic-management/client-settings.md +++ b/site/content/how-to/traffic-management/client-settings.md @@ -45,19 +45,19 @@ For all the possible configuration options for `ClientSettingsPolicy`, see the [ - Create the coffee and tea example applications: ```yaml - kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/client-settings-policy/app.yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/client-settings-policy/app.yaml ``` - Create a Gateway: ```yaml - kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/client-settings-policy/gateway.yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/client-settings-policy/gateway.yaml ``` - Create HTTPRoutes for the coffee and tea applications: ```yaml - kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/client-settings-policy/httproutes.yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/client-settings-policy/httproutes.yaml ``` - Test the configuration: diff --git a/site/content/how-to/traffic-management/request-response-headers.md b/site/content/how-to/traffic-management/request-response-headers.md index f3518624c7..a62e01134c 100644 --- a/site/content/how-to/traffic-management/request-response-headers.md +++ b/site/content/how-to/traffic-management/request-response-headers.md @@ -64,7 +64,7 @@ This examples demonstrates how to configure traffic routing for a simple echo se Begin by deploying the example application `headers`. It is a simple application that returns the request headers which will be modified later. ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/http-request-header-filter/headers.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/http-request-header-filter/headers.yaml ``` This will create the headers Service and a Deployment with one Pod. Run the following command to verify the resources were created: @@ -175,7 +175,7 @@ kubectl delete httproutes.gateway.networking.k8s.io headers ``` ```shell -kubectl delete -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/http-request-header-filter/headers.yaml +kubectl delete -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/http-request-header-filter/headers.yaml ``` ## ResponseHeaderModifier example @@ -187,7 +187,7 @@ Begin by configuring an application with custom headers and a simple HTTPRoute. Begin by deploying the example application `headers`. It is a simple application that adds response headers that will be modified later. ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/http-response-header-filter/headers.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/http-response-header-filter/headers.yaml ``` This will create the headers Service and a Deployment with one Pod. Run the following command to verify the resources were created: diff --git a/site/content/how-to/traffic-management/snippets.md b/site/content/how-to/traffic-management/snippets.md index e986042ad6..469682401a 100644 --- a/site/content/how-to/traffic-management/snippets.md +++ b/site/content/how-to/traffic-management/snippets.md @@ -73,19 +73,19 @@ We have outlined a few best practices to keep in mind when using `SnippetsFilter - Create the coffee and tea example applications: ```yaml - kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/snippets-filter/app.yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/snippets-filter/app.yaml ``` - Create a Gateway: ```yaml - kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/snippets-filter/gateway.yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/snippets-filter/gateway.yaml ``` - Create HTTPRoutes for the coffee and tea applications: ```yaml - kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/examples/snippets-filter/httproutes.yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/examples/snippets-filter/httproutes.yaml ``` - Test the configuration: diff --git a/site/content/how-to/upgrade-apps-without-downtime.md b/site/content/how-to/upgrade-apps-without-downtime.md index 2c50fce0c7..0feaf8cf5c 100644 --- a/site/content/how-to/upgrade-apps-without-downtime.md +++ b/site/content/how-to/upgrade-apps-without-downtime.md @@ -56,7 +56,7 @@ For example, an application can be exposed using a routing rule like below: port: 80 ``` -{{< note >}}See the [Cafe example](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.0/examples/cafe-example) for a basic example.{{< /note >}} +{{< note >}}See the [Cafe example](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.1/examples/cafe-example) for a basic example.{{< /note >}} The upgrade methods in the next sections cover: @@ -121,4 +121,4 @@ By updating the rule you can further increase the share of traffic the new versi weight: 1 ``` -See the [Traffic splitting example](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.0/examples/traffic-splitting) from our repository. +See the [Traffic splitting example](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.1/examples/traffic-splitting) from our repository. diff --git a/site/content/includes/installation/install-gateway-api-experimental-features.md b/site/content/includes/installation/install-gateway-api-experimental-features.md index e9a516e903..1881e314c2 100644 --- a/site/content/includes/installation/install-gateway-api-experimental-features.md +++ b/site/content/includes/installation/install-gateway-api-experimental-features.md @@ -10,7 +10,7 @@ To use Gateway API experimental resources, the Gateway API resources from the ex To install the Gateway API resources from the experimental channel, run the following: ```shell -kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.0" | kubectl apply -f - +kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.1" | kubectl apply -f - ``` {{< note >}}If you plan to use the `edge` version of NGINX Gateway Fabric, you can replace the version in `ref` with `main`, for example `ref=main`. {{}} diff --git a/site/content/includes/installation/install-gateway-api-resources.md b/site/content/includes/installation/install-gateway-api-resources.md index 9fa5a82956..8b0f853406 100644 --- a/site/content/includes/installation/install-gateway-api-resources.md +++ b/site/content/includes/installation/install-gateway-api-resources.md @@ -2,12 +2,12 @@ docs: "DOCS-1438" --- -{{< note >}} The [Gateway API resources](https://github.com/kubernetes-sigs/gateway-api) from the standard channel must be installed before deploying NGINX Gateway Fabric. If they are already installed in your cluster, please ensure they are the correct version as supported by the NGINX Gateway Fabric - [see the Technical Specifications](https://github.com/nginxinc/nginx-gateway-fabric/blob/v1.5.0/README.md#technical-specifications). {{}} +{{< note >}} The [Gateway API resources](https://github.com/kubernetes-sigs/gateway-api) from the standard channel must be installed before deploying NGINX Gateway Fabric. If they are already installed in your cluster, please ensure they are the correct version as supported by the NGINX Gateway Fabric - [see the Technical Specifications](https://github.com/nginxinc/nginx-gateway-fabric/blob/v1.5.1/README.md#technical-specifications). {{}} To install the Gateway API resources, run the following: ```shell -kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.0" | kubectl apply -f - +kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.1" | kubectl apply -f - ``` {{< note >}}If you plan to use the `edge` version of NGINX Gateway Fabric, you can replace the version in `ref` with `main`, for example `ref=main`.{{}} @@ -18,7 +18,7 @@ NGINX Gateway Fabric currently supports a subset of the additional features prov To install from the experimental channel, run the following: ```shell -kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.0" | kubectl apply -f - +kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.1" | kubectl apply -f - ``` {{< note >}} To learn more about what Gateway API resources NGINX Gateway Fabric currently supports, visit our [Gateway API Compatibility]({{< relref "overview/gateway-api-compatibility.md" >}}) document. {{}} diff --git a/site/content/includes/installation/uninstall-gateway-api-resources.md b/site/content/includes/installation/uninstall-gateway-api-resources.md index 94e6a886c5..16f91e9864 100644 --- a/site/content/includes/installation/uninstall-gateway-api-resources.md +++ b/site/content/includes/installation/uninstall-gateway-api-resources.md @@ -7,11 +7,11 @@ docs: "DOCS-1436" To uninstall the Gateway API resources, run the following: ```shell -kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.0" | kubectl delete -f - +kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.1" | kubectl delete -f - ``` Alternatively, if you installed the Gateway APIs from the experimental channel, run the following: ```shell -kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.0" | kubectl delete -f - +kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.1" | kubectl delete -f - ``` diff --git a/site/content/installation/building-the-images.md b/site/content/installation/building-the-images.md index b294d5fb7b..84d550c3a3 100644 --- a/site/content/installation/building-the-images.md +++ b/site/content/installation/building-the-images.md @@ -26,7 +26,7 @@ If building the NGINX Plus image, you will also need a valid NGINX Plus license 1. Clone the repo and change into the `nginx-gateway-fabric` directory: ```shell - git clone https://github.com/nginxinc/nginx-gateway-fabric.git --branch v1.5.0 + git clone https://github.com/nginxinc/nginx-gateway-fabric.git --branch v1.5.1 cd nginx-gateway-fabric ``` @@ -62,20 +62,20 @@ If building the NGINX Plus image, you will also need a valid NGINX Plus license ``` Set the `PREFIX` variable to the name of the registry you'd like to push the image to. By default, the images will be - named `nginx-gateway-fabric:1.5.0` and `nginx-gateway-fabric/nginx:1.5.0` or `nginx-gateway-fabric/nginx-plus:1.5.0`. + named `nginx-gateway-fabric:1.5.1` and `nginx-gateway-fabric/nginx:1.5.1` or `nginx-gateway-fabric/nginx-plus:1.5.1`. 1. Push the images to your container registry: ```shell - docker push myregistry.example.com/nginx-gateway-fabric:1.5.0 - docker push myregistry.example.com/nginx-gateway-fabric/nginx:1.5.0 + docker push myregistry.example.com/nginx-gateway-fabric:1.5.1 + docker push myregistry.example.com/nginx-gateway-fabric/nginx:1.5.1 ``` or ```shell - docker push myregistry.example.com/nginx-gateway-fabric:1.5.0 - docker push myregistry.example.com/nginx-gateway-fabric/nginx-plus:1.5.0 + docker push myregistry.example.com/nginx-gateway-fabric:1.5.1 + docker push myregistry.example.com/nginx-gateway-fabric/nginx-plus:1.5.1 ``` Make sure to substitute `myregistry.example.com/nginx-gateway-fabric` with your registry. diff --git a/site/content/installation/installing-ngf/helm.md b/site/content/installation/installing-ngf/helm.md index 02cfbf9490..57a7595baf 100644 --- a/site/content/installation/installing-ngf/helm.md +++ b/site/content/installation/installing-ngf/helm.md @@ -9,7 +9,7 @@ docs: "DOCS-1430" Learn how to install, upgrade, and uninstall NGINX Gateway Fabric in a Kubernetes cluster using Helm. -{{< important >}} NGINX Plus users that are upgrading from version 1.4.0 to 1.5.0 need to install an NGINX Plus JWT +{{< important >}} NGINX Plus users that are upgrading from version 1.4.0 to 1.5.x need to install an NGINX Plus JWT Secret before upgrading. Follow the steps in the [Before you begin](#before-you-begin) section to create the Secret. If you use a different name than the default `nplus-license` name, specify the Secret name by setting `--set nginx.usage.secretName=` when running `helm upgrade`. {{< /important >}} ## Before you begin @@ -49,6 +49,8 @@ To complete this guide, you'll need to install: ### Install from the OCI registry +The following steps install NGINX Gateway Fabric directly from the OCI helm registry. If you prefer, you can [install from sources](#install-from-sources) instead. + {{}} {{%tab name="NGINX"%}} @@ -68,7 +70,7 @@ helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric --create-nam To install the latest stable release of NGINX Gateway Fabric in the **nginx-gateway** namespace, run the following command: ```shell -helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric --set nginx.image.repository=private-registry.nginx.com/nginx-gateway-fabric/nginx-plus --set nginx.plus=true --set serviceAccount.imagePullSecret=nginx-plus-registry-secret --create-namespace -n nginx-gateway +helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric --set nginx.image.repository=private-registry.nginx.com/nginx-gateway-fabric/nginx-plus --set nginx.plus=true --set serviceAccount.imagePullSecret=nginx-plus-registry-secret -n nginx-gateway ``` {{% /tab %}} @@ -77,7 +79,7 @@ helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric --set nginx `ngf` is the name of the release, and can be changed to any name you want. This name is added as a prefix to the Deployment name. -If the namespace already exists, you can omit the optional `--create-namespace` flag. If you want the latest version from the **main** branch, add `--version 0.0.0-edge` to your install command. +If you want the latest version from the **main** branch, add `--version 0.0.0-edge` to your install command. To wait for the Deployment to be ready, you can either add the `--wait` flag to the `helm install` command, or run the following after installing: @@ -87,6 +89,7 @@ kubectl wait --timeout=5m -n nginx-gateway deployment/ngf-nginx-gateway-fabric - ### Install from sources {#install-from-sources} +If you prefer to install directly from sources, instead of through the OCI helm registry, use the following steps. {{}} @@ -109,7 +112,7 @@ helm install ngf . --create-namespace -n nginx-gateway To install the chart into the **nginx-gateway** namespace, run the following command: ```shell -helm install ngf . --set nginx.image.repository=private-registry.nginx.com/nginx-gateway-fabric/nginx-plus --set nginx.plus=true --set serviceAccount.imagePullSecret=nginx-plus-registry-secret --create-namespace -n nginx-gateway +helm install ngf . --set nginx.image.repository=private-registry.nginx.com/nginx-gateway-fabric/nginx-plus --set nginx.plus=true --set serviceAccount.imagePullSecret=nginx-plus-registry-secret -n nginx-gateway ``` {{% /tab %}} @@ -118,8 +121,6 @@ helm install ngf . --set nginx.image.repository=private-registry.nginx.com/nginx `ngf` is the name of the release, and can be changed to any name you want. This name is added as a prefix to the Deployment name. - If the namespace already exists, you can omit the optional `--create-namespace` flag. - To wait for the Deployment to be ready, you can either add the `--wait` flag to the `helm install` command, or run the following after installing: ```shell @@ -157,7 +158,7 @@ helm install ngf oci://ghcr.io/nginxinc/charts/nginx-gateway-fabric --create-nam #### Examples -You can find several examples of configuration options of the `values.yaml` file in the [helm examples](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.0/examples/helm) directory. +You can find several examples of configuration options of the `values.yaml` file in the [helm examples](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.1/examples/helm) directory. ### Access NGINX Gateway Fabric @@ -178,13 +179,13 @@ To upgrade your Gateway API resources, take the following steps: - To upgrade the Gateway API resources, run: ```shell - kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.0" | kubectl apply -f - + kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.1" | kubectl apply -f - ``` or, if you installed the from the experimental channel: ```shell - kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.0" | kubectl apply -f - + kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.1" | kubectl apply -f - ``` ### Upgrade NGINX Gateway Fabric CRDs @@ -198,7 +199,7 @@ To upgrade the CRDs, take the following steps: 2. Upgrade the CRDs: ```shell - kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/crds.yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/crds.yaml ``` {{}}Ignore the following warning, as it is expected.{{}} @@ -209,9 +210,11 @@ To upgrade the CRDs, take the following steps: ### Upgrade NGINX Gateway Fabric release -{{< important >}} NGINX Plus users that are upgrading from version 1.4.0 to 1.5.0 need to install an NGINX Plus JWT +{{< important >}} NGINX Plus users that are upgrading from version 1.4.0 to 1.5.x need to install an NGINX Plus JWT Secret before upgrading. Follow the steps in the [Before you begin](#before-you-begin) section to create the Secret. If you use a different name than the default `nplus-license` name, specify the Secret name by setting `--set nginx.usage.secretName=` when running `helm upgrade`. {{}} +There are two possible ways to upgrade NGINX Gateway Fabric. You can either upgrade from the OCI registry, or download the chart and upgrade from the source. + #### Upgrade from the OCI registry - To upgrade to the latest stable release of NGINX Gateway Fabric, run: @@ -315,7 +318,7 @@ Follow these steps to uninstall NGINX Gateway Fabric and Gateway API from your K ```shell kubectl delete ns nginx-gateway - kubectl delete -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/crds.yaml + kubectl delete -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/crds.yaml ``` 3. **Remove the Gateway API resources:** @@ -324,4 +327,4 @@ Follow these steps to uninstall NGINX Gateway Fabric and Gateway API from your K ## Additional configuration -For a full list of the Helm Chart configuration parameters, read [the NGINX Gateway Fabric Helm Chart](https://github.com/nginxinc/nginx-gateway-fabric/blob/v1.5.0/charts/nginx-gateway-fabric/README.md#configuration). +For a full list of the Helm Chart configuration parameters, read [the NGINX Gateway Fabric Helm Chart](https://github.com/nginxinc/nginx-gateway-fabric/blob/v1.5.1/charts/nginx-gateway-fabric/README.md#configuration). diff --git a/site/content/installation/installing-ngf/manifests.md b/site/content/installation/installing-ngf/manifests.md index 875a8a08c3..dad91d5527 100644 --- a/site/content/installation/installing-ngf/manifests.md +++ b/site/content/installation/installing-ngf/manifests.md @@ -9,7 +9,7 @@ docs: "DOCS-1429" Learn how to install, upgrade, and uninstall NGINX Gateway Fabric using Kubernetes manifests. -{{< important >}} NGINX Plus users that are upgrading from version 1.4.0 to 1.5.0 need to install an NGINX Plus JWT +{{< important >}} NGINX Plus users that are upgrading from version 1.4.0 to 1.5.x need to install an NGINX Plus JWT Secret before upgrading. Follow the steps in the [Before you begin](#before-you-begin) section to create the Secret, which is referenced in the updated deployment manifest for the newest version. {{< /important >}} ## Before you begin @@ -53,7 +53,7 @@ Deploying NGINX Gateway Fabric with Kubernetes manifests takes only a few steps. #### Stable release ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/crds.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/crds.yaml ``` #### Edge version @@ -73,7 +73,7 @@ kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric Deploys NGINX Gateway Fabric with NGINX OSS. ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/default/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/default/deploy.yaml ``` {{% /tab %}} @@ -83,7 +83,7 @@ kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric Deploys NGINX Gateway Fabric with NGINX OSS and an AWS Network Load Balancer service. ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/aws-nlb/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/aws-nlb/deploy.yaml ``` {{% /tab %}} @@ -93,7 +93,7 @@ kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric Deploys NGINX Gateway Fabric with NGINX OSS and `nodeSelector` to deploy on Linux nodes. ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/azure/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/azure/deploy.yaml ``` {{% /tab %}} @@ -105,7 +105,7 @@ NGINX Plus Docker registry, and the `imagePullSecretName` is the name of the Sec The NGINX Plus JWT Secret used to run NGINX Plus is also specified in a volume mount and the `--usage-report-secret` parameter. These Secrets are created as part of the [Before you begin](#before-you-begin) section. ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/nginx-plus/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/nginx-plus/deploy.yaml ``` {{% /tab %}} @@ -115,7 +115,7 @@ kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric Deploys NGINX Gateway Fabric with NGINX OSS and experimental features. ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/experimental/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/experimental/deploy.yaml ``` {{< note >}} Requires the Gateway APIs installed from the experimental channel. {{< /note >}} @@ -129,7 +129,7 @@ NGINX Plus Docker registry, and the `imagePullSecretName` is the name of the Sec The NGINX Plus JWT Secret used to run NGINX Plus is also specified in a volume mount and the `--usage-report-secret` parameter. These Secrets are created as part of the [Before you begin](#before-you-begin) section. ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/nginx-plus-experimental/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/nginx-plus-experimental/deploy.yaml ``` {{< note >}} Requires the Gateway APIs installed from the experimental channel. {{< /note >}} @@ -141,7 +141,7 @@ kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric Deploys NGINX Gateway Fabric with NGINX OSS using a Service type of `NodePort`. ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/nodeport/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/nodeport/deploy.yaml ``` {{% /tab %}} @@ -151,7 +151,7 @@ kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric Deploys NGINX Gateway Fabric with NGINX OSS on OpenShift. ```shell -kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/openshift/deploy.yaml +kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/openshift/deploy.yaml ``` {{% /tab %}} @@ -179,7 +179,7 @@ nginx-gateway-5d4f4c7db7-xk2kq 2/2 Running 0 112s ## Upgrade NGINX Gateway Fabric -{{< important >}} NGINX Plus users that are upgrading from version 1.4.0 to 1.5.0 need to install an NGINX Plus JWT +{{< important >}} NGINX Plus users that are upgrading from version 1.4.0 to 1.5.x need to install an NGINX Plus JWT Secret before upgrading. Follow the steps in the [Before you begin](#before-you-begin) section to create the Secret, which is referenced in the updated deployment manifest for the newest version. {{< /important >}} {{}}For guidance on zero downtime upgrades, see the [Delay Pod Termination](#configure-delayed-pod-termination-for-zero-downtime-upgrades) section below.{{}} @@ -193,13 +193,13 @@ To upgrade NGINX Gateway Fabric and get the latest features and improvements, ta - To upgrade the Gateway API resources, run: ```shell - kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.0" | kubectl apply -f - + kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.1" | kubectl apply -f - ``` or, if you installed the from the experimental channel: ```shell - kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.0" | kubectl apply -f - + kubectl kustomize "https://github.com/nginxinc/nginx-gateway-fabric/config/crd/gateway-api/experimental?ref=v1.5.1" | kubectl apply -f - ``` 1. **Upgrade NGINX Gateway Fabric CRDs:** @@ -207,7 +207,7 @@ To upgrade NGINX Gateway Fabric and get the latest features and improvements, ta - To upgrade the Custom Resource Definitions (CRDs), run: ```shell - kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/crds.yaml + kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/crds.yaml ``` 1. **Upgrade NGINX Gateway Fabric deployment:** @@ -278,7 +278,7 @@ Follow these steps to uninstall NGINX Gateway Fabric and Gateway API from your K ``` ```shell - kubectl delete -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.0/deploy/crds.yaml + kubectl delete -f https://raw.githubusercontent.com/nginxinc/nginx-gateway-fabric/v1.5.1/deploy/crds.yaml ``` 1. **Remove the Gateway API resources:** diff --git a/site/content/installation/nginx-plus-jwt.md b/site/content/installation/nginx-plus-jwt.md index 220fd0ef32..a2f79792a1 100644 --- a/site/content/installation/nginx-plus-jwt.md +++ b/site/content/installation/nginx-plus-jwt.md @@ -83,6 +83,8 @@ and the following volume mount to the `nginx` container: {{}} +**If you are reporting to the default licensing endpoint, then you can now proceed with [installing NGINX Gateway Fabric]({{< relref "installation/installing-ngf" >}}). Otherwise, follow the steps below to configure reporting to NGINX Instance Manager.** + ### Reporting to NGINX Instance Manager {#nim} If you are deploying NGINX Gateway Fabric in an environment where you need to report to NGINX Instance Manager instead of the default licensing endpoint, a few extra steps may be required. diff --git a/site/content/overview/gateway-architecture.md b/site/content/overview/gateway-architecture.md index c3b829b0eb..b31bcd3b71 100644 --- a/site/content/overview/gateway-architecture.md +++ b/site/content/overview/gateway-architecture.md @@ -21,7 +21,7 @@ NGINX Gateway Fabric is an open source project that provides an implementation o For a list of supported Gateway API resources and features, see the [Gateway API Compatibility]({{< relref "/overview/gateway-api-compatibility.md" >}}) documentation. -We have more information regarding our [design principles](https://github.com/nginxinc/nginx-gateway-fabric/blob/v1.5.0/docs/developer/design-principles.md) in the project's GitHub repository. +We have more information regarding our [design principles](https://github.com/nginxinc/nginx-gateway-fabric/blob/v1.5.1/docs/developer/design-principles.md) in the project's GitHub repository. ## NGINX Gateway Fabric at a high level @@ -72,7 +72,7 @@ The following list describes the connections, preceeded by their types in parent 1. (HTTPS) - Read: _NGF_ reads the _Kubernetes API_ to get the latest versions of the resources in the cluster. - - Write: _NGF_ writes to the _Kubernetes API_ to update the handled resources' statuses and emit events. If there's more than one replica of _NGF_ and [leader election](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.0/charts/nginx-gateway-fabric#configuration) is enabled, only the _NGF_ pod that is leading will write statuses to the _Kubernetes API_. + - Write: _NGF_ writes to the _Kubernetes API_ to update the handled resources' statuses and emit events. If there's more than one replica of _NGF_ and [leader election](https://github.com/nginxinc/nginx-gateway-fabric/tree/v1.5.1/charts/nginx-gateway-fabric#configuration) is enabled, only the _NGF_ pod that is leading will write statuses to the _Kubernetes API_. 1. (HTTP, HTTPS) _Prometheus_ fetches the `controller-runtime` and NGINX metrics via an HTTP endpoint that _NGF_ exposes (`:9113/metrics` by default). Prometheus is **not** required by NGINX Gateway Fabric, and its endpoint can be turned off. 1. (File I/O) - Write: _NGF_ generates NGINX _configuration_ based on the cluster resources and writes them as `.conf` files to the mounted `nginx-conf` volume, located at `/etc/nginx/conf.d`. It also writes _TLS certificates_ and _keys_ from [TLS secrets](https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets) referenced in the accepted Gateway resource to the `nginx-secrets` volume at the path `/etc/nginx/secrets`. @@ -86,7 +86,7 @@ The following list describes the connections, preceeded by their types in parent 1. (File I/O) - Write: The _NGINX master_ writes to the auxiliary Unix sockets folder, which is located in the `/var/run/nginx` directory. - - Read: The _NGINX master_ reads the `nginx.conf` file from the `/etc/nginx` directory. This [file](https://github.com/nginxinc/nginx-gateway-fabric/blob/v1.5.0/internal/mode/static/nginx/conf/nginx.conf) contains the global and http configuration settings for NGINX. In addition, _NGINX master_ reads the NJS modules referenced in the configuration when it starts or during a reload. NJS modules are stored in the `/usr/lib/nginx/modules` directory. + - Read: The _NGINX master_ reads the `nginx.conf` file from the `/etc/nginx` directory. This [file](https://github.com/nginxinc/nginx-gateway-fabric/blob/v1.5.1/internal/mode/static/nginx/conf/nginx.conf) contains the global and http configuration settings for NGINX. In addition, _NGINX master_ reads the NJS modules referenced in the configuration when it starts or during a reload. NJS modules are stored in the `/usr/lib/nginx/modules` directory. 1. (File I/O) The _NGINX master_ sends logs to its _stdout_ and _stderr_, which are collected by the container runtime. 1. (File I/O) An _NGINX worker_ writes logs to its _stdout_ and _stderr_, which are collected by the container runtime. 1. (Signal) The _NGINX master_ controls the [lifecycle of _NGINX workers_](https://nginx.org/en/docs/control.html#reconfiguration) it creates workers with the new configuration and shutdowns workers with the old configuration. diff --git a/site/content/support.md b/site/content/support.md index 5fda3b44b7..061929b2c9 100644 --- a/site/content/support.md +++ b/site/content/support.md @@ -5,7 +5,27 @@ weight: 600 docs: "DOCS-1411" --- -NGINX Gateway Fabric adheres to the support policy detailed in the following knowledge base article: [K000140156](https://my.f5.com/manage/s/article/K000140156). +F5 NGINX Gateway Fabric adheres to the support policy detailed in the following knowledge base article: [K000140156](https://my.f5.com/manage/s/article/K000140156). + +After opening a support ticket, F5 staff will request additional information to better understand the problem. + +The [nginx-supportpkg-for-k8s](https://github.com/nginxinc/nginx-supportpkg-for-k8s) plugin collects the information needed by F5 Technical Support to assist with troubleshooting your issue. + +The plugin uses [krew](https://krew.sigs.k8s.io), the plugin manager for the Kubernetes [kubectl](https://kubernetes.io/docs/reference/kubectl/) command-line tool. + +The plugin may collect some or all of the following global and namespace-specific information: + +- Kubernetes version and information about Nodes and Custom Resources +- Kubernetes metrics +- Helm deployments +- List of Pods, Events, ConfigMaps, Services, Deployments, Daemonsets, StatefulSets, ReplicaSets, and Leases +- Pod log output +- `nginx -T` output from NGINX-related Pods + +This plugin **does not** collect secrets or coredumps. + +Visit the [project’s GitHub repository](https://github.com/nginxinc/nginx-supportpkg-for-k8s) for further details. + **Support Channels:** diff --git a/site/go.mod b/site/go.mod index 1e2b2ee840..4145091b7d 100644 --- a/site/go.mod +++ b/site/go.mod @@ -2,4 +2,4 @@ module github.com/nginxinc/nginx-gateway-fabric/site go 1.21 -require github.com/nginxinc/nginx-hugo-theme v0.41.22 // indirect +require github.com/nginxinc/nginx-hugo-theme v0.41.23 // indirect diff --git a/site/go.sum b/site/go.sum index 1819ea06c2..6bf2752ad6 100644 --- a/site/go.sum +++ b/site/go.sum @@ -1,2 +1,2 @@ -github.com/nginxinc/nginx-hugo-theme v0.41.22 h1:Gb/OLbpumNqp8vOPkZzO2GmgPDRd1yr2tWHWUBHg8BA= -github.com/nginxinc/nginx-hugo-theme v0.41.22/go.mod h1:DPNgSS5QYxkjH/BfH4uPDiTfODqWJ50NKZdorguom8M= +github.com/nginxinc/nginx-hugo-theme v0.41.23 h1:ddIfLF7BFd78qyIn3z5aReeC4BO/m9FH81d5S+al/6s= +github.com/nginxinc/nginx-hugo-theme v0.41.23/go.mod h1:DPNgSS5QYxkjH/BfH4uPDiTfODqWJ50NKZdorguom8M= diff --git a/tests/Makefile b/tests/Makefile index 529e052322..9f58422b00 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -109,7 +109,7 @@ sync-files-to-vm: ## Syncs your local NGF files with the NGF repo on the VM ./scripts/sync-files-to-vm.sh .PHONY: nfr-test -nfr-test: ## Run the NFR tests on a GCP VM +nfr-test: check-for-plus-usage-endpoint ## Run the NFR tests on a GCP VM CI=$(CI) ./scripts/run-tests-gcp-vm.sh .PHONY: start-longevity-test @@ -130,7 +130,7 @@ stop-longevity-test: nfr-test ## Stop the longevity test and collects results --ngf-image-repo=$(PREFIX) --nginx-image-repo=$(NGINX_PREFIX) --nginx-plus-image-repo=$(NGINX_PLUS_PREFIX) \ --pull-policy=$(PULL_POLICY) --service-type=$(GW_SERVICE_TYPE) \ --is-gke-internal-lb=$(GW_SVC_GKE_INTERNAL) --plus-enabled=$(PLUS_ENABLED) \ - --plus-license-file-name=$(PLUS_LICENSE_FILE) + --plus-license-file-name=$(PLUS_LICENSE_FILE) --plus-usage-endpoint=$(PLUS_USAGE_ENDPOINT) .PHONY: test test: build-crossplane-image ## Runs the functional tests on your kind k8s cluster @@ -143,11 +143,11 @@ test: build-crossplane-image ## Runs the functional tests on your kind k8s clust --ngf-image-repo=$(PREFIX) --nginx-image-repo=$(NGINX_PREFIX) --nginx-plus-image-repo=$(NGINX_PLUS_PREFIX) \ --pull-policy=$(PULL_POLICY) --service-type=$(GW_SERVICE_TYPE) \ --is-gke-internal-lb=$(GW_SVC_GKE_INTERNAL) --cluster-name=$(CLUSTER_NAME) --plus-enabled=$(PLUS_ENABLED) \ - --plus-license-file-name=$(PLUS_LICENSE_FILE) + --plus-license-file-name=$(PLUS_LICENSE_FILE) --plus-usage-endpoint=$(PLUS_USAGE_ENDPOINT) .PHONY: test-with-plus test-with-plus: PLUS_ENABLED=true -test-with-plus: test ## Runs the functional tests for NGF with NGINX Plus on your default k8s cluster +test-with-plus: check-for-plus-usage-endpoint test ## Runs the functional tests for NGF with NGINX Plus on your default k8s cluster .PHONY: cleanup-gcp cleanup-gcp: cleanup-router cleanup-vm delete-gke-cluster ## Cleanup all GCP resources @@ -177,7 +177,7 @@ deploy-updated-provisioner: ## Update provisioner manifest and deploy to the con .PHONY: generate-static-deployment generate-static-deployment: - helm template nginx-gateway $(CHART_DIR) --set nameOverride=nginx-gateway --set metrics.enable=false --set nginxGateway.productTelemetry.enable=false -n nginx-gateway -s templates/deployment.yaml --set nginxGateway.image.repository=$(PREFIX) --set nginxGateway.image.tag=$(TAG) --set nginxGateway.image.pullPolicy=Never --set nginx.image.repository=$(NGINX_PREFIX) --set nginx.image.tag=$(TAG) --set nginx.image.pullPolicy=Never --set nginxGateway.gwAPIExperimentalFeatures.enable=$(ENABLE_EXPERIMENTAL) --set nginx.plus=$(PLUS_ENABLED) > $(SELF_DIR)config/tests/static-deployment.yaml + helm template nginx-gateway $(CHART_DIR) --set nameOverride=nginx-gateway --set metrics.enable=false --set nginxGateway.productTelemetry.enable=false -n nginx-gateway -s templates/deployment.yaml --set nginxGateway.image.repository=$(PREFIX) --set nginxGateway.image.tag=$(TAG) --set nginxGateway.image.pullPolicy=Never --set nginx.image.repository=$(NGINX_PREFIX) --set nginx.image.tag=$(TAG) --set nginx.image.pullPolicy=Never --set nginxGateway.gwAPIExperimentalFeatures.enable=$(ENABLE_EXPERIMENTAL) --set nginx.plus=$(PLUS_ENABLED) --set nginx.usage.endpoint=$(PLUS_USAGE_ENDPOINT) > $(SELF_DIR)config/tests/static-deployment.yaml # this target is used to install the gateway-api CRDs from the main branch (only used in the nightly CI job) # it overrides the target in the main Makefile when the GW_API_VERSION is set to main diff --git a/tests/conformance/provisioner/provisioner.yaml b/tests/conformance/provisioner/provisioner.yaml index 5862ee37ec..c058d3ecde 100644 --- a/tests/conformance/provisioner/provisioner.yaml +++ b/tests/conformance/provisioner/provisioner.yaml @@ -68,7 +68,7 @@ spec: spec: serviceAccountName: nginx-gateway-provisioner containers: - - image: ghcr.io/nginxinc/nginx-gateway-fabric:edge + - image: ghcr.io/nginxinc/nginx-gateway-fabric:1.5.1 imagePullPolicy: Always name: nginx-gateway-provisioner securityContext: diff --git a/tests/framework/ngf.go b/tests/framework/ngf.go index 6c3008d882..691343cabc 100644 --- a/tests/framework/ngf.go +++ b/tests/framework/ngf.go @@ -33,8 +33,9 @@ type InstallationConfig struct { ImageTag string ImagePullPolicy string ServiceType string - IsGKEInternalLB bool + PlusUsageEndpoint string Plus bool + IsGKEInternalLB bool } // InstallGatewayAPI installs the specified version of the Gateway API resources. @@ -78,6 +79,7 @@ func InstallNGF(cfg InstallationConfig, extraArgs ...string) ([]byte, error) { } args = append(args, setImageArgs(cfg)...) + args = append(args, setPlusUsageEndpointArg(cfg)...) fullArgs := append(args, extraArgs...) //nolint:gocritic GinkgoWriter.Printf("Installing NGF with command: helm %v\n", strings.Join(fullArgs, " ")) @@ -226,6 +228,15 @@ func setImageArgs(cfg InstallationConfig) []string { return args } +func setPlusUsageEndpointArg(cfg InstallationConfig) []string { + var args []string + if cfg.Plus && cfg.PlusUsageEndpoint != "" { + args = append(args, formatValueSet("nginx.usage.endpoint", cfg.PlusUsageEndpoint)...) + } + + return args +} + func formatValueSet(key, value string) []string { return []string{"--set", fmt.Sprintf("%s=%s", key, value)} } diff --git a/tests/suite/graceful_recovery_test.go b/tests/suite/graceful_recovery_test.go index 4ec106c708..a45b23635a 100644 --- a/tests/suite/graceful_recovery_test.go +++ b/tests/suite/graceful_recovery_test.go @@ -367,7 +367,7 @@ func checkContainerLogsForErrors(ngfPodName string, checkNginxLogsOnly bool) { Expect(line).ToNot(ContainSubstring("[emerg]"), line) if strings.Contains(line, "[error]") { expectedError1 := "connect() failed (111: Connection refused)" - expectedError2 := "product.connect.nginx.com could not be resolved" + expectedError2 := "could not be resolved (host not found) during usage report" expectedError3 := "server returned 429" // FIXME(salonichf5) remove this error message check // when https://github.com/nginxinc/nginx-gateway-fabric/issues/2090 is completed. diff --git a/tests/suite/system_suite_test.go b/tests/suite/system_suite_test.go index 7c51bc8e97..2575720c15 100644 --- a/tests/suite/system_suite_test.go +++ b/tests/suite/system_suite_test.go @@ -62,6 +62,7 @@ var ( isGKEInternalLB = flag.Bool("is-gke-internal-lb", false, "Is the LB service GKE internal only") plusEnabled = flag.Bool("plus-enabled", false, "Is NGINX Plus enabled") plusLicenseFileName = flag.String("plus-license-file-name", "", "File name containing the NGINX Plus JWT") + plusUsageEndpoint = flag.String("plus-usage-endpoint", "", "Endpoint for reporting NGINX Plus usage") clusterName = flag.String("cluster-name", "kind", "Cluster name") ) @@ -190,12 +191,13 @@ func setup(cfg setupConfig, extraInstallArgs ...string) { func createNGFInstallConfig(cfg setupConfig, extraInstallArgs ...string) framework.InstallationConfig { installCfg := framework.InstallationConfig{ - ReleaseName: cfg.releaseName, - Namespace: ngfNamespace, - ChartPath: cfg.chartPath, - ServiceType: *serviceType, - IsGKEInternalLB: *isGKEInternalLB, - Plus: *plusEnabled, + ReleaseName: cfg.releaseName, + Namespace: ngfNamespace, + ChartPath: cfg.chartPath, + ServiceType: *serviceType, + IsGKEInternalLB: *isGKEInternalLB, + Plus: *plusEnabled, + PlusUsageEndpoint: *plusUsageEndpoint, } // if we aren't installing from the public charts, then set the custom images