From 910c5af5e9258ad62bb4e233523654852c7877ed Mon Sep 17 00:00:00 2001 From: Tina Usova Date: Fri, 12 Sep 2025 15:26:34 +0100 Subject: [PATCH 1/5] Add EnforceInitialReport variable everywhere --- charts/nginx-gateway-fabric/README.md | 3 +- .../templates/_helpers.tpl | 11 +++ .../templates/deployment.yaml | 3 + .../nginx-gateway-fabric/values.schema.json | 7 ++ charts/nginx-gateway-fabric/values.yaml | 3 + cmd/gateway/commands.go | 72 +++++++++++-------- cmd/gateway/commands_test.go | 1 + internal/controller/config/config.go | 2 + .../controller/nginx/config/main_config.go | 24 ++++--- internal/controller/provisioner/objects.go | 1 + .../controller/provisioner/objects_test.go | 11 +-- internal/controller/provisioner/templates.go | 4 ++ 12 files changed, 94 insertions(+), 48 deletions(-) diff --git a/charts/nginx-gateway-fabric/README.md b/charts/nginx-gateway-fabric/README.md index 4f2541107c..7fd4b771f8 100644 --- a/charts/nginx-gateway-fabric/README.md +++ b/charts/nginx-gateway-fabric/README.md @@ -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":false,"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 | `{}` | @@ -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 | `false` | | `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` | diff --git a/charts/nginx-gateway-fabric/templates/_helpers.tpl b/charts/nginx-gateway-fabric/templates/_helpers.tpl index a1d5b686f5..e05e7e674a 100644 --- a/charts/nginx-gateway-fabric/templates/_helpers.tpl +++ b/charts/nginx-gateway-fabric/templates/_helpers.tpl @@ -110,3 +110,14 @@ Filters out empty fields from a struct. {{- $result | toYaml -}} {{- end -}} {{- end }} + +{{/* +Enforcing the initial NGINX Plus licensing report. +*/}} +{{- define "nginx-gateway.enforceInitialReport" -}} +{{- if .Values.Usage.enforceInitialReport }} +enforce_initial_report on; +{{- else }} +enforce_initial_report off; +{{- end }} +{{- end }} diff --git a/charts/nginx-gateway-fabric/templates/deployment.yaml b/charts/nginx-gateway-fabric/templates/deployment.yaml index 9be1b13f16..27ff7ab9d6 100644 --- a/charts/nginx-gateway-fabric/templates/deployment.yaml +++ b/charts/nginx-gateway-fabric/templates/deployment.yaml @@ -72,6 +72,9 @@ spec: {{- if .Values.nginx.usage.clientSSLSecretName }} - --usage-report-client-ssl-secret={{ .Values.nginx.usage.clientSSLSecretName }} {{- end }} + {{- if .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 }} diff --git a/charts/nginx-gateway-fabric/values.schema.json b/charts/nginx-gateway-fabric/values.schema.json index ca5d339d44..435b3d2330 100644 --- a/charts/nginx-gateway-fabric/values.schema.json +++ b/charts/nginx-gateway-fabric/values.schema.json @@ -692,6 +692,13 @@ "title": "endpoint", "type": "string" }, + "enforceInitialReport": { + "default": false, + "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.", diff --git a/charts/nginx-gateway-fabric/values.yaml b/charts/nginx-gateway-fabric/values.yaml index 044e0f2d37..528a766aa9 100644 --- a/charts/nginx-gateway-fabric/values.yaml +++ b/charts/nginx-gateway-fabric/values.yaml @@ -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: false + # @schema # type: object # properties: diff --git a/cmd/gateway/commands.go b/cmd/gateway/commands.go index 9f83cbcfb3..6d44d1b505 100644 --- a/cmd/gateway/commands.go +++ b/cmd/gateway/commands.go @@ -58,31 +58,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 + snippetsFiltersFlag = "snippets-filters" + nginxSCCFlag = "nginx-scc" + usageReportEnforceInitialReportFlag = "usage-report-enforce-initial-report" ) // flag values @@ -165,6 +166,7 @@ func createControllerCommand() *cobra.Command { usageReportCASecretName = stringValidatingValue{ validator: validateResourceName, } + usageReportEnforceInitialReport bool ) cmd := &cobra.Command{ @@ -218,12 +220,13 @@ func createControllerCommand() *cobra.Command { if plus { usageReportConfig = config.UsageReportConfig{ - SecretName: usageReportSecretName.value, - ClientSSLSecretName: usageReportClientSSLSecretName.value, - CASecretName: usageReportCASecretName.value, - Endpoint: usageReportEndpoint.value, - Resolver: usageReportResolver.value, - SkipVerify: usageReportSkipVerify, + SecretName: usageReportSecretName.value, + ClientSSLSecretName: usageReportClientSSLSecretName.value, + CASecretName: usageReportCASecretName.value, + Endpoint: usageReportEndpoint.value, + Resolver: usageReportResolver.value, + SkipVerify: usageReportSkipVerify, + EnforceInitialReport: usageReportEnforceInitialReport, } } @@ -488,6 +491,13 @@ func createControllerCommand() *cobra.Command { ` Only applicable in OpenShift.`, ) + cmd.Flags().BoolVar( + &usageReportEnforceInitialReport, + usageReportEnforceInitialReportFlag, + false, + "Enable enforcement of the initial NGINX Plus licensing report. If set to false, the initial report is not enforced.", + ) + return cmd } diff --git a/cmd/gateway/commands_test.go b/cmd/gateway/commands_test.go index 0ecd4111d9..037e91bbcc 100644 --- a/cmd/gateway/commands_test.go +++ b/cmd/gateway/commands_test.go @@ -154,6 +154,7 @@ func TestControllerCmdFlagValidation(t *testing.T) { "--usage-report-resolver=resolver.com", "--usage-report-ca-secret=ca-secret", "--usage-report-client-ssl-secret=client-secret", + "--usage-report-enforce-initial-report=true", "--snippets-filters", "--nginx-scc=nginx-sscc-name", "--nginx-one-dataplane-key-secret=dataplane-key-secret", diff --git a/internal/controller/config/config.go b/internal/controller/config/config.go index ff6744b101..bf75ec0181 100644 --- a/internal/controller/config/config.go +++ b/internal/controller/config/config.go @@ -125,6 +125,8 @@ type UsageReportConfig struct { Resolver string // SkipVerify controls whether the nginx verifies the server certificate. SkipVerify bool + // Enabled is the flag for toggling usage reporting on or off. + EnforceInitialReport bool } // Flags contains the NGF command-line flag names and values. diff --git a/internal/controller/nginx/config/main_config.go b/internal/controller/nginx/config/main_config.go index 1fb7991225..bd58eabee7 100644 --- a/internal/controller/nginx/config/main_config.go +++ b/internal/controller/nginx/config/main_config.go @@ -55,13 +55,14 @@ func executeEventsConfig(conf dataplane.Configuration) []executeResult { } type mgmtConf struct { - Endpoint string - Resolver string - LicenseTokenFile string - CACertFile string - ClientSSLCertFile string - ClientSSLKeyFile string - SkipVerify bool + Endpoint string + Resolver string + LicenseTokenFile string + CACertFile string + ClientSSLCertFile string + ClientSSLKeyFile string + SkipVerify bool + EnforceInitialReport bool } // generateMgmtFiles generates the NGINX Plus configuration file for the mgmt block. As part of this, @@ -88,10 +89,11 @@ func (g GeneratorImpl) generateMgmtFiles(conf dataplane.Configuration) []agent.F files := []agent.File{tokenFile} cfg := mgmtConf{ - Endpoint: g.usageReportConfig.Endpoint, - Resolver: g.usageReportConfig.Resolver, - LicenseTokenFile: tokenFile.Meta.Name, - SkipVerify: g.usageReportConfig.SkipVerify, + Endpoint: g.usageReportConfig.Endpoint, + Resolver: g.usageReportConfig.Resolver, + LicenseTokenFile: tokenFile.Meta.Name, + SkipVerify: g.usageReportConfig.SkipVerify, + EnforceInitialReport: g.usageReportConfig.EnforceInitialReport, } if content, ok := conf.AuxiliarySecrets[graph.PlusReportCACertificate]; ok { diff --git a/internal/controller/provisioner/objects.go b/internal/controller/provisioner/objects.go index 9ed081c219..2b880293b0 100644 --- a/internal/controller/provisioner/objects.go +++ b/internal/controller/provisioner/objects.go @@ -435,6 +435,7 @@ func (p *NginxProvisioner) buildNginxConfigMaps( "SkipVerify": p.cfg.PlusUsageConfig.SkipVerify, "UsageCASecret": caSecret, "UsageClientSSLSecret": clientSSLSecret, + "EnforceInitialReport": p.cfg.PlusUsageConfig.EnforceInitialReport, } bootstrapCM.Data["mgmt.conf"] = string(helpers.MustExecuteTemplate(mgmtTemplate, mgmtFields)) diff --git a/internal/controller/provisioner/objects_test.go b/internal/controller/provisioner/objects_test.go index e72d1057c5..e9ce9960d0 100644 --- a/internal/controller/provisioner/objects_test.go +++ b/internal/controller/provisioner/objects_test.go @@ -502,11 +502,12 @@ func TestBuildNginxResourceObjects_Plus(t *testing.T) { }, Plus: true, PlusUsageConfig: &config.UsageReportConfig{ - SecretName: jwtTestSecretName, - CASecretName: caTestSecretName, - ClientSSLSecretName: clientTestSecretName, - Endpoint: "test.com", - SkipVerify: true, + SecretName: jwtTestSecretName, + CASecretName: caTestSecretName, + ClientSSLSecretName: clientTestSecretName, + Endpoint: "test.com", + SkipVerify: true, + EnforceInitialReport: true, }, AgentTLSSecretName: agentTLSTestSecretName, }, diff --git a/internal/controller/provisioner/templates.go b/internal/controller/provisioner/templates.go index d52700ad2f..b2c377cbd9 100644 --- a/internal/controller/provisioner/templates.go +++ b/internal/controller/provisioner/templates.go @@ -29,7 +29,11 @@ const mgmtTemplateText = `mgmt { ssl_certificate /etc/nginx/certs-bootstrap/tls.crt; ssl_certificate_key /etc/nginx/certs-bootstrap/tls.key; {{- end }} + {{- if .EnforceInitialReport }} + enforce_initial_report on; + {{- else }} enforce_initial_report off; + {{- end }} deployment_context /etc/nginx/main-includes/deployment_ctx.json; }` From 3f643791653b287df6732aec95727b8b0541dd28 Mon Sep 17 00:00:00 2001 From: Tina Usova Date: Tue, 16 Sep 2025 11:32:08 +0100 Subject: [PATCH 2/5] fix review comments --- charts/nginx-gateway-fabric/README.md | 4 ++-- charts/nginx-gateway-fabric/templates/_helpers.tpl | 11 ----------- charts/nginx-gateway-fabric/values.schema.json | 2 +- charts/nginx-gateway-fabric/values.yaml | 2 +- cmd/gateway/commands.go | 4 ++-- cmd/gateway/commands_test.go | 2 +- deploy/experimental-nginx-plus/deploy.yaml | 1 + deploy/nginx-plus/deploy.yaml | 1 + deploy/snippets-filters-nginx-plus/deploy.yaml | 1 + internal/controller/config/config.go | 2 +- .../controller/nginx/config/main_config_template.go | 5 +++++ internal/controller/provisioner/objects_test.go | 3 ++- internal/controller/provisioner/templates.go | 4 ---- 13 files changed, 18 insertions(+), 24 deletions(-) diff --git a/charts/nginx-gateway-fabric/README.md b/charts/nginx-gateway-fabric/README.md index 7fd4b771f8..eb7f3ce114 100644 --- a/charts/nginx-gateway-fabric/README.md +++ b/charts/nginx-gateway-fabric/README.md @@ -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":"","enforceInitialReport":false,"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 | `{}` | @@ -241,7 +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 | `false` | +| `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` | diff --git a/charts/nginx-gateway-fabric/templates/_helpers.tpl b/charts/nginx-gateway-fabric/templates/_helpers.tpl index e05e7e674a..a1d5b686f5 100644 --- a/charts/nginx-gateway-fabric/templates/_helpers.tpl +++ b/charts/nginx-gateway-fabric/templates/_helpers.tpl @@ -110,14 +110,3 @@ Filters out empty fields from a struct. {{- $result | toYaml -}} {{- end -}} {{- end }} - -{{/* -Enforcing the initial NGINX Plus licensing report. -*/}} -{{- define "nginx-gateway.enforceInitialReport" -}} -{{- if .Values.Usage.enforceInitialReport }} -enforce_initial_report on; -{{- else }} -enforce_initial_report off; -{{- end }} -{{- end }} diff --git a/charts/nginx-gateway-fabric/values.schema.json b/charts/nginx-gateway-fabric/values.schema.json index 435b3d2330..9f44991db3 100644 --- a/charts/nginx-gateway-fabric/values.schema.json +++ b/charts/nginx-gateway-fabric/values.schema.json @@ -693,7 +693,7 @@ "type": "string" }, "enforceInitialReport": { - "default": false, + "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", diff --git a/charts/nginx-gateway-fabric/values.yaml b/charts/nginx-gateway-fabric/values.yaml index 528a766aa9..52f1e03e55 100644 --- a/charts/nginx-gateway-fabric/values.yaml +++ b/charts/nginx-gateway-fabric/values.yaml @@ -338,7 +338,7 @@ nginx: clientSSLSecretName: "" # -- Enable enforcement of the initial NGINX Plus licensing report. If set to false, the initial report is not enforced. - enforceInitialReport: false + enforceInitialReport: true # @schema # type: object diff --git a/cmd/gateway/commands.go b/cmd/gateway/commands.go index 6d44d1b505..eeb1e96778 100644 --- a/cmd/gateway/commands.go +++ b/cmd/gateway/commands.go @@ -81,9 +81,9 @@ func createControllerCommand() *cobra.Command { 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" - usageReportEnforceInitialReportFlag = "usage-report-enforce-initial-report" ) // flag values @@ -494,7 +494,7 @@ func createControllerCommand() *cobra.Command { cmd.Flags().BoolVar( &usageReportEnforceInitialReport, usageReportEnforceInitialReportFlag, - false, + true, "Enable enforcement of the initial NGINX Plus licensing report. If set to false, the initial report is not enforced.", ) diff --git a/cmd/gateway/commands_test.go b/cmd/gateway/commands_test.go index 037e91bbcc..5f0bb72bf6 100644 --- a/cmd/gateway/commands_test.go +++ b/cmd/gateway/commands_test.go @@ -154,7 +154,7 @@ func TestControllerCmdFlagValidation(t *testing.T) { "--usage-report-resolver=resolver.com", "--usage-report-ca-secret=ca-secret", "--usage-report-client-ssl-secret=client-secret", - "--usage-report-enforce-initial-report=true", + "--usage-report-enforce-initial-report", "--snippets-filters", "--nginx-scc=nginx-sscc-name", "--nginx-one-dataplane-key-secret=dataplane-key-secret", diff --git a/deploy/experimental-nginx-plus/deploy.yaml b/deploy/experimental-nginx-plus/deploy.yaml index 5b478afd22..c11cbc662d 100644 --- a/deploy/experimental-nginx-plus/deploy.yaml +++ b/deploy/experimental-nginx-plus/deploy.yaml @@ -271,6 +271,7 @@ spec: - --nginx-docker-secret=nginx-plus-registry-secret - --nginx-plus - --usage-report-secret=nplus-license + - --usage-report-enforce-initial-report=true - --metrics-port=9113 - --health-port=8081 - --leader-election-lock-name=nginx-gateway-leader-election diff --git a/deploy/nginx-plus/deploy.yaml b/deploy/nginx-plus/deploy.yaml index c82a24e0e9..70f8f34c49 100644 --- a/deploy/nginx-plus/deploy.yaml +++ b/deploy/nginx-plus/deploy.yaml @@ -267,6 +267,7 @@ spec: - --nginx-docker-secret=nginx-plus-registry-secret - --nginx-plus - --usage-report-secret=nplus-license + - --usage-report-enforce-initial-report=true - --metrics-port=9113 - --health-port=8081 - --leader-election-lock-name=nginx-gateway-leader-election diff --git a/deploy/snippets-filters-nginx-plus/deploy.yaml b/deploy/snippets-filters-nginx-plus/deploy.yaml index 79b8a2bf0f..ed0dccb81f 100644 --- a/deploy/snippets-filters-nginx-plus/deploy.yaml +++ b/deploy/snippets-filters-nginx-plus/deploy.yaml @@ -269,6 +269,7 @@ spec: - --nginx-docker-secret=nginx-plus-registry-secret - --nginx-plus - --usage-report-secret=nplus-license + - --usage-report-enforce-initial-report=true - --metrics-port=9113 - --health-port=8081 - --leader-election-lock-name=nginx-gateway-leader-election diff --git a/internal/controller/config/config.go b/internal/controller/config/config.go index bf75ec0181..ca13a204e7 100644 --- a/internal/controller/config/config.go +++ b/internal/controller/config/config.go @@ -125,7 +125,7 @@ type UsageReportConfig struct { Resolver string // SkipVerify controls whether the nginx verifies the server certificate. SkipVerify bool - // Enabled is the flag for toggling usage reporting on or off. + // EnforceInitialReport is the flag for toggling usage reporting on or off. EnforceInitialReport bool } diff --git a/internal/controller/nginx/config/main_config_template.go b/internal/controller/nginx/config/main_config_template.go index ae668431a8..a3ebc10d81 100644 --- a/internal/controller/nginx/config/main_config_template.go +++ b/internal/controller/nginx/config/main_config_template.go @@ -37,5 +37,10 @@ mgmt { ssl_certificate {{ .ClientSSLCertFile }}; ssl_certificate_key {{ .ClientSSLKeyFile }}; {{- end }} + {{- if .EnforceInitialReport }} + enforce_initial_report on; + {{- else }} + enforce_initial_report off; + {{- end }} } ` diff --git a/internal/controller/provisioner/objects_test.go b/internal/controller/provisioner/objects_test.go index e9ce9960d0..c63f3c06fa 100644 --- a/internal/controller/provisioner/objects_test.go +++ b/internal/controller/provisioner/objects_test.go @@ -507,7 +507,7 @@ func TestBuildNginxResourceObjects_Plus(t *testing.T) { ClientSSLSecretName: clientTestSecretName, Endpoint: "test.com", SkipVerify: true, - EnforceInitialReport: true, + EnforceInitialReport: false, }, AgentTLSSecretName: agentTLSTestSecretName, }, @@ -588,6 +588,7 @@ func TestBuildNginxResourceObjects_Plus(t *testing.T) { g.Expect(cm.Data["mgmt.conf"]).To(ContainSubstring("ssl_trusted_certificate")) g.Expect(cm.Data["mgmt.conf"]).To(ContainSubstring("ssl_certificate")) g.Expect(cm.Data["mgmt.conf"]).To(ContainSubstring("ssl_certificate_key")) + g.Expect(cm.Data["mgmt.conf"]).To(ContainSubstring("enforce_initial_report off")) cmObj = objects[5] cm, ok = cmObj.(*corev1.ConfigMap) diff --git a/internal/controller/provisioner/templates.go b/internal/controller/provisioner/templates.go index b2c377cbd9..d52700ad2f 100644 --- a/internal/controller/provisioner/templates.go +++ b/internal/controller/provisioner/templates.go @@ -29,11 +29,7 @@ const mgmtTemplateText = `mgmt { ssl_certificate /etc/nginx/certs-bootstrap/tls.crt; ssl_certificate_key /etc/nginx/certs-bootstrap/tls.key; {{- end }} - {{- if .EnforceInitialReport }} - enforce_initial_report on; - {{- else }} enforce_initial_report off; - {{- end }} deployment_context /etc/nginx/main-includes/deployment_ctx.json; }` From db7223ef85f4294dfcd436e077f8e9f6d72b1e8e Mon Sep 17 00:00:00 2001 From: Tina Usova Date: Tue, 16 Sep 2025 19:26:04 +0100 Subject: [PATCH 3/5] Fix helm flag verification and add tests for Plus configuration --- .../templates/deployment.yaml | 2 +- cmd/gateway/commands.go | 102 +++++++++++------- cmd/gateway/commands_test.go | 86 +++++++++++++++ 3 files changed, 148 insertions(+), 42 deletions(-) diff --git a/charts/nginx-gateway-fabric/templates/deployment.yaml b/charts/nginx-gateway-fabric/templates/deployment.yaml index 27ff7ab9d6..5bc292bdb4 100644 --- a/charts/nginx-gateway-fabric/templates/deployment.yaml +++ b/charts/nginx-gateway-fabric/templates/deployment.yaml @@ -72,7 +72,7 @@ spec: {{- if .Values.nginx.usage.clientSSLSecretName }} - --usage-report-client-ssl-secret={{ .Values.nginx.usage.clientSSLSecretName }} {{- end }} - {{- if .Values.nginx.usage.enforceInitialReport }} + {{- if hasKey .Values.nginx.usage "enforceInitialReport" }} - --usage-report-enforce-initial-report={{ .Values.nginx.usage.enforceInitialReport }} {{- end }} {{- end }} diff --git a/cmd/gateway/commands.go b/cmd/gateway/commands.go index eeb1e96778..6229e831c4 100644 --- a/cmd/gateway/commands.go +++ b/cmd/gateway/commands.go @@ -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", @@ -149,25 +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, - } - usageReportEnforceInitialReport bool - ) + }, + } cmd := &cobra.Command{ Use: "controller", @@ -213,21 +225,9 @@ func createControllerCommand() *cobra.Command { return fmt.Errorf("error parsing telemetry endpoint insecure: %w", err) } - 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, - EnforceInitialReport: usageReportEnforceInitialReport, - } + usageReportConfig, urcErr := buildUsageReportConfig(plus, usageReportParams) + if urcErr != nil { + return urcErr } flagKeys, flagValues := parseFlags(cmd.Flags()) @@ -435,33 +435,33 @@ 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 "+ @@ -469,13 +469,20 @@ func createControllerCommand() *cobra.Command { ) 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, @@ -491,16 +498,29 @@ func createControllerCommand() *cobra.Command { ` Only applicable in OpenShift.`, ) - cmd.Flags().BoolVar( - &usageReportEnforceInitialReport, - usageReportEnforceInitialReportFlag, - true, - "Enable enforcement of the initial NGINX Plus licensing report. If set to false, the initial report is not enforced.", - ) - return cmd } +func buildUsageReportConfig(plus bool, params UsageReportParams) (config.UsageReportConfig, error) { + if plus && params.SecretName.value == "" { + return config.UsageReportConfig{}, errors.New("usage-report-secret is required when using NGINX Plus") + } + + if 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 + } + + return config.UsageReportConfig{}, nil +} + func createGenerateCertsCommand() *cobra.Command { // flag names const ( diff --git a/cmd/gateway/commands_test.go b/cmd/gateway/commands_test.go index 5f0bb72bf6..d924b1fbfa 100644 --- a/cmd/gateway/commands_test.go +++ b/cmd/gateway/commands_test.go @@ -855,3 +855,89 @@ func TestCreateGatewayPodConfig(t *testing.T) { g.Expect(err).To(MatchError(errors.New("environment variable POD_UID not set"))) g.Expect(cfg).To(Equal(config.GatewayPodConfig{})) } + +func TestUsageReportConfig(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + params UsageReportParams + expected config.UsageReportConfig + plus bool + expectError bool + }{ + { + name: "NGINX Plus enabled with all valid parameters", + plus: true, + params: UsageReportParams{ + SecretName: stringValidatingValue{value: "test-secret"}, + ClientSSLSecretName: stringValidatingValue{value: "client-ssl-secret"}, + CASecretName: stringValidatingValue{value: "ca-secret"}, + Endpoint: stringValidatingValue{value: "example.com"}, + Resolver: stringValidatingValue{value: "resolver.com"}, + SkipVerify: true, + EnforceInitialReport: false, + }, + expectError: false, + expected: config.UsageReportConfig{ + SecretName: "test-secret", + ClientSSLSecretName: "client-ssl-secret", + CASecretName: "ca-secret", + Endpoint: "example.com", + Resolver: "resolver.com", + SkipVerify: true, + EnforceInitialReport: false, + }, + }, + { + name: "NGINX Plus enabled with missing secret", + plus: true, + params: UsageReportParams{ + SecretName: stringValidatingValue{value: ""}, + ClientSSLSecretName: stringValidatingValue{value: "client-ssl-secret"}, + CASecretName: stringValidatingValue{value: "ca-secret"}, + Endpoint: stringValidatingValue{value: "example.com"}, + Resolver: stringValidatingValue{value: "resolver.com"}, + SkipVerify: true, + EnforceInitialReport: false, + }, + expectError: true, + }, + { + name: "NGINX Plus disabled", + plus: false, + params: UsageReportParams{ + SecretName: stringValidatingValue{value: "test-secret"}, + ClientSSLSecretName: stringValidatingValue{value: "client-ssl-secret"}, + CASecretName: stringValidatingValue{value: "ca-secret"}, + Endpoint: stringValidatingValue{value: "example.com"}, + Resolver: stringValidatingValue{value: "resolver.com"}, + SkipVerify: true, + EnforceInitialReport: false, + }, + expectError: false, + expected: config.UsageReportConfig{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + result, err := buildUsageReportConfig(tc.plus, tc.params) + + if tc.expectError { + if err == nil { + t.Errorf("expected an error but got none") + } + } else { + if err != nil { + t.Errorf("did not expect an error but got: %v", err) + } + + if result != tc.expected { + t.Errorf("expected result %+v, but got %+v", tc.expected, result) + } + } + }) + } +} From be6b05d1581bd3eb3be0b5e57b182981da7ef119 Mon Sep 17 00:00:00 2001 From: Tina Usova Date: Wed, 17 Sep 2025 09:38:32 +0100 Subject: [PATCH 4/5] Move if logic out of methid and leave only OFF setting in template --- cmd/gateway/commands.go | 41 +++++++++---------- cmd/gateway/commands_test.go | 25 ++--------- .../nginx/config/main_config_template.go | 4 +- internal/controller/provisioner/objects.go | 1 - .../controller/provisioner/objects_test.go | 11 +++-- 5 files changed, 30 insertions(+), 52 deletions(-) diff --git a/cmd/gateway/commands.go b/cmd/gateway/commands.go index 6229e831c4..f334d499a7 100644 --- a/cmd/gateway/commands.go +++ b/cmd/gateway/commands.go @@ -42,8 +42,8 @@ const ( nginxOneTelemetryEndpointHost = "agent.connect.nginx.com" ) -// UsageReportParams holds the parameters for building the usage report configuration for PLUS. -type UsageReportParams struct { +// usageReportParams holds the parameters for building the usage report configuration for PLUS. +type usageReportParams struct { SecretName stringValidatingValue ClientSSLSecretName stringValidatingValue CASecretName stringValidatingValue @@ -162,7 +162,7 @@ func createControllerCommand() *cobra.Command { } ) - usageReportParams := UsageReportParams{ + usageReportParams := usageReportParams{ SecretName: stringValidatingValue{ validator: validateResourceName, value: "nplus-license", @@ -225,9 +225,12 @@ func createControllerCommand() *cobra.Command { return fmt.Errorf("error parsing telemetry endpoint insecure: %w", err) } - usageReportConfig, urcErr := buildUsageReportConfig(plus, usageReportParams) - if urcErr != nil { - return urcErr + var usageReportConfig config.UsageReportConfig + if plus { + usageReportConfig, err = buildUsageReportConfig(usageReportParams) + if err != nil { + return err + } } flagKeys, flagValues := parseFlags(cmd.Flags()) @@ -501,24 +504,20 @@ func createControllerCommand() *cobra.Command { return cmd } -func buildUsageReportConfig(plus bool, params UsageReportParams) (config.UsageReportConfig, error) { - if plus && params.SecretName.value == "" { +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") } - if 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 - } - - return config.UsageReportConfig{}, nil + 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 { diff --git a/cmd/gateway/commands_test.go b/cmd/gateway/commands_test.go index d924b1fbfa..4cb8f0d532 100644 --- a/cmd/gateway/commands_test.go +++ b/cmd/gateway/commands_test.go @@ -861,15 +861,13 @@ func TestUsageReportConfig(t *testing.T) { testCases := []struct { name string - params UsageReportParams + params usageReportParams expected config.UsageReportConfig - plus bool expectError bool }{ { name: "NGINX Plus enabled with all valid parameters", - plus: true, - params: UsageReportParams{ + params: usageReportParams{ SecretName: stringValidatingValue{value: "test-secret"}, ClientSSLSecretName: stringValidatingValue{value: "client-ssl-secret"}, CASecretName: stringValidatingValue{value: "ca-secret"}, @@ -891,8 +889,7 @@ func TestUsageReportConfig(t *testing.T) { }, { name: "NGINX Plus enabled with missing secret", - plus: true, - params: UsageReportParams{ + params: usageReportParams{ SecretName: stringValidatingValue{value: ""}, ClientSSLSecretName: stringValidatingValue{value: "client-ssl-secret"}, CASecretName: stringValidatingValue{value: "ca-secret"}, @@ -902,20 +899,6 @@ func TestUsageReportConfig(t *testing.T) { EnforceInitialReport: false, }, expectError: true, - }, - { - name: "NGINX Plus disabled", - plus: false, - params: UsageReportParams{ - SecretName: stringValidatingValue{value: "test-secret"}, - ClientSSLSecretName: stringValidatingValue{value: "client-ssl-secret"}, - CASecretName: stringValidatingValue{value: "ca-secret"}, - Endpoint: stringValidatingValue{value: "example.com"}, - Resolver: stringValidatingValue{value: "resolver.com"}, - SkipVerify: true, - EnforceInitialReport: false, - }, - expectError: false, expected: config.UsageReportConfig{}, }, } @@ -923,7 +906,7 @@ func TestUsageReportConfig(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Parallel() - result, err := buildUsageReportConfig(tc.plus, tc.params) + result, err := buildUsageReportConfig(tc.params) if tc.expectError { if err == nil { diff --git a/internal/controller/nginx/config/main_config_template.go b/internal/controller/nginx/config/main_config_template.go index a3ebc10d81..21f6a28abd 100644 --- a/internal/controller/nginx/config/main_config_template.go +++ b/internal/controller/nginx/config/main_config_template.go @@ -37,9 +37,7 @@ mgmt { ssl_certificate {{ .ClientSSLCertFile }}; ssl_certificate_key {{ .ClientSSLKeyFile }}; {{- end }} - {{- if .EnforceInitialReport }} - enforce_initial_report on; - {{- else }} + {{- if not .EnforceInitialReport }} enforce_initial_report off; {{- end }} } diff --git a/internal/controller/provisioner/objects.go b/internal/controller/provisioner/objects.go index 2b880293b0..9ed081c219 100644 --- a/internal/controller/provisioner/objects.go +++ b/internal/controller/provisioner/objects.go @@ -435,7 +435,6 @@ func (p *NginxProvisioner) buildNginxConfigMaps( "SkipVerify": p.cfg.PlusUsageConfig.SkipVerify, "UsageCASecret": caSecret, "UsageClientSSLSecret": clientSSLSecret, - "EnforceInitialReport": p.cfg.PlusUsageConfig.EnforceInitialReport, } bootstrapCM.Data["mgmt.conf"] = string(helpers.MustExecuteTemplate(mgmtTemplate, mgmtFields)) diff --git a/internal/controller/provisioner/objects_test.go b/internal/controller/provisioner/objects_test.go index c63f3c06fa..d4b580f54e 100644 --- a/internal/controller/provisioner/objects_test.go +++ b/internal/controller/provisioner/objects_test.go @@ -502,12 +502,11 @@ func TestBuildNginxResourceObjects_Plus(t *testing.T) { }, Plus: true, PlusUsageConfig: &config.UsageReportConfig{ - SecretName: jwtTestSecretName, - CASecretName: caTestSecretName, - ClientSSLSecretName: clientTestSecretName, - Endpoint: "test.com", - SkipVerify: true, - EnforceInitialReport: false, + SecretName: jwtTestSecretName, + CASecretName: caTestSecretName, + ClientSSLSecretName: clientTestSecretName, + Endpoint: "test.com", + SkipVerify: true, }, AgentTLSSecretName: agentTLSTestSecretName, }, From dd95cfa175d2eeb906475d5b27869179becd47c5 Mon Sep 17 00:00:00 2001 From: Tina Usova Date: Wed, 17 Sep 2025 11:20:52 +0100 Subject: [PATCH 5/5] Fix description in config file --- internal/controller/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/controller/config/config.go b/internal/controller/config/config.go index ca13a204e7..e23f73ca59 100644 --- a/internal/controller/config/config.go +++ b/internal/controller/config/config.go @@ -125,7 +125,7 @@ type UsageReportConfig struct { Resolver string // SkipVerify controls whether the nginx verifies the server certificate. SkipVerify bool - // EnforceInitialReport is the flag for toggling usage reporting on or off. + // EnforceInitialReport controls whether the initial NGINX Plus licensing report is enforced. EnforceInitialReport bool }