Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
dd99515
Update inference design (#3902)
sjberman Sep 15, 2025
01cfcba
Update curlimages/curl Docker tag to v8.16.0 (#3897)
renovate[bot] Sep 15, 2025
c96694b
Tests/improve nfr logging (#3872)
tataruty Sep 15, 2025
4e3dc46
Update sigstore/cosign-installer action to v3.10.0 (#3903)
renovate[bot] Sep 15, 2025
635b3fc
Set NGINX Plus default image (#3919)
sjberman Sep 15, 2025
43245fb
NFR Test Results for NGF version edge
nginx-bot Sep 16, 2025
e179aac
Update anchore/scan-action action to v7 (#3925)
renovate[bot] Sep 16, 2025
abec621
Update Helm release opentelemetry-collector to v0.134.0 (#3924)
renovate[bot] Sep 16, 2025
cd96a13
Update dependency goreleaser/goreleaser to v2.12.1 (#3923)
renovate[bot] Sep 16, 2025
84a517f
Update anchore/sbom-action action to v0.20.6 (#3922)
renovate[bot] Sep 16, 2025
97a47be
Merge branch 'main' into tests/nfr-tests-edge
salonichf5 Sep 16, 2025
8bd27a3
NGINX Plus: support `enforce_initial_report` field (#3899)
tataruty Sep 17, 2025
5c3fc1b
Update lucacome/draft-release action to v2 (#3927)
renovate[bot] Sep 17, 2025
d41c43f
Merge branch 'main' into tests/nfr-tests-edge
sjberman Sep 17, 2025
24e0cb6
Improve connection reset handling during ServiceAccountToken rotation…
ciarams87 Sep 17, 2025
36788a1
Add support for gateway addresses field (#3896)
bjee19 Sep 17, 2025
ffed3ae
Merge branch 'main' into tests/nfr-tests-edge
ciarams87 Sep 18, 2025
cbf7936
Update dependency nginx/agent to v3.3.1 (#3934)
renovate[bot] Sep 18, 2025
952bc7f
Merge branch 'main' into tests/nfr-tests-edge
ciarams87 Sep 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ jobs:
- name: Scan SBOM
id: scan
if: ${{ !inputs.dry_run }}
uses: anchore/scan-action@1638637db639e0ade3258b51db49a9a137574c3e # v6.5.1
uses: anchore/scan-action@f6601287cdb1efc985d6b765bbf99cb4c0ac29d8 # v7.0.0
with:
sbom: "sbom-${{ inputs.image }}.json"
only-fixed: true
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ jobs:
echo "GOCACHE=${{ github.workspace }}/.gocache" >> $GITHUB_ENV

- name: Create/Update Draft
uses: lucacome/draft-release@00f74370c044c322da6cb52acc707d62c7762c71 # v1.2.4
uses: lucacome/draft-release@fd099feb33710d1fa27b915a08a7acd6a1fb7fd2 # v2.0.0
with:
minor-label: "enhancement"
major-label: "change"
Expand All @@ -199,16 +199,16 @@ jobs:

- name: Download Syft
if: ${{ inputs.is_production_release }}
uses: anchore/sbom-action/download-syft@da167eac915b4e86f08b264dbdbc867b61be6f0c # v0.20.5
uses: anchore/sbom-action/download-syft@f8bdd1d8ac5e901a77a92f111440fdb1b593736b # v0.20.6

- name: Install Cosign
if: ${{ inputs.is_production_release }}
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0

- name: Build binary
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
with:
version: v2.12.0 # renovate: datasource=github-tags depName=goreleaser/goreleaser
version: v2.12.1 # renovate: datasource=github-tags depName=goreleaser/goreleaser
args: ${{ (inputs.is_production_release && (inputs.dry_run == false || inputs.dry_run == null)) && 'release' || 'build --snapshot' }} --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:
- name: Build binary
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
with:
version: v2.12.0 # renovate: datasource=github-tags depName=goreleaser/goreleaser
version: v2.12.1 # renovate: datasource=github-tags depName=goreleaser/goreleaser
args: build --single-target --snapshot --clean
env:
TELEMETRY_ENDPOINT: "" # disables sending telemetry
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/functional.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
- name: Build binary
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
with:
version: v2.12.0 # renovate: datasource=github-tags depName=goreleaser/goreleaser
version: v2.12.1 # renovate: datasource=github-tags depName=goreleaser/goreleaser
args: build --single-target --snapshot --clean
env:
TELEMETRY_ENDPOINT: otel-collector-opentelemetry-collector.collector.svc.cluster.local:4317
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:

- name: Get Release Notes
id: notes
uses: lucacome/draft-release@00f74370c044c322da6cb52acc707d62c7762c71 # v1.2.4
uses: lucacome/draft-release@fd099feb33710d1fa27b915a08a7acd6a1fb7fd2 # v2.0.0
with:
config-path: .github/release-notes.yml
dry-run: true
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The following table lists the software versions NGINX Gateway Fabric supports.

| NGINX Gateway Fabric | Gateway API | Kubernetes | NGINX OSS | NGINX Plus | NGINX Agent |
|----------------------|-------------|------------|-----------|------------|-------------|
| Edge | 1.3.0 | 1.25+ | 1.29.1 | R35 | v3.3.0 |
| Edge | 1.3.0 | 1.25+ | 1.29.1 | R35 | v3.3.1 |
| 2.1.1 | 1.3.0 | 1.25+ | 1.29.1 | R35 | v3.2.1 |
| 2.1.0 | 1.3.0 | 1.25+ | 1.29.1 | R35 | v3.2.1 |
| 2.0.2 | 1.3.0 | 1.25+ | 1.28.0 | R34 | v3.0.1 |
Expand Down
2 changes: 1 addition & 1 deletion build/Dockerfile.nginx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ADD --link --chown=101:1001 https://cs.nginx.com/static/keys/nginx_signing.rsa.p
FROM nginx:1.29.1-alpine-otel

# renovate: datasource=github-tags depName=nginx/agent
ARG NGINX_AGENT_VERSION=v3.3.0
ARG NGINX_AGENT_VERSION=v3.3.1
ARG NJS_DIR
ARG NGINX_CONF_DIR
ARG BUILD_AGENT
Expand Down
2 changes: 1 addition & 1 deletion build/Dockerfile.nginxplus
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ FROM alpine:3.22

ARG NGINX_PLUS_VERSION=R35
# renovate: datasource=github-tags depName=nginx/agent
ARG NGINX_AGENT_VERSION=v3.3.0
ARG NGINX_AGENT_VERSION=v3.3.1
ARG NJS_DIR
ARG NGINX_CONF_DIR
ARG BUILD_AGENT
Expand Down
3 changes: 2 additions & 1 deletion charts/nginx-gateway-fabric/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri
| `certGenerator.ttlSecondsAfterFinished` | How long to wait after the cert generator job has finished before it is removed by the job controller. | int | `30` |
| `clusterDomain` | The DNS cluster domain of your Kubernetes cluster. | string | `"cluster.local"` |
| `gateways` | A list of Gateway objects. View https://gateway-api.sigs.k8s.io/reference/spec/#gateway for full Gateway reference. | list | `[]` |
| `nginx` | The nginx section contains the configuration for all NGINX data plane deployments installed by the NGINX Gateway Fabric control plane. | object | `{"autoscaling":{"enable":false},"config":{},"container":{"hostPorts":[],"lifecycle":{},"readinessProbe":{},"resources":{},"volumeMounts":[]},"debug":false,"image":{"pullPolicy":"Always","repository":"ghcr.io/nginx/nginx-gateway-fabric/nginx","tag":"edge"},"imagePullSecret":"","imagePullSecrets":[],"kind":"deployment","nginxOneConsole":{"dataplaneKeySecretName":"","endpointHost":"agent.connect.nginx.com","endpointPort":443,"skipVerify":false},"patches":[],"plus":false,"pod":{},"replicas":1,"service":{"externalTrafficPolicy":"Local","loadBalancerClass":"","loadBalancerIP":"","loadBalancerSourceRanges":[],"nodePorts":[],"patches":[],"type":"LoadBalancer"},"usage":{"caSecretName":"","clientSSLSecretName":"","endpoint":"","resolver":"","secretName":"nplus-license","skipVerify":false}}` |
| `nginx` | The nginx section contains the configuration for all NGINX data plane deployments installed by the NGINX Gateway Fabric control plane. | object | `{"autoscaling":{"enable":false},"config":{},"container":{"hostPorts":[],"lifecycle":{},"readinessProbe":{},"resources":{},"volumeMounts":[]},"debug":false,"image":{"pullPolicy":"Always","repository":"ghcr.io/nginx/nginx-gateway-fabric/nginx","tag":"edge"},"imagePullSecret":"","imagePullSecrets":[],"kind":"deployment","nginxOneConsole":{"dataplaneKeySecretName":"","endpointHost":"agent.connect.nginx.com","endpointPort":443,"skipVerify":false},"patches":[],"plus":false,"pod":{},"replicas":1,"service":{"externalTrafficPolicy":"Local","loadBalancerClass":"","loadBalancerIP":"","loadBalancerSourceRanges":[],"nodePorts":[],"patches":[],"type":"LoadBalancer"},"usage":{"caSecretName":"","clientSSLSecretName":"","endpoint":"","enforceInitialReport":true,"resolver":"","secretName":"nplus-license","skipVerify":false}}` |
| `nginx.autoscaling` | Autoscaling configuration for the NGINX data plane. | object | `{"enable":false}` |
| `nginx.autoscaling.enable` | Enable or disable Horizontal Pod Autoscaler for the NGINX data plane. | bool | `false` |
| `nginx.config` | The configuration for the data plane that is contained in the NginxProxy resource. This is applied globally to all Gateways managed by this instance of NGINX Gateway Fabric. | object | `{}` |
Expand Down Expand Up @@ -241,6 +241,7 @@ The following table lists the configurable parameters of the NGINX Gateway Fabri
| `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 | `""` |
| `nginx.usage.clientSSLSecretName` | The name of the Secret containing the client certificate and key for authenticating with NGINX Instance Manager. Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway). | string | `""` |
| `nginx.usage.endpoint` | The endpoint of the NGINX Plus usage reporting server. Default: product.connect.nginx.com | string | `""` |
| `nginx.usage.enforceInitialReport` | Enable enforcement of the initial NGINX Plus licensing report. If set to false, the initial report is not enforced. | bool | `true` |
| `nginx.usage.resolver` | The nameserver used to resolve the NGINX Plus usage reporting endpoint. Used with NGINX Instance Manager. | string | `""` |
| `nginx.usage.secretName` | The name of the Secret containing the JWT for NGINX Plus usage reporting. Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway). | string | `"nplus-license"` |
| `nginx.usage.skipVerify` | Disable client verification of the NGINX Plus usage reporting server certificate. | bool | `false` |
Expand Down
3 changes: 3 additions & 0 deletions charts/nginx-gateway-fabric/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ spec:
{{- if .Values.nginx.usage.clientSSLSecretName }}
- --usage-report-client-ssl-secret={{ .Values.nginx.usage.clientSSLSecretName }}
{{- end }}
{{- if hasKey .Values.nginx.usage "enforceInitialReport" }}
- --usage-report-enforce-initial-report={{ .Values.nginx.usage.enforceInitialReport }}
{{- end }}
{{- end }}
{{- if .Values.nginxGateway.metrics.enable }}
- --metrics-port={{ .Values.nginxGateway.metrics.port }}
Expand Down
7 changes: 7 additions & 0 deletions charts/nginx-gateway-fabric/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,13 @@
"title": "endpoint",
"type": "string"
},
"enforceInitialReport": {
"default": true,
"description": "Enable enforcement of the initial NGINX Plus licensing report. If set to false, the initial report is not enforced.",
"required": [],
"title": "enforceInitialReport",
"type": "boolean"
},
"resolver": {
"default": "",
"description": "The nameserver used to resolve the NGINX Plus usage reporting endpoint. Used with NGINX Instance Manager.",
Expand Down
3 changes: 3 additions & 0 deletions charts/nginx-gateway-fabric/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,9 @@ nginx:
# Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway).
clientSSLSecretName: ""

# -- Enable enforcement of the initial NGINX Plus licensing report. If set to false, the initial report is not enforced.
enforceInitialReport: true

# @schema
# type: object
# properties:
Expand Down
137 changes: 83 additions & 54 deletions cmd/gateway/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ const (
nginxOneTelemetryEndpointHost = "agent.connect.nginx.com"
)

// usageReportParams holds the parameters for building the usage report configuration for PLUS.
type usageReportParams struct {
SecretName stringValidatingValue
ClientSSLSecretName stringValidatingValue
CASecretName stringValidatingValue
Endpoint stringValidatingValue
Resolver stringValidatingValue
SkipVerify bool
EnforceInitialReport bool
}

func createRootCommand() *cobra.Command {
rootCmd := &cobra.Command{
Use: "gateway",
Expand All @@ -58,31 +69,32 @@ func createRootCommand() *cobra.Command {
func createControllerCommand() *cobra.Command {
// flag names
const (
configFlag = "config"
serviceFlag = "service"
agentTLSSecretFlag = "agent-tls-secret"
nginxOneDataplaneKeySecretFlag = "nginx-one-dataplane-key-secret" //nolint:gosec // not credentials
nginxOneTelemetryEndpointHostFlag = "nginx-one-telemetry-endpoint-host"
nginxOneTelemetryEndpointPortFlag = "nginx-one-telemetry-endpoint-port"
nginxOneTLSSkipVerifyFlag = "nginx-one-tls-skip-verify"
metricsDisableFlag = "metrics-disable"
metricsSecureFlag = "metrics-secure-serving"
metricsPortFlag = "metrics-port"
healthDisableFlag = "health-disable"
healthPortFlag = "health-port"
leaderElectionDisableFlag = "leader-election-disable"
leaderElectionLockNameFlag = "leader-election-lock-name"
productTelemetryDisableFlag = "product-telemetry-disable"
gwAPIExperimentalFlag = "gateway-api-experimental-features"
nginxDockerSecretFlag = "nginx-docker-secret" //nolint:gosec // not credentials
usageReportSecretFlag = "usage-report-secret"
usageReportEndpointFlag = "usage-report-endpoint"
usageReportResolverFlag = "usage-report-resolver"
usageReportSkipVerifyFlag = "usage-report-skip-verify"
usageReportClientSSLSecretFlag = "usage-report-client-ssl-secret" //nolint:gosec // not credentials
usageReportCASecretFlag = "usage-report-ca-secret" //nolint:gosec // not credentials
snippetsFiltersFlag = "snippets-filters"
nginxSCCFlag = "nginx-scc"
configFlag = "config"
serviceFlag = "service"
agentTLSSecretFlag = "agent-tls-secret"
nginxOneDataplaneKeySecretFlag = "nginx-one-dataplane-key-secret" //nolint:gosec // not credentials
nginxOneTelemetryEndpointHostFlag = "nginx-one-telemetry-endpoint-host"
nginxOneTelemetryEndpointPortFlag = "nginx-one-telemetry-endpoint-port"
nginxOneTLSSkipVerifyFlag = "nginx-one-tls-skip-verify"
metricsDisableFlag = "metrics-disable"
metricsSecureFlag = "metrics-secure-serving"
metricsPortFlag = "metrics-port"
healthDisableFlag = "health-disable"
healthPortFlag = "health-port"
leaderElectionDisableFlag = "leader-election-disable"
leaderElectionLockNameFlag = "leader-election-lock-name"
productTelemetryDisableFlag = "product-telemetry-disable"
gwAPIExperimentalFlag = "gateway-api-experimental-features"
nginxDockerSecretFlag = "nginx-docker-secret" //nolint:gosec // not credentials
usageReportSecretFlag = "usage-report-secret"
usageReportEndpointFlag = "usage-report-endpoint"
usageReportResolverFlag = "usage-report-resolver"
usageReportSkipVerifyFlag = "usage-report-skip-verify"
usageReportClientSSLSecretFlag = "usage-report-client-ssl-secret" //nolint:gosec // not credentials
usageReportCASecretFlag = "usage-report-ca-secret" //nolint:gosec // not credentials
usageReportEnforceInitialReportFlag = "usage-report-enforce-initial-report"
snippetsFiltersFlag = "snippets-filters"
nginxSCCFlag = "nginx-scc"
)

// flag values
Expand Down Expand Up @@ -148,24 +160,26 @@ func createControllerCommand() *cobra.Command {
nginxDockerSecrets = stringSliceValidatingValue{
validator: validateResourceName,
}
usageReportSkipVerify bool
usageReportSecretName = stringValidatingValue{
)

usageReportParams := usageReportParams{
SecretName: stringValidatingValue{
validator: validateResourceName,
value: "nplus-license",
}
usageReportEndpoint = stringValidatingValue{
},
Endpoint: stringValidatingValue{
validator: validateEndpointOptionalPort,
}
usageReportResolver = stringValidatingValue{
},
Resolver: stringValidatingValue{
validator: validateEndpointOptionalPort,
}
usageReportClientSSLSecretName = stringValidatingValue{
},
ClientSSLSecretName: stringValidatingValue{
validator: validateResourceName,
}
usageReportCASecretName = stringValidatingValue{
},
CASecretName: stringValidatingValue{
validator: validateResourceName,
}
)
},
}

cmd := &cobra.Command{
Use: "controller",
Expand Down Expand Up @@ -212,18 +226,10 @@ func createControllerCommand() *cobra.Command {
}

var usageReportConfig config.UsageReportConfig
if plus && usageReportSecretName.value == "" {
return errors.New("usage-report-secret is required when using NGINX Plus")
}

if plus {
usageReportConfig = config.UsageReportConfig{
SecretName: usageReportSecretName.value,
ClientSSLSecretName: usageReportClientSSLSecretName.value,
CASecretName: usageReportCASecretName.value,
Endpoint: usageReportEndpoint.value,
Resolver: usageReportResolver.value,
SkipVerify: usageReportSkipVerify,
usageReportConfig, err = buildUsageReportConfig(usageReportParams)
if err != nil {
return err
}
}

Expand Down Expand Up @@ -432,47 +438,54 @@ func createControllerCommand() *cobra.Command {
)

cmd.Flags().Var(
&usageReportSecretName,
&usageReportParams.SecretName,
usageReportSecretFlag,
"The name of the Secret containing the JWT for NGINX Plus usage reporting. Must exist in the same namespace "+
"that the NGINX Gateway Fabric control plane is running in (default namespace: nginx-gateway).",
)

cmd.Flags().Var(
&usageReportEndpoint,
&usageReportParams.Endpoint,
usageReportEndpointFlag,
"The endpoint of the NGINX Plus usage reporting server.",
)

cmd.Flags().Var(
&usageReportResolver,
&usageReportParams.Resolver,
usageReportResolverFlag,
"The nameserver used to resolve the NGINX Plus usage reporting endpoint. Used with NGINX Instance Manager.",
)

cmd.Flags().BoolVar(
&usageReportSkipVerify,
&usageReportParams.SkipVerify,
usageReportSkipVerifyFlag,
false,
"Disable client verification of the NGINX Plus usage reporting server certificate.",
)

cmd.Flags().Var(
&usageReportClientSSLSecretName,
&usageReportParams.ClientSSLSecretName,
usageReportClientSSLSecretFlag,
"The name of the Secret containing the client certificate and key for authenticating with NGINX Instance Manager. "+
"Must exist in the same namespace that the NGINX Gateway Fabric control plane is running in "+
"(default namespace: nginx-gateway).",
)

cmd.Flags().Var(
&usageReportCASecretName,
&usageReportParams.CASecretName,
usageReportCASecretFlag,
"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).",
)

cmd.Flags().BoolVar(
&usageReportParams.EnforceInitialReport,
usageReportEnforceInitialReportFlag,
true,
"Enable enforcement of the initial NGINX Plus licensing report. If set to false, the initial report is not enforced.",
)

cmd.Flags().BoolVar(
&snippetsFilters,
snippetsFiltersFlag,
Expand All @@ -491,6 +504,22 @@ func createControllerCommand() *cobra.Command {
return cmd
}

func buildUsageReportConfig(params usageReportParams) (config.UsageReportConfig, error) {
if params.SecretName.value == "" {
return config.UsageReportConfig{}, errors.New("usage-report-secret is required when using NGINX Plus")
}

return config.UsageReportConfig{
SecretName: params.SecretName.value,
ClientSSLSecretName: params.ClientSSLSecretName.value,
CASecretName: params.CASecretName.value,
Endpoint: params.Endpoint.value,
Resolver: params.Resolver.value,
SkipVerify: params.SkipVerify,
EnforceInitialReport: params.EnforceInitialReport,
}, nil
}

func createGenerateCertsCommand() *cobra.Command {
// flag names
const (
Expand Down
Loading
Loading