From 31cf91ca37dd4a330cf1facdbce6614daf216676 Mon Sep 17 00:00:00 2001 From: bjee19 <139261241+bjee19@users.noreply.github.com> Date: Tue, 12 Aug 2025 15:46:44 -0700 Subject: [PATCH 1/4] (Cherry-pick) Fix NFR tests (#3722) (#3723) Cherry-pick #3722 --- tests/framework/ngf.go | 2 +- tests/framework/timeout.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/framework/ngf.go b/tests/framework/ngf.go index 87252bc325..8bff1a4194 100644 --- a/tests/framework/ngf.go +++ b/tests/framework/ngf.go @@ -134,7 +134,7 @@ func UpgradeNGF(cfg InstallationConfig, extraArgs ...string) ([]byte, error) { crdPath := filepath.Join(cfg.ChartPath, "crds") + "/" cmd := exec.CommandContext( context.Background(), - "kubectl", "apply", "--server-side", "-f", crdPath, + "kubectl", "apply", "--server-side", "--force-conflicts", "-f", crdPath, ) output, err := cmd.CombinedOutput() if err != nil { diff --git a/tests/framework/timeout.go b/tests/framework/timeout.go index 87abe87189..394f9e351d 100644 --- a/tests/framework/timeout.go +++ b/tests/framework/timeout.go @@ -46,7 +46,7 @@ func DefaultTimeoutConfig() TimeoutConfig { CreateTimeout: 60 * time.Second, UpdateTimeout: 60 * time.Second, DeleteTimeout: 10 * time.Second, - DeleteNamespaceTimeout: 90 * time.Second, + DeleteNamespaceTimeout: 150 * time.Second, GetTimeout: 10 * time.Second, ManifestFetchTimeout: 10 * time.Second, RequestTimeout: 10 * time.Second, From b6f8fcff5cdded45ac312d04ff07f323020a09b2 Mon Sep 17 00:00:00 2001 From: Saloni Choudhary <146118978+salonichf5@users.noreply.github.com> Date: Thu, 14 Aug 2025 02:38:37 +0530 Subject: [PATCH 2/4] Cherry-pick: Update NGINX Plus version to R35 (#3729) Cherry-pick: update NGINX Plus version to R35 --- README.md | 2 +- build/Dockerfile.nginxplus | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 72f853cac1..31ba187260 100644 --- a/README.md +++ b/README.md @@ -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.0 | R34 | v3.2.0 | +| Edge | 1.3.0 | 1.25+ | 1.29.0 | R35 | v3.2.0 | | 2.0.2 | 1.3.0 | 1.25+ | 1.28.0 | R34 | v3.0.1 | | 2.0.1 | 1.3.0 | 1.25+ | 1.28.0 | R34 | v3.0.1 | | 2.0.0 | 1.3.0 | 1.25+ | 1.28.0 | R34 | v3.0.0 | diff --git a/build/Dockerfile.nginxplus b/build/Dockerfile.nginxplus index 70effd1624..14642ad801 100644 --- a/build/Dockerfile.nginxplus +++ b/build/Dockerfile.nginxplus @@ -4,9 +4,9 @@ FROM scratch AS nginx-files # the following links can be replaced with local files if needed, i.e. ADD --chown=101:1001 ADD --link --chown=101:1001 https://cs.nginx.com/static/keys/nginx_signing.rsa.pub nginx_signing.rsa.pub -FROM alpine:3.21 +FROM alpine:3.22 -ARG NGINX_PLUS_VERSION=R34 +ARG NGINX_PLUS_VERSION=R35 # renovate: datasource=github-tags depName=nginx/agent ARG NGINX_AGENT_VERSION=v3.2.0 ARG NJS_DIR From f8bbfdd957a90f1dcd751fe6972a851ee9887445 Mon Sep 17 00:00:00 2001 From: Saloni Choudhary <146118978+salonichf5@users.noreply.github.com> Date: Thu, 14 Aug 2025 05:23:32 +0530 Subject: [PATCH 3/4] Cherry pick: Add nginx one console telemetry field (#3731) Add nginx one console connection telemetry field (#3717) Problem: We want to know how many clusters are connected to NGINX One console. Solution: Reports product telemetry to report if cluster is connected to NGINX One console --- internal/controller/manager.go | 5 +++-- internal/controller/telemetry/collector.go | 9 +++++++-- internal/controller/telemetry/collector_test.go | 17 ++++++++++------- internal/controller/telemetry/data.avdl | 3 +++ .../telemetry/data_attributes_generated.go | 1 + internal/controller/telemetry/data_test.go | 3 +++ tests/suite/telemetry_test.go | 1 + 7 files changed, 28 insertions(+), 11 deletions(-) diff --git a/internal/controller/manager.go b/internal/controller/manager.go index 999f22d9ca..a4e9fd9cf0 100644 --- a/internal/controller/manager.go +++ b/internal/controller/manager.go @@ -289,8 +289,9 @@ func StartManager(cfg config.Config) error { Namespace: cfg.GatewayPodConfig.Namespace, Name: cfg.GatewayPodConfig.Name, }, - ImageSource: cfg.ImageSource, - Flags: cfg.Flags, + ImageSource: cfg.ImageSource, + Flags: cfg.Flags, + NginxOneConsoleConnection: cfg.NginxOneConsoleTelemetryConfig.DataplaneKeySecretName != "", }) job, err := createTelemetryJob(cfg, dataCollector, healthChecker.getReadyCh()) diff --git a/internal/controller/telemetry/collector.go b/internal/controller/telemetry/collector.go index 2ea076f792..e06da3f0b8 100644 --- a/internal/controller/telemetry/collector.go +++ b/internal/controller/telemetry/collector.go @@ -64,6 +64,8 @@ type Data struct { NginxPodCount int64 // ControlPlanePodCount is the total number of NGF control plane Pods. ControlPlanePodCount int64 + // NginxOneConnectionEnabled is a boolean that indicates whether the connection to the Nginx One Console is enabled. + NginxOneConnectionEnabled bool } // NGFResourceCounts stores the counts of all relevant resources that NGF processes and generates configuration from. @@ -113,14 +115,16 @@ type DataCollectorConfig struct { GraphGetter GraphGetter // ConfigurationGetter allows us to get the Configuration. ConfigurationGetter ConfigurationGetter - // Version is the NGF version. - Version string // PodNSName is the NamespacedName of the NGF Pod. PodNSName types.NamespacedName + // Version is the NGF version. + Version string // ImageSource is the source of the NGF image. ImageSource string // Flags contains the command-line NGF flag keys and values. Flags config.Flags + // NginxOneConsoleConnection is a boolean that indicates whether the connection to the Nginx One Console is enabled. + NginxOneConsoleConnection bool } // DataCollectorImpl is am implementation of DataCollector. @@ -189,6 +193,7 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { SnippetsFiltersDirectivesCount: snippetsFiltersDirectivesCount, NginxPodCount: nginxPodCount, ControlPlanePodCount: int64(replicaCount), + NginxOneConnectionEnabled: c.cfg.NginxOneConsoleConnection, } return data, nil diff --git a/internal/controller/telemetry/collector_test.go b/internal/controller/telemetry/collector_test.go index ea90045032..8c749fdfbe 100644 --- a/internal/controller/telemetry/collector_test.go +++ b/internal/controller/telemetry/collector_test.go @@ -176,6 +176,7 @@ var _ = Describe("Collector", Ordered, func() { FlagValues: flags.Values, SnippetsFiltersDirectives: []string{}, SnippetsFiltersDirectivesCount: []int64{}, + NginxOneConnectionEnabled: true, } k8sClientReader = &kubernetesfakes.FakeReader{} @@ -186,13 +187,14 @@ var _ = Describe("Collector", Ordered, func() { fakeConfigurationGetter.GetLatestConfigurationReturns(nil) dataCollector = telemetry.NewDataCollectorImpl(telemetry.DataCollectorConfig{ - K8sClientReader: k8sClientReader, - GraphGetter: fakeGraphGetter, - ConfigurationGetter: fakeConfigurationGetter, - Version: version, - PodNSName: podNSName, - ImageSource: "local", - Flags: flags, + K8sClientReader: k8sClientReader, + GraphGetter: fakeGraphGetter, + ConfigurationGetter: fakeConfigurationGetter, + Version: version, + PodNSName: podNSName, + ImageSource: "local", + Flags: flags, + NginxOneConsoleConnection: true, }) baseGetCalls = createGetCallsFunc(ngfPod, ngfReplicaSet, kubeNamespace) @@ -516,6 +518,7 @@ var _ = Describe("Collector", Ordered, func() { // empty + one gateway using daemonset expData.NginxPodCount = int64(8) expData.ControlPlanePodCount = int64(2) + expData.NginxOneConnectionEnabled = true data, err := dataCollector.Collect(ctx) Expect(err).ToNot(HaveOccurred()) diff --git a/internal/controller/telemetry/data.avdl b/internal/controller/telemetry/data.avdl index 95d99f316b..c19881315a 100644 --- a/internal/controller/telemetry/data.avdl +++ b/internal/controller/telemetry/data.avdl @@ -111,5 +111,8 @@ attached at the Gateway level. */ /** ControlPlanePodCount is the total number of NGF control plane Pods. */ long? ControlPlanePodCount = null; + /** NginxOneConnectionEnabled is a boolean that indicates whether the connection to the Nginx One Console is enabled. */ + boolean? NginxOneConnectionEnabled = null; + } } diff --git a/internal/controller/telemetry/data_attributes_generated.go b/internal/controller/telemetry/data_attributes_generated.go index afbd8dfb1f..3b8b3dcf3f 100644 --- a/internal/controller/telemetry/data_attributes_generated.go +++ b/internal/controller/telemetry/data_attributes_generated.go @@ -22,6 +22,7 @@ func (d *Data) Attributes() []attribute.KeyValue { attrs = append(attrs, d.NGFResourceCounts.Attributes()...) attrs = append(attrs, attribute.Int64("NginxPodCount", d.NginxPodCount)) attrs = append(attrs, attribute.Int64("ControlPlanePodCount", d.ControlPlanePodCount)) + attrs = append(attrs, attribute.Bool("NginxOneConnectionEnabled", d.NginxOneConnectionEnabled)) return attrs } diff --git a/internal/controller/telemetry/data_test.go b/internal/controller/telemetry/data_test.go index 867424e145..49c8e3543c 100644 --- a/internal/controller/telemetry/data_test.go +++ b/internal/controller/telemetry/data_test.go @@ -46,6 +46,7 @@ func TestDataAttributes(t *testing.T) { SnippetsFiltersDirectivesCount: []int64{3, 2, 1}, NginxPodCount: 3, ControlPlanePodCount: 3, + NginxOneConnectionEnabled: true, } expected := []attribute.KeyValue{ @@ -84,6 +85,7 @@ func TestDataAttributes(t *testing.T) { attribute.Int64("GatewayAttachedNpCount", 15), attribute.Int64("NginxPodCount", 3), attribute.Int64("ControlPlanePodCount", 3), + attribute.Bool("NginxOneConnectionEnabled", true), } result := data.Attributes() @@ -129,6 +131,7 @@ func TestDataAttributesWithEmptyData(t *testing.T) { attribute.Int64("GatewayAttachedNpCount", 0), attribute.Int64("NginxPodCount", 0), attribute.Int64("ControlPlanePodCount", 0), + attribute.Bool("NginxOneConnectionEnabled", false), } result := data.Attributes() diff --git a/tests/suite/telemetry_test.go b/tests/suite/telemetry_test.go index a4d5f502ca..2ad0c0b3a0 100644 --- a/tests/suite/telemetry_test.go +++ b/tests/suite/telemetry_test.go @@ -95,6 +95,7 @@ var _ = Describe("Telemetry test with OTel collector", Label("telemetry"), func( "GatewayAttachedNpCount: Int(0)", "NginxPodCount: Int(0)", "ControlPlanePodCount: Int(1)", + "NginxOneConnectionEnabled: Bool(false)", }, ) }) From 89e085d9cc5316cd3146ee2b97876a7d1391fc06 Mon Sep 17 00:00:00 2001 From: Sarthak Agrawal <68310924+sarthyparty@users.noreply.github.com> Date: Wed, 13 Aug 2025 17:37:53 -0700 Subject: [PATCH 4/4] Fix events block crash (#3730) --- .../controller/nginx/conf/nginx-plus.conf | 4 ++ internal/controller/nginx/conf/nginx.conf | 4 ++ internal/controller/nginx/config/generator.go | 7 +++ .../controller/nginx/config/generator_test.go | 55 ++++++++++--------- .../controller/nginx/config/main_config.go | 16 +++++- .../nginx/config/main_config_template.go | 7 ++- .../nginx/config/main_config_test.go | 38 ++++++++++++- internal/controller/provisioner/objects.go | 13 ++++- .../controller/provisioner/objects_test.go | 6 +- internal/controller/provisioner/templates.go | 14 ++--- 10 files changed, 122 insertions(+), 42 deletions(-) diff --git a/internal/controller/nginx/conf/nginx-plus.conf b/internal/controller/nginx/conf/nginx-plus.conf index 84be2a6691..f2b0ec0dc8 100644 --- a/internal/controller/nginx/conf/nginx-plus.conf +++ b/internal/controller/nginx/conf/nginx-plus.conf @@ -5,6 +5,10 @@ worker_processes auto; pid /var/run/nginx/nginx.pid; +events { + include /etc/nginx/events-includes/*.conf; +} + http { include /etc/nginx/conf.d/*.conf; include /etc/nginx/mime.types; diff --git a/internal/controller/nginx/conf/nginx.conf b/internal/controller/nginx/conf/nginx.conf index f98d7eaa6e..791994fdf8 100644 --- a/internal/controller/nginx/conf/nginx.conf +++ b/internal/controller/nginx/conf/nginx.conf @@ -5,6 +5,10 @@ worker_processes auto; pid /var/run/nginx/nginx.pid; +events { + include /etc/nginx/events-includes/*.conf; +} + http { include /etc/nginx/conf.d/*.conf; include /etc/nginx/mime.types; diff --git a/internal/controller/nginx/config/generator.go b/internal/controller/nginx/config/generator.go index 290185c315..6fa7602c04 100644 --- a/internal/controller/nginx/config/generator.go +++ b/internal/controller/nginx/config/generator.go @@ -38,6 +38,9 @@ const ( // For example, these files include load_module directives and snippets that target the main context. mainIncludesFolder = configFolder + "/main-includes" + // eventsIncludesFolder is the folder where NGINX events context configuration files are stored. + eventsIncludesFolder = configFolder + "/events-includes" + // secretsFolder is the folder where secrets (like TLS certs/keys) are stored. secretsFolder = configFolder + "/secrets" @@ -56,6 +59,9 @@ const ( // mainIncludesConfigFile is the path to the file containing NGINX configuration in the main context. mainIncludesConfigFile = mainIncludesFolder + "/main.conf" + // eventsIncludesConfigFile is the path to the file containing NGINX events configuration. + eventsIncludesConfigFile = eventsIncludesFolder + "/events.conf" + // mgmtIncludesFile is the path to the file containing the NGINX Plus mgmt config. mgmtIncludesFile = mainIncludesFolder + "/mgmt.conf" @@ -196,6 +202,7 @@ func (g GeneratorImpl) getExecuteFuncs( ) []executeFunc { return []executeFunc{ executeMainConfig, + executeEventsConfig, executeBaseHTTPConfig, g.newExecuteServersFunc(generator, keepAliveCheck), newExecuteUpstreamsFunc(upstreams), diff --git a/internal/controller/nginx/config/generator_test.go b/internal/controller/nginx/config/generator_test.go index 1340834d03..c77b22cb99 100644 --- a/internal/controller/nginx/config/generator_test.go +++ b/internal/controller/nginx/config/generator_test.go @@ -147,7 +147,7 @@ func TestGenerate(t *testing.T) { files := generator.Generate(conf) - g.Expect(files).To(HaveLen(17)) + g.Expect(files).To(HaveLen(18)) arrange := func(i, j int) bool { return files[i].Meta.Name < files[j].Meta.Name } @@ -158,6 +158,7 @@ func TestGenerate(t *testing.T) { /etc/nginx/conf.d/http.conf /etc/nginx/conf.d/matches.json /etc/nginx/conf.d/plus-api.conf + /etc/nginx/events-includes/events.conf /etc/nginx/includes/http_snippet1.conf /etc/nginx/includes/http_snippet2.conf /etc/nginx/includes/main_snippet1.conf @@ -211,28 +212,32 @@ func TestGenerate(t *testing.T) { g.Expect(httpCfg).To(ContainSubstring("deny all;")) g.Expect(httpCfg).To(ContainSubstring("location = /dashboard.html {}")) + // events config file + g.Expect(files[3].Meta.Name).To(Equal("/etc/nginx/events-includes/events.conf")) + g.Expect(string(files[3].Contents)).To(ContainSubstring("worker_connections")) + // snippet include files // content is not checked in this test. - g.Expect(files[3].Meta.Name).To(Equal("/etc/nginx/includes/http_snippet1.conf")) - g.Expect(files[4].Meta.Name).To(Equal("/etc/nginx/includes/http_snippet2.conf")) - g.Expect(files[5].Meta.Name).To(Equal("/etc/nginx/includes/main_snippet1.conf")) - g.Expect(files[6].Meta.Name).To(Equal("/etc/nginx/includes/main_snippet2.conf")) + g.Expect(files[4].Meta.Name).To(Equal("/etc/nginx/includes/http_snippet1.conf")) + g.Expect(files[5].Meta.Name).To(Equal("/etc/nginx/includes/http_snippet2.conf")) + g.Expect(files[6].Meta.Name).To(Equal("/etc/nginx/includes/main_snippet1.conf")) + g.Expect(files[7].Meta.Name).To(Equal("/etc/nginx/includes/main_snippet2.conf")) - g.Expect(files[7].Meta.Name).To(Equal("/etc/nginx/main-includes/deployment_ctx.json")) - deploymentCtx := string(files[7].Contents) + g.Expect(files[8].Meta.Name).To(Equal("/etc/nginx/main-includes/deployment_ctx.json")) + deploymentCtx := string(files[8].Contents) g.Expect(deploymentCtx).To(ContainSubstring("\"integration\":\"ngf\"")) g.Expect(deploymentCtx).To(ContainSubstring("\"cluster_id\":\"test-uid\"")) g.Expect(deploymentCtx).To(ContainSubstring("\"installation_id\":\"test-uid-replicaSet\"")) g.Expect(deploymentCtx).To(ContainSubstring("\"cluster_node_count\":1")) - g.Expect(files[8].Meta.Name).To(Equal("/etc/nginx/main-includes/main.conf")) - mainConfStr := string(files[8].Contents) + g.Expect(files[9].Meta.Name).To(Equal("/etc/nginx/main-includes/main.conf")) + mainConfStr := string(files[9].Contents) g.Expect(mainConfStr).To(ContainSubstring("load_module modules/ngx_otel_module.so;")) g.Expect(mainConfStr).To(ContainSubstring("include /etc/nginx/includes/main_snippet1.conf;")) g.Expect(mainConfStr).To(ContainSubstring("include /etc/nginx/includes/main_snippet2.conf;")) - g.Expect(files[9].Meta.Name).To(Equal("/etc/nginx/main-includes/mgmt.conf")) - mgmtConf := string(files[9].Contents) + g.Expect(files[10].Meta.Name).To(Equal("/etc/nginx/main-includes/mgmt.conf")) + mgmtConf := string(files[10].Contents) g.Expect(mgmtConf).To(ContainSubstring("usage_report endpoint=test-endpoint")) g.Expect(mgmtConf).To(ContainSubstring("license_token /etc/nginx/secrets/license.jwt")) g.Expect(mgmtConf).To(ContainSubstring("deployment_context /etc/nginx/main-includes/deployment_ctx.json")) @@ -240,23 +245,23 @@ func TestGenerate(t *testing.T) { g.Expect(mgmtConf).To(ContainSubstring("ssl_certificate /etc/nginx/secrets/mgmt-tls.crt")) g.Expect(mgmtConf).To(ContainSubstring("ssl_certificate_key /etc/nginx/secrets/mgmt-tls.key")) - g.Expect(files[10].Meta.Name).To(Equal("/etc/nginx/secrets/license.jwt")) - g.Expect(string(files[10].Contents)).To(Equal("license")) + g.Expect(files[11].Meta.Name).To(Equal("/etc/nginx/secrets/license.jwt")) + g.Expect(string(files[11].Contents)).To(Equal("license")) - g.Expect(files[11].Meta.Name).To(Equal("/etc/nginx/secrets/mgmt-ca.crt")) - g.Expect(string(files[11].Contents)).To(Equal("ca")) + g.Expect(files[12].Meta.Name).To(Equal("/etc/nginx/secrets/mgmt-ca.crt")) + g.Expect(string(files[12].Contents)).To(Equal("ca")) - g.Expect(files[12].Meta.Name).To(Equal("/etc/nginx/secrets/mgmt-tls.crt")) - g.Expect(string(files[12].Contents)).To(Equal("cert")) + g.Expect(files[13].Meta.Name).To(Equal("/etc/nginx/secrets/mgmt-tls.crt")) + g.Expect(string(files[13].Contents)).To(Equal("cert")) - g.Expect(files[13].Meta.Name).To(Equal("/etc/nginx/secrets/mgmt-tls.key")) - g.Expect(string(files[13].Contents)).To(Equal("key")) + g.Expect(files[14].Meta.Name).To(Equal("/etc/nginx/secrets/mgmt-tls.key")) + g.Expect(string(files[14].Contents)).To(Equal("key")) - g.Expect(files[14].Meta.Name).To(Equal("/etc/nginx/secrets/test-certbundle.crt")) - certBundle := string(files[14].Contents) + g.Expect(files[15].Meta.Name).To(Equal("/etc/nginx/secrets/test-certbundle.crt")) + certBundle := string(files[15].Contents) g.Expect(certBundle).To(Equal("test-cert")) - g.Expect(files[15]).To(Equal(agent.File{ + g.Expect(files[16]).To(Equal(agent.File{ Meta: &pb.FileMeta{ Name: "/etc/nginx/secrets/test-keypair.pem", Hash: filesHelper.GenerateHash([]byte("test-cert\ntest-key")), @@ -266,9 +271,9 @@ func TestGenerate(t *testing.T) { Contents: []byte("test-cert\ntest-key"), })) - g.Expect(files[16].Meta.Name).To(Equal("/etc/nginx/stream-conf.d/stream.conf")) - g.Expect(files[16].Meta.Permissions).To(Equal(file.RegularFileMode)) - streamCfg := string(files[16].Contents) + g.Expect(files[17].Meta.Name).To(Equal("/etc/nginx/stream-conf.d/stream.conf")) + g.Expect(files[17].Meta.Permissions).To(Equal(file.RegularFileMode)) + streamCfg := string(files[17].Contents) g.Expect(streamCfg).To(ContainSubstring("listen unix:/var/run/nginx/app.example.com-443.sock")) g.Expect(streamCfg).To(ContainSubstring("listen 443")) g.Expect(streamCfg).To(ContainSubstring("app.example.com unix:/var/run/nginx/app.example.com-443.sock")) diff --git a/internal/controller/nginx/config/main_config.go b/internal/controller/nginx/config/main_config.go index fa10606f22..1fb7991225 100644 --- a/internal/controller/nginx/config/main_config.go +++ b/internal/controller/nginx/config/main_config.go @@ -15,8 +15,9 @@ import ( ) var ( - mainConfigTemplate = gotemplate.Must(gotemplate.New("main").Parse(mainConfigTemplateText)) - mgmtConfigTemplate = gotemplate.Must(gotemplate.New("mgmt").Parse(mgmtConfigTemplateText)) + mainConfigTemplate = gotemplate.Must(gotemplate.New("main").Parse(mainConfigTemplateText)) + mgmtConfigTemplate = gotemplate.Must(gotemplate.New("mgmt").Parse(mgmtConfigTemplateText)) + eventsConfigTemplate = gotemplate.Must(gotemplate.New("events").Parse(eventsConfigTemplateText)) ) type mainConfig struct { @@ -42,6 +43,17 @@ func executeMainConfig(conf dataplane.Configuration) []executeResult { return results } +func executeEventsConfig(conf dataplane.Configuration) []executeResult { + eventsData := helpers.MustExecuteTemplate(eventsConfigTemplate, conf) + + return []executeResult{ + { + dest: eventsIncludesConfigFile, + data: eventsData, + }, + } +} + type mgmtConf struct { Endpoint string Resolver string diff --git a/internal/controller/nginx/config/main_config_template.go b/internal/controller/nginx/config/main_config_template.go index 103aa3fc14..ae668431a8 100644 --- a/internal/controller/nginx/config/main_config_template.go +++ b/internal/controller/nginx/config/main_config_template.go @@ -7,15 +7,16 @@ load_module modules/ngx_otel_module.so; error_log stderr {{ .Conf.Logging.ErrorLevel }}; -events { - worker_connections {{ .Conf.WorkerConnections }}; -} {{ range $i := .Includes -}} include {{ $i.Name }}; {{ end -}} ` +const eventsConfigTemplateText = ` +worker_connections {{ .WorkerConnections }}; +` + const mgmtConfigTemplateText = ` mgmt { {{- if .Endpoint }} diff --git a/internal/controller/nginx/config/main_config_test.go b/internal/controller/nginx/config/main_config_test.go index dc8861da15..132084afa7 100644 --- a/internal/controller/nginx/config/main_config_test.go +++ b/internal/controller/nginx/config/main_config_test.go @@ -173,8 +173,44 @@ func TestExecuteMainConfig_WorkerConnections(t *testing.T) { res := executeMainConfig(test.conf) g.Expect(res).To(HaveLen(1)) g.Expect(res[0].dest).To(Equal(mainIncludesConfigFile)) + g.Expect(string(res[0].data)).To(ContainSubstring("error_log stderr")) + }) + } +} + +func TestExecuteEventsConfig_WorkerConnections(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + expWorkerConnections string + conf dataplane.Configuration + }{ + { + name: "custom worker connections", + conf: dataplane.Configuration{ + WorkerConnections: 2048, + }, + expWorkerConnections: "worker_connections 2048;", + }, + { + name: "default worker connections", + conf: dataplane.Configuration{ + WorkerConnections: dataplane.DefaultWorkerConnections, + }, + expWorkerConnections: "worker_connections 1024;", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + g := NewWithT(t) + + res := executeEventsConfig(test.conf) + g.Expect(res).To(HaveLen(1)) + g.Expect(res[0].dest).To(Equal(eventsIncludesConfigFile)) g.Expect(string(res[0].data)).To(ContainSubstring(test.expWorkerConnections)) - g.Expect(string(res[0].data)).To(ContainSubstring("events {")) }) } } diff --git a/internal/controller/provisioner/objects.go b/internal/controller/provisioner/objects.go index 86908a7dc1..6abe6f230c 100644 --- a/internal/controller/provisioner/objects.go +++ b/internal/controller/provisioner/objects.go @@ -396,6 +396,11 @@ func (p *NginxProvisioner) buildNginxConfigMaps( "WorkerConnections": workerConnections, } + // Create events ConfigMap data using template + eventsFields := map[string]interface{}{ + "WorkerConnections": workerConnections, + } + bootstrapCM := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: ngxIncludesConfigMapName, @@ -404,7 +409,8 @@ func (p *NginxProvisioner) buildNginxConfigMaps( Annotations: objectMeta.Annotations, }, Data: map[string]string{ - "main.conf": string(helpers.MustExecuteTemplate(mainTemplate, mainFields)), + "main.conf": string(helpers.MustExecuteTemplate(mainTemplate, mainFields)), + "events.conf": string(helpers.MustExecuteTemplate(eventsTemplate, eventsFields)), }, } @@ -826,6 +832,7 @@ func (p *NginxProvisioner) buildNginxPodTemplateSpec( {MountPath: "/etc/nginx/conf.d", Name: "nginx-conf"}, {MountPath: "/etc/nginx/stream-conf.d", Name: "nginx-stream-conf"}, {MountPath: "/etc/nginx/main-includes", Name: "nginx-main-includes"}, + {MountPath: "/etc/nginx/events-includes", Name: "nginx-events-includes"}, {MountPath: "/etc/nginx/secrets", Name: "nginx-secrets"}, {MountPath: "/var/run/nginx", Name: "nginx-run"}, {MountPath: "/var/cache/nginx", Name: "nginx-cache"}, @@ -845,6 +852,8 @@ func (p *NginxProvisioner) buildNginxPodTemplateSpec( "--destination", "/etc/nginx-agent", "--source", "/includes/main.conf", "--destination", "/etc/nginx/main-includes", + "--source", "/includes/events.conf", + "--destination", "/etc/nginx/events-includes", }, Env: []corev1.EnvVar{ { @@ -861,6 +870,7 @@ func (p *NginxProvisioner) buildNginxPodTemplateSpec( {MountPath: "/etc/nginx-agent", Name: "nginx-agent"}, {MountPath: "/includes", Name: "nginx-includes-bootstrap"}, {MountPath: "/etc/nginx/main-includes", Name: "nginx-main-includes"}, + {MountPath: "/etc/nginx/events-includes", Name: "nginx-events-includes"}, }, SecurityContext: &corev1.SecurityContext{ Capabilities: &corev1.Capabilities{ @@ -927,6 +937,7 @@ func (p *NginxProvisioner) buildNginxPodTemplateSpec( {Name: "nginx-conf", VolumeSource: emptyDirVolumeSource}, {Name: "nginx-stream-conf", VolumeSource: emptyDirVolumeSource}, {Name: "nginx-main-includes", VolumeSource: emptyDirVolumeSource}, + {Name: "nginx-events-includes", VolumeSource: emptyDirVolumeSource}, {Name: "nginx-secrets", VolumeSource: emptyDirVolumeSource}, {Name: "nginx-run", VolumeSource: emptyDirVolumeSource}, {Name: "nginx-cache", VolumeSource: emptyDirVolumeSource}, diff --git a/internal/controller/provisioner/objects_test.go b/internal/controller/provisioner/objects_test.go index 08f6f629ec..600ff5d87f 100644 --- a/internal/controller/provisioner/objects_test.go +++ b/internal/controller/provisioner/objects_test.go @@ -1275,7 +1275,7 @@ func TestBuildNginxConfigMaps_WorkerConnections(t *testing.T) { bootstrapCM, ok := configMaps[0].(*corev1.ConfigMap) g.Expect(ok).To(BeTrue()) - g.Expect(bootstrapCM.Data["main.conf"]).To(ContainSubstring("worker_connections 1024;")) + g.Expect(bootstrapCM.Data["events.conf"]).To(ContainSubstring("worker_connections 1024;")) // Test with default worker connections (empty NginxProxy config) nProxyCfgEmpty := &graph.EffectiveNginxProxy{} @@ -1284,7 +1284,7 @@ func TestBuildNginxConfigMaps_WorkerConnections(t *testing.T) { bootstrapCM, ok = configMaps[0].(*corev1.ConfigMap) g.Expect(ok).To(BeTrue()) - g.Expect(bootstrapCM.Data["main.conf"]).To(ContainSubstring("worker_connections 1024;")) + g.Expect(bootstrapCM.Data["events.conf"]).To(ContainSubstring("worker_connections 1024;")) // Test with custom worker connections nProxyCfg := &graph.EffectiveNginxProxy{ @@ -1296,7 +1296,7 @@ func TestBuildNginxConfigMaps_WorkerConnections(t *testing.T) { bootstrapCM, ok = configMaps[0].(*corev1.ConfigMap) g.Expect(ok).To(BeTrue()) - g.Expect(bootstrapCM.Data["main.conf"]).To(ContainSubstring("worker_connections 2048;")) + g.Expect(bootstrapCM.Data["events.conf"]).To(ContainSubstring("worker_connections 2048;")) } func TestBuildNginxConfigMaps_AgentFields(t *testing.T) { diff --git a/internal/controller/provisioner/templates.go b/internal/controller/provisioner/templates.go index c6eb828377..78945d53f7 100644 --- a/internal/controller/provisioner/templates.go +++ b/internal/controller/provisioner/templates.go @@ -3,17 +3,17 @@ package provisioner import gotemplate "text/template" var ( - mainTemplate = gotemplate.Must(gotemplate.New("main").Parse(mainTemplateText)) - mgmtTemplate = gotemplate.Must(gotemplate.New("mgmt").Parse(mgmtTemplateText)) - agentTemplate = gotemplate.Must(gotemplate.New("agent").Parse(agentTemplateText)) + mainTemplate = gotemplate.Must(gotemplate.New("main").Parse(mainTemplateText)) + mgmtTemplate = gotemplate.Must(gotemplate.New("mgmt").Parse(mgmtTemplateText)) + agentTemplate = gotemplate.Must(gotemplate.New("agent").Parse(agentTemplateText)) + eventsTemplate = gotemplate.Must(gotemplate.New("events").Parse(eventsTemplateText)) ) const mainTemplateText = ` -error_log stderr {{ .ErrorLevel }}; +error_log stderr {{ .ErrorLevel }};` -events { - worker_connections {{ .WorkerConnections }}; -}` +const eventsTemplateText = ` +worker_connections {{ .WorkerConnections }};` const mgmtTemplateText = `mgmt { {{- if .UsageEndpoint }}