From 4103612a5e1a1d12b172ddb76e0591902eb40031 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Tue, 7 Oct 2025 12:09:30 +0100 Subject: [PATCH 01/15] Add BuilOS to telemetry --- cmd/gateway/commands.go | 6 ++ internal/controller/config/config.go | 2 + internal/controller/manager.go | 1 + internal/controller/telemetry/collector.go | 10 ++++ .../controller/telemetry/collector_test.go | 59 +++++++++++++++++++ internal/controller/telemetry/data.avdl | 2 + tests/suite/telemetry_test.go | 1 + 7 files changed, 81 insertions(+) diff --git a/cmd/gateway/commands.go b/cmd/gateway/commands.go index 4cb67bf3ec..b8c23b1ec8 100644 --- a/cmd/gateway/commands.go +++ b/cmd/gateway/commands.go @@ -209,6 +209,11 @@ func createControllerCommand() *cobra.Command { imageSource = "unknown" } + buildOs := os.Getenv("BUILD_OS") + if buildOs == "" { + buildOs = "alpine" + } + period, err := time.ParseDuration(telemetryReportPeriod) if err != nil { return fmt.Errorf("error parsing telemetry report period: %w", err) @@ -271,6 +276,7 @@ func createControllerCommand() *cobra.Command { Plus: plus, ExperimentalFeatures: gwExperimentalFeatures, ImageSource: imageSource, + BuildOS: buildOs, Flags: config.Flags{ Names: flagKeys, Values: flagValues, diff --git a/internal/controller/config/config.go b/internal/controller/config/config.go index e23f73ca59..5105acac18 100644 --- a/internal/controller/config/config.go +++ b/internal/controller/config/config.go @@ -26,6 +26,8 @@ type Config struct { GatewayClassName string // ImageSource is the source of the NGINX Gateway image. ImageSource string + // BuildOS is the OS the NGF and NGINX binary was built on. + BuildOS string // GatewayCtlrName is the name of this controller. GatewayCtlrName string // UsageReportConfig specifies the NGINX Plus usage reporting configuration. diff --git a/internal/controller/manager.go b/internal/controller/manager.go index a4e9fd9cf0..a4b1bc1d64 100644 --- a/internal/controller/manager.go +++ b/internal/controller/manager.go @@ -290,6 +290,7 @@ func StartManager(cfg config.Config) error { Name: cfg.GatewayPodConfig.Name, }, ImageSource: cfg.ImageSource, + BuildOS: cfg.BuildOS, Flags: cfg.Flags, NginxOneConsoleConnection: cfg.NginxOneConsoleTelemetryConfig.DataplaneKeySecretName != "", }) diff --git a/internal/controller/telemetry/collector.go b/internal/controller/telemetry/collector.go index e06da3f0b8..4fd4ca45e2 100644 --- a/internal/controller/telemetry/collector.go +++ b/internal/controller/telemetry/collector.go @@ -66,6 +66,8 @@ type Data struct { ControlPlanePodCount int64 // NginxOneConnectionEnabled is a boolean that indicates whether the connection to the Nginx One Console is enabled. NginxOneConnectionEnabled bool + // BuildOS is the OS the NGF and NGINX binary was built on. + BuildOS string } // NGFResourceCounts stores the counts of all relevant resources that NGF processes and generates configuration from. @@ -121,6 +123,8 @@ type DataCollectorConfig struct { Version string // ImageSource is the source of the NGF image. ImageSource string + // BuildOS is the OS the NGF and NGINX binary was built on. + BuildOS 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. @@ -174,6 +178,11 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { nginxPodCount := getNginxPodCount(g, clusterInfo.NodeCount) + buildOS := c.cfg.BuildOS + if buildOS == "" { + buildOS = "alpine" + } + data := Data{ Data: tel.Data{ ProjectName: "NGF", @@ -187,6 +196,7 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { }, NGFResourceCounts: graphResourceCount, ImageSource: c.cfg.ImageSource, + BuildOS: buildOS, FlagNames: c.cfg.Flags.Names, FlagValues: c.cfg.Flags.Values, SnippetsFiltersDirectives: snippetsFiltersDirectives, diff --git a/internal/controller/telemetry/collector_test.go b/internal/controller/telemetry/collector_test.go index 8c749fdfbe..eef847bef0 100644 --- a/internal/controller/telemetry/collector_test.go +++ b/internal/controller/telemetry/collector_test.go @@ -72,6 +72,64 @@ func createGetCallsFunc(objects ...client.Object) getCallsFunc { } var _ = Describe("Collector", Ordered, func() { + + Describe("BuildOS field", func() { + var ( + k8sClientReader *kubernetesfakes.FakeReader + fakeGraphGetter *telemetryfakes.FakeGraphGetter + fakeConfigurationGetter *telemetryfakes.FakeConfigurationGetter + version string + podNSName types.NamespacedName + flags config.Flags + ) + + BeforeEach(func() { + version = "1.1" + k8sClientReader = &kubernetesfakes.FakeReader{} + fakeGraphGetter = &telemetryfakes.FakeGraphGetter{} + fakeConfigurationGetter = &telemetryfakes.FakeConfigurationGetter{} + podNSName = types.NamespacedName{Namespace: "nginx-gateway", Name: "ngf-pod"} + flags = config.Flags{} + fakeGraphGetter.GetLatestGraphReturns(&graph.Graph{}) + fakeConfigurationGetter.GetLatestConfigurationReturns(nil) + }) + + It("sets BuildOS to 'alpine' when config.BuildOS is empty", func(ctx SpecContext) { + dataCollector := telemetry.NewDataCollectorImpl(telemetry.DataCollectorConfig{ + K8sClientReader: k8sClientReader, + GraphGetter: fakeGraphGetter, + ConfigurationGetter: fakeConfigurationGetter, + Version: version, + PodNSName: podNSName, + ImageSource: "local", + Flags: flags, + NginxOneConsoleConnection: true, + BuildOS: "", + }) + + data, err := dataCollector.Collect(ctx) + Expect(err).ToNot(HaveOccurred()) + Expect(data.BuildOS).To(Equal("alpine")) + }) + + It("sets BuildOS to 'ubi' when config.BuildOS is 'ubi'", func(ctx SpecContext) { + dataCollector := telemetry.NewDataCollectorImpl(telemetry.DataCollectorConfig{ + K8sClientReader: k8sClientReader, + GraphGetter: fakeGraphGetter, + ConfigurationGetter: fakeConfigurationGetter, + Version: version, + PodNSName: podNSName, + ImageSource: "local", + Flags: flags, + NginxOneConsoleConnection: true, + BuildOS: "ubi", + }) + + data, err := dataCollector.Collect(ctx) + Expect(err).ToNot(HaveOccurred()) + Expect(data.BuildOS).To(Equal("ubi")) + }) + }) var ( k8sClientReader *kubernetesfakes.FakeReader fakeGraphGetter *telemetryfakes.FakeGraphGetter @@ -195,6 +253,7 @@ var _ = Describe("Collector", Ordered, func() { ImageSource: "local", Flags: flags, NginxOneConsoleConnection: true, + BuildOS: "", }) baseGetCalls = createGetCallsFunc(ngfPod, ngfReplicaSet, kubeNamespace) diff --git a/internal/controller/telemetry/data.avdl b/internal/controller/telemetry/data.avdl index c19881315a..7420c98610 100644 --- a/internal/controller/telemetry/data.avdl +++ b/internal/controller/telemetry/data.avdl @@ -114,5 +114,7 @@ attached at the Gateway level. */ /** NginxOneConnectionEnabled is a boolean that indicates whether the connection to the Nginx One Console is enabled. */ boolean? NginxOneConnectionEnabled = null; + /** BuildOS is a string that indicates the base operating statem that both NGF and NGINX were built on. */ + string? BuildOS = null; } } diff --git a/tests/suite/telemetry_test.go b/tests/suite/telemetry_test.go index 2ad0c0b3a0..bc57c1ca1e 100644 --- a/tests/suite/telemetry_test.go +++ b/tests/suite/telemetry_test.go @@ -96,6 +96,7 @@ var _ = Describe("Telemetry test with OTel collector", Label("telemetry"), func( "NginxPodCount: Int(0)", "ControlPlanePodCount: Int(1)", "NginxOneConnectionEnabled: Bool(false)", + "BuildOS:", }, ) }) From 06c853dd227c4a5d9b35fd1094e7fc52df9e82af Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Tue, 7 Oct 2025 14:41:42 +0100 Subject: [PATCH 02/15] Run `make generate` to update data.avdl and generated attributes --- internal/controller/telemetry/data.avdl | 3 ++- internal/controller/telemetry/data_attributes_generated.go | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/controller/telemetry/data.avdl b/internal/controller/telemetry/data.avdl index 7420c98610..50a3b35cb8 100644 --- a/internal/controller/telemetry/data.avdl +++ b/internal/controller/telemetry/data.avdl @@ -114,7 +114,8 @@ attached at the Gateway level. */ /** NginxOneConnectionEnabled is a boolean that indicates whether the connection to the Nginx One Console is enabled. */ boolean? NginxOneConnectionEnabled = null; - /** BuildOS is a string that indicates the base operating statem that both NGF and NGINX were built on. */ + /** BuildOS is the OS the NGF and NGINX binary was built on. */ string? BuildOS = null; + } } diff --git a/internal/controller/telemetry/data_attributes_generated.go b/internal/controller/telemetry/data_attributes_generated.go index 3b8b3dcf3f..3423c902c9 100644 --- a/internal/controller/telemetry/data_attributes_generated.go +++ b/internal/controller/telemetry/data_attributes_generated.go @@ -23,6 +23,7 @@ func (d *Data) Attributes() []attribute.KeyValue { attrs = append(attrs, attribute.Int64("NginxPodCount", d.NginxPodCount)) attrs = append(attrs, attribute.Int64("ControlPlanePodCount", d.ControlPlanePodCount)) attrs = append(attrs, attribute.Bool("NginxOneConnectionEnabled", d.NginxOneConnectionEnabled)) + attrs = append(attrs, attribute.String("BuildOS", d.BuildOS)) return attrs } From 4bc9935417f438c1554d8643c3ab9219c2789522 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 09:12:16 +0000 Subject: [PATCH 03/15] Update module google.golang.org/grpc to v1.76.0 (#4029) * Update module google.golang.org/grpc to v1.76.0 | datasource | package | from | to | | ---------- | ---------------------- | ------- | ------- | | go | google.golang.org/grpc | v1.75.1 | v1.76.0 | Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update files for renovate --------- Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- tests/go.mod | 2 +- tests/go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index d88e103e73..b0569b16d3 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 go.uber.org/zap v1.27.0 golang.org/x/text v0.29.0 - google.golang.org/grpc v1.75.1 + google.golang.org/grpc v1.76.0 google.golang.org/protobuf v1.36.10 gopkg.in/evanphx/json-patch.v4 v4.13.0 k8s.io/api v0.34.1 diff --git a/go.sum b/go.sum index dc9ee2c46e..576e5d163a 100644 --- a/go.sum +++ b/go.sum @@ -323,8 +323,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1: google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A= +google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/tests/go.mod b/tests/go.mod index fe66c54ad4..3c349d45bf 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -72,7 +72,7 @@ require ( golang.org/x/tools v0.36.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/grpc v1.75.1 // indirect + google.golang.org/grpc v1.76.0 // indirect google.golang.org/protobuf v1.36.10 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/tests/go.sum b/tests/go.sum index d057ff9cf3..53809c4a54 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -234,8 +234,8 @@ gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A= +google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 014b64b41445169b49dea0152395a99967183ee7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 13:09:15 +0100 Subject: [PATCH 04/15] Update module github.com/prometheus/common to v0.67.1 (#4042) | datasource | package | from | to | | ---------- | ---------------------------- | ------- | ------- | | go | github.com/prometheus/common | v0.66.1 | v0.67.1 | Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- tests/go.mod | 12 ++++++------ tests/go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/go.mod b/tests/go.mod index 3c349d45bf..95fd575a57 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -9,7 +9,7 @@ require ( github.com/onsi/ginkgo/v2 v2.26.0 github.com/onsi/gomega v1.38.2 github.com/prometheus/client_golang v1.23.2 - github.com/prometheus/common v0.66.1 + github.com/prometheus/common v0.67.1 github.com/tsenart/vegeta/v12 v12.12.0 k8s.io/api v0.34.1 k8s.io/apiextensions-apiserver v0.34.1 @@ -59,14 +59,14 @@ require ( github.com/stretchr/testify v1.11.1 // indirect github.com/x448/float16 v0.8.4 // indirect go.uber.org/automaxprocs v1.6.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/mod v0.27.0 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/net v0.44.0 // indirect + golang.org/x/oauth2 v0.31.0 // indirect golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect golang.org/x/text v0.29.0 // indirect golang.org/x/time v0.9.0 // indirect golang.org/x/tools v0.36.0 // indirect diff --git a/tests/go.sum b/tests/go.sum index 53809c4a54..2fe41a7018 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -123,8 +123,8 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= +github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= @@ -175,8 +175,8 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -193,10 +193,10 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo= +golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -205,10 +205,10 @@ golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= From 1d9dd4a14e895e78b0ac960cf225379867a5d87f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 13:31:16 +0000 Subject: [PATCH 05/15] Update github/codeql-action action to v4 (#4043) | datasource | package | from | to | | ----------- | -------------------- | ------- | ------- | | github-tags | github/codeql-action | v3.30.6 | v4.30.7 | Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/scorecards.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cdd3dc2ae0..3c989f6b9b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -187,7 +187,7 @@ jobs: fail-build: false - name: Upload scan result to GitHub Security tab - uses: github/codeql-action/upload-sarif@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6 + uses: github/codeql-action/upload-sarif@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7 if: ${{ !inputs.dry_run }} continue-on-error: true with: diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 789091f05f..12f5b47388 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -60,6 +60,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6 + uses: github/codeql-action/upload-sarif@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7 with: sarif_file: results.sarif From 3d58eb3ae6acb42d84ec717e696421ce5b07cf0e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 15:33:18 +0000 Subject: [PATCH 06/15] Update nginx Docker tag to v1.29.2 (#4041) * Update nginx Docker tag to v1.29.2 | datasource | package | from | to | | ---------- | ------- | ------ | ------ | | docker | nginx | 1.29.1 | 1.29.2 | Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update README * Remove package updates --------- Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Ciara Stacke --- README.md | 2 +- build/Dockerfile.nginx | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f62476df30..b3706a6284 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.1 | R35 | v3.3.2 | +| Edge | 1.3.0 | 1.25+ | 1.29.2 | R35 | v3.3.2 | | 2.1.4 | 1.3.0 | 1.25+ | 1.29.1 | R35 | v3.3.1 | | 2.1.3 | 1.3.0 | 1.25+ | 1.29.1 | R35 | v3.3.1 | | 2.1.2 | 1.3.0 | 1.25+ | 1.29.1 | R35 | v3.3.1 | diff --git a/build/Dockerfile.nginx b/build/Dockerfile.nginx index ef9eddfada..e219eb9b79 100644 --- a/build/Dockerfile.nginx +++ b/build/Dockerfile.nginx @@ -4,10 +4,7 @@ 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 nginx:1.29.1-alpine-otel -# the following apk update and add are to address CVE-2025-59375, CVE-2025-8961/CVE-2025-9165, CVE-2025-9230, and CVE-2025-9231/CVE-2025-9232 respectively. -# once a new base image is available with these package updates, they can be removed. -RUN apk update && apk add --no-cache 'libexpat>=2.7.2-r0' 'tiff>=4.7.1-r0' 'libcrypto3>=3.5.4-r0' 'libssl3>=3.5.4-r0' +FROM nginx:1.29.2-alpine-otel # renovate: datasource=github-tags depName=nginx/agent ARG NGINX_AGENT_VERSION=v3.3.2 From db96078944370200ac50abbe17f73a7a94582ad0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 Oct 2025 08:33:12 +0000 Subject: [PATCH 07/15] Update ghcr.io/nginx/dependencies/nginx-ubi:ubi9 Docker digest to 46e38dc (#4039) Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- build/ubi/Dockerfile.nginx | 2 +- build/ubi/Dockerfile.nginxplus | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/ubi/Dockerfile.nginx b/build/ubi/Dockerfile.nginx index 58ba1ec6af..b441590511 100644 --- a/build/ubi/Dockerfile.nginx +++ b/build/ubi/Dockerfile.nginx @@ -6,7 +6,7 @@ ADD --link --chown=101:1001 https://nginx.org/keys/nginx_signing.key nginx_signi ADD --link --chown=101:1001 build/ubi/repos/nginx.repo nginx.repo ADD --link --chown=101:1001 build/ubi/repos/agent.repo agent.repo -FROM ghcr.io/nginx/dependencies/nginx-ubi:ubi9@sha256:073c40696d255cbc11aff52473f975e99c8253e0982da7f42d9f70b567b31eb2 AS ubi9-packages +FROM ghcr.io/nginx/dependencies/nginx-ubi:ubi9@sha256:46e38dc6d8a9151f28f6dd775c528425ca4dfbc2a39055da08f653c12f959d27 AS ubi9-packages FROM redhat/ubi9-minimal:9.6 AS ubi-nginx diff --git a/build/ubi/Dockerfile.nginxplus b/build/ubi/Dockerfile.nginxplus index 699b24d289..c392ddd76c 100644 --- a/build/ubi/Dockerfile.nginxplus +++ b/build/ubi/Dockerfile.nginxplus @@ -6,7 +6,7 @@ ADD --link --chown=101:1001 https://cs.nginx.com/static/files/plus-9.repo nginx- ADD --link --chown=101:1001 https://nginx.org/keys/nginx_signing.key nginx_signing.key ADD --link --chown=101:1001 build/ubi/repos/agent.repo agent.repo -FROM ghcr.io/nginx/dependencies/nginx-ubi:ubi9@sha256:073c40696d255cbc11aff52473f975e99c8253e0982da7f42d9f70b567b31eb2 AS ubi9-packages +FROM ghcr.io/nginx/dependencies/nginx-ubi:ubi9@sha256:46e38dc6d8a9151f28f6dd775c528425ca4dfbc2a39055da08f653c12f959d27 AS ubi9-packages FROM redhat/ubi9-minimal:9.6 AS ubi-nginx-plus From b7d7dd926760efa5e72193cd8dcd861bddb4fff9 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 9 Oct 2025 10:06:46 +0100 Subject: [PATCH 08/15] Pass os.Getenv("BUILD_OS") directly to manager --- cmd/gateway/commands.go | 6 -- internal/controller/config/config.go | 2 - internal/controller/manager.go | 3 +- internal/controller/telemetry/collector.go | 7 +-- .../controller/telemetry/collector_test.go | 58 ------------------- 5 files changed, 3 insertions(+), 73 deletions(-) diff --git a/cmd/gateway/commands.go b/cmd/gateway/commands.go index b8c23b1ec8..4cb67bf3ec 100644 --- a/cmd/gateway/commands.go +++ b/cmd/gateway/commands.go @@ -209,11 +209,6 @@ func createControllerCommand() *cobra.Command { imageSource = "unknown" } - buildOs := os.Getenv("BUILD_OS") - if buildOs == "" { - buildOs = "alpine" - } - period, err := time.ParseDuration(telemetryReportPeriod) if err != nil { return fmt.Errorf("error parsing telemetry report period: %w", err) @@ -276,7 +271,6 @@ func createControllerCommand() *cobra.Command { Plus: plus, ExperimentalFeatures: gwExperimentalFeatures, ImageSource: imageSource, - BuildOS: buildOs, Flags: config.Flags{ Names: flagKeys, Values: flagValues, diff --git a/internal/controller/config/config.go b/internal/controller/config/config.go index 5105acac18..e23f73ca59 100644 --- a/internal/controller/config/config.go +++ b/internal/controller/config/config.go @@ -26,8 +26,6 @@ type Config struct { GatewayClassName string // ImageSource is the source of the NGINX Gateway image. ImageSource string - // BuildOS is the OS the NGF and NGINX binary was built on. - BuildOS string // GatewayCtlrName is the name of this controller. GatewayCtlrName string // UsageReportConfig specifies the NGINX Plus usage reporting configuration. diff --git a/internal/controller/manager.go b/internal/controller/manager.go index a4b1bc1d64..012c242cc9 100644 --- a/internal/controller/manager.go +++ b/internal/controller/manager.go @@ -3,6 +3,7 @@ package controller import ( "context" "fmt" + "os" "time" "github.com/go-logr/logr" @@ -290,7 +291,7 @@ func StartManager(cfg config.Config) error { Name: cfg.GatewayPodConfig.Name, }, ImageSource: cfg.ImageSource, - BuildOS: cfg.BuildOS, + BuildOS: os.Getenv("BUILD_OS"), Flags: cfg.Flags, NginxOneConsoleConnection: cfg.NginxOneConsoleTelemetryConfig.DataplaneKeySecretName != "", }) diff --git a/internal/controller/telemetry/collector.go b/internal/controller/telemetry/collector.go index 4fd4ca45e2..d33fa15e62 100644 --- a/internal/controller/telemetry/collector.go +++ b/internal/controller/telemetry/collector.go @@ -178,11 +178,6 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { nginxPodCount := getNginxPodCount(g, clusterInfo.NodeCount) - buildOS := c.cfg.BuildOS - if buildOS == "" { - buildOS = "alpine" - } - data := Data{ Data: tel.Data{ ProjectName: "NGF", @@ -196,7 +191,7 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { }, NGFResourceCounts: graphResourceCount, ImageSource: c.cfg.ImageSource, - BuildOS: buildOS, + BuildOS: c.cfg.BuildOS, FlagNames: c.cfg.Flags.Names, FlagValues: c.cfg.Flags.Values, SnippetsFiltersDirectives: snippetsFiltersDirectives, diff --git a/internal/controller/telemetry/collector_test.go b/internal/controller/telemetry/collector_test.go index eef847bef0..c950d4f07a 100644 --- a/internal/controller/telemetry/collector_test.go +++ b/internal/controller/telemetry/collector_test.go @@ -72,64 +72,6 @@ func createGetCallsFunc(objects ...client.Object) getCallsFunc { } var _ = Describe("Collector", Ordered, func() { - - Describe("BuildOS field", func() { - var ( - k8sClientReader *kubernetesfakes.FakeReader - fakeGraphGetter *telemetryfakes.FakeGraphGetter - fakeConfigurationGetter *telemetryfakes.FakeConfigurationGetter - version string - podNSName types.NamespacedName - flags config.Flags - ) - - BeforeEach(func() { - version = "1.1" - k8sClientReader = &kubernetesfakes.FakeReader{} - fakeGraphGetter = &telemetryfakes.FakeGraphGetter{} - fakeConfigurationGetter = &telemetryfakes.FakeConfigurationGetter{} - podNSName = types.NamespacedName{Namespace: "nginx-gateway", Name: "ngf-pod"} - flags = config.Flags{} - fakeGraphGetter.GetLatestGraphReturns(&graph.Graph{}) - fakeConfigurationGetter.GetLatestConfigurationReturns(nil) - }) - - It("sets BuildOS to 'alpine' when config.BuildOS is empty", func(ctx SpecContext) { - dataCollector := telemetry.NewDataCollectorImpl(telemetry.DataCollectorConfig{ - K8sClientReader: k8sClientReader, - GraphGetter: fakeGraphGetter, - ConfigurationGetter: fakeConfigurationGetter, - Version: version, - PodNSName: podNSName, - ImageSource: "local", - Flags: flags, - NginxOneConsoleConnection: true, - BuildOS: "", - }) - - data, err := dataCollector.Collect(ctx) - Expect(err).ToNot(HaveOccurred()) - Expect(data.BuildOS).To(Equal("alpine")) - }) - - It("sets BuildOS to 'ubi' when config.BuildOS is 'ubi'", func(ctx SpecContext) { - dataCollector := telemetry.NewDataCollectorImpl(telemetry.DataCollectorConfig{ - K8sClientReader: k8sClientReader, - GraphGetter: fakeGraphGetter, - ConfigurationGetter: fakeConfigurationGetter, - Version: version, - PodNSName: podNSName, - ImageSource: "local", - Flags: flags, - NginxOneConsoleConnection: true, - BuildOS: "ubi", - }) - - data, err := dataCollector.Collect(ctx) - Expect(err).ToNot(HaveOccurred()) - Expect(data.BuildOS).To(Equal("ubi")) - }) - }) var ( k8sClientReader *kubernetesfakes.FakeReader fakeGraphGetter *telemetryfakes.FakeGraphGetter From 5e5a3c5f7b4514fb913b7cb235fb1fc0a0f51e58 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 9 Oct 2025 16:16:32 +0100 Subject: [PATCH 09/15] Fix failing unit tests --- internal/controller/telemetry/collector.go | 32 +++++-------------- .../controller/telemetry/collector_test.go | 3 +- internal/controller/telemetry/data_test.go | 2 ++ 3 files changed, 12 insertions(+), 25 deletions(-) diff --git a/internal/controller/telemetry/collector.go b/internal/controller/telemetry/collector.go index d33fa15e62..c43811f891 100644 --- a/internal/controller/telemetry/collector.go +++ b/internal/controller/telemetry/collector.go @@ -41,33 +41,17 @@ type ConfigurationGetter interface { // //go:generate go run -tags generator github.com/nginx/telemetry-exporter/cmd/generator -type=Data -scheme -scheme-protocol=NGFProductTelemetry -scheme-df-datatype=ngf-product-telemetry type Data struct { - // ImageSource tells whether the image was built by GitHub or locally (values are 'gha', 'local', or 'unknown') ImageSource string - tel.Data // embedding is required by the generator. - // FlagNames contains the command-line flag names. - FlagNames []string - // FlagValues contains the values of the command-line flags, where each value corresponds to the flag from FlagNames - // at the same index. - // Each value is either 'true' or 'false' for boolean flags and 'default' or 'user-defined' for non-boolean flags. - FlagValues []string - // SnippetsFiltersDirectives contains the directive-context strings of all applied SnippetsFilters. - // Both lists are ordered first by count, then by lexicographical order of the context string, - // then lastly by directive string. - SnippetsFiltersDirectives []string - // SnippetsFiltersDirectivesCount contains the count of the directive-context strings, where each count - // corresponds to the string from SnippetsFiltersDirectives at the same index. - // Both lists are ordered first by count, then by lexicographical order of the context string, - // then lastly by directive string. + BuildOS string + tel.Data + FlagNames []string + FlagValues []string + SnippetsFiltersDirectives []string SnippetsFiltersDirectivesCount []int64 - NGFResourceCounts // embedding is required by the generator. - // NginxPodCount is the total number of Nginx data plane Pods. - 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. + NGFResourceCounts + NginxPodCount int64 + ControlPlanePodCount int64 NginxOneConnectionEnabled bool - // BuildOS is the OS the NGF and NGINX binary was built on. - BuildOS string } // NGFResourceCounts stores the counts of all relevant resources that NGF processes and generates configuration from. diff --git a/internal/controller/telemetry/collector_test.go b/internal/controller/telemetry/collector_test.go index c950d4f07a..530e28db0f 100644 --- a/internal/controller/telemetry/collector_test.go +++ b/internal/controller/telemetry/collector_test.go @@ -172,6 +172,7 @@ var _ = Describe("Collector", Ordered, func() { NGFResourceCounts: telemetry.NGFResourceCounts{}, ControlPlanePodCount: 1, ImageSource: "local", + BuildOS: "ubi", FlagNames: flags.Names, FlagValues: flags.Values, SnippetsFiltersDirectives: []string{}, @@ -193,9 +194,9 @@ var _ = Describe("Collector", Ordered, func() { Version: version, PodNSName: podNSName, ImageSource: "local", + BuildOS: "ubi", Flags: flags, NginxOneConsoleConnection: true, - BuildOS: "", }) baseGetCalls = createGetCallsFunc(ngfPod, ngfReplicaSet, kubeNamespace) diff --git a/internal/controller/telemetry/data_test.go b/internal/controller/telemetry/data_test.go index 49c8e3543c..03b36f9a2b 100644 --- a/internal/controller/telemetry/data_test.go +++ b/internal/controller/telemetry/data_test.go @@ -86,6 +86,7 @@ func TestDataAttributes(t *testing.T) { attribute.Int64("NginxPodCount", 3), attribute.Int64("ControlPlanePodCount", 3), attribute.Bool("NginxOneConnectionEnabled", true), + attribute.String("BuildOS", ""), } result := data.Attributes() @@ -132,6 +133,7 @@ func TestDataAttributesWithEmptyData(t *testing.T) { attribute.Int64("NginxPodCount", 0), attribute.Int64("ControlPlanePodCount", 0), attribute.Bool("NginxOneConnectionEnabled", false), + attribute.String("BuildOS", ""), } result := data.Attributes() From a3d5a8e6809a3889f55fa74e5c251247978dbdf9 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 9 Oct 2025 19:18:33 +0100 Subject: [PATCH 10/15] Revert data struct and add nolint --- internal/controller/telemetry/collector.go | 34 +++++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/internal/controller/telemetry/collector.go b/internal/controller/telemetry/collector.go index c43811f891..91e3a5523e 100644 --- a/internal/controller/telemetry/collector.go +++ b/internal/controller/telemetry/collector.go @@ -39,19 +39,37 @@ type ConfigurationGetter interface { // Data is telemetry data. // +// nolint +// //go:generate go run -tags generator github.com/nginx/telemetry-exporter/cmd/generator -type=Data -scheme -scheme-protocol=NGFProductTelemetry -scheme-df-datatype=ngf-product-telemetry type Data struct { + // ImageSource tells whether the image was built by GitHub or locally (values are 'gha', 'local', or 'unknown') ImageSource string - BuildOS string - tel.Data - FlagNames []string - FlagValues []string - SnippetsFiltersDirectives []string + tel.Data // embedding is required by the generator. + // FlagNames contains the command-line flag names. + FlagNames []string + // FlagValues contains the values of the command-line flags, where each value corresponds to the flag from FlagNames + // at the same index. + // Each value is either 'true' or 'false' for boolean flags and 'default' or 'user-defined' for non-boolean flags. + FlagValues []string + // SnippetsFiltersDirectives contains the directive-context strings of all applied SnippetsFilters. + // Both lists are ordered first by count, then by lexicographical order of the context string, + // then lastly by directive string. + SnippetsFiltersDirectives []string + // SnippetsFiltersDirectivesCount contains the count of the directive-context strings, where each count + // corresponds to the string from SnippetsFiltersDirectives at the same index. + // Both lists are ordered first by count, then by lexicographical order of the context string, + // then lastly by directive string. SnippetsFiltersDirectivesCount []int64 - NGFResourceCounts - NginxPodCount int64 - ControlPlanePodCount int64 + NGFResourceCounts // embedding is required by the generator. + // NginxPodCount is the total number of Nginx data plane Pods. + 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 + // BuildOS is the OS the NGF and NGINX binary was built on. + BuildOS string } // NGFResourceCounts stores the counts of all relevant resources that NGF processes and generates configuration from. From 00b418df6fe2838daa072930f83bfdc855e7e641 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 9 Oct 2025 19:24:10 +0100 Subject: [PATCH 11/15] Fix //nolint lint error --- internal/controller/telemetry/collector.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/controller/telemetry/collector.go b/internal/controller/telemetry/collector.go index 91e3a5523e..1738d4d0cc 100644 --- a/internal/controller/telemetry/collector.go +++ b/internal/controller/telemetry/collector.go @@ -39,10 +39,8 @@ type ConfigurationGetter interface { // Data is telemetry data. // -// nolint -// //go:generate go run -tags generator github.com/nginx/telemetry-exporter/cmd/generator -type=Data -scheme -scheme-protocol=NGFProductTelemetry -scheme-df-datatype=ngf-product-telemetry -type Data struct { +type Data struct { //nolint // ImageSource tells whether the image was built by GitHub or locally (values are 'gha', 'local', or 'unknown') ImageSource string tel.Data // embedding is required by the generator. From 80220519be7cfa4a30d988d72e0cadae33183d62 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 9 Oct 2025 19:35:44 +0100 Subject: [PATCH 12/15] Add comment about //nolint --- internal/controller/telemetry/collector.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/controller/telemetry/collector.go b/internal/controller/telemetry/collector.go index 1738d4d0cc..a5d678ef7e 100644 --- a/internal/controller/telemetry/collector.go +++ b/internal/controller/telemetry/collector.go @@ -40,7 +40,7 @@ type ConfigurationGetter interface { // Data is telemetry data. // //go:generate go run -tags generator github.com/nginx/telemetry-exporter/cmd/generator -type=Data -scheme -scheme-protocol=NGFProductTelemetry -scheme-df-datatype=ngf-product-telemetry -type Data struct { //nolint +type Data struct { //nolint //required to skip golangci-lint-full fieldalignment // ImageSource tells whether the image was built by GitHub or locally (values are 'gha', 'local', or 'unknown') ImageSource string tel.Data // embedding is required by the generator. From 75f6de77fd15f7cbe3cb93301737ccb04eeb0be7 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Fri, 10 Oct 2025 16:42:42 +0100 Subject: [PATCH 13/15] Add buildOs to normal test case --- internal/controller/manager.go | 2 -- internal/controller/telemetry/collector.go | 8 +++++++- internal/controller/telemetry/collector_test.go | 5 +++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/internal/controller/manager.go b/internal/controller/manager.go index 012c242cc9..a4e9fd9cf0 100644 --- a/internal/controller/manager.go +++ b/internal/controller/manager.go @@ -3,7 +3,6 @@ package controller import ( "context" "fmt" - "os" "time" "github.com/go-logr/logr" @@ -291,7 +290,6 @@ func StartManager(cfg config.Config) error { Name: cfg.GatewayPodConfig.Name, }, ImageSource: cfg.ImageSource, - BuildOS: os.Getenv("BUILD_OS"), Flags: cfg.Flags, NginxOneConsoleConnection: cfg.NginxOneConsoleTelemetryConfig.DataplaneKeySecretName != "", }) diff --git a/internal/controller/telemetry/collector.go b/internal/controller/telemetry/collector.go index a5d678ef7e..61ae534f94 100644 --- a/internal/controller/telemetry/collector.go +++ b/internal/controller/telemetry/collector.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "os" "runtime" "sort" "strings" @@ -178,6 +179,11 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { nginxPodCount := getNginxPodCount(g, clusterInfo.NodeCount) + buildOs := os.Getenv("BUILD_OS") + if buildOs == "" { + buildOs = "alpine" + } + data := Data{ Data: tel.Data{ ProjectName: "NGF", @@ -191,7 +197,7 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { }, NGFResourceCounts: graphResourceCount, ImageSource: c.cfg.ImageSource, - BuildOS: c.cfg.BuildOS, + BuildOS: buildOs, FlagNames: c.cfg.Flags.Names, FlagValues: c.cfg.Flags.Values, SnippetsFiltersDirectives: snippetsFiltersDirectives, diff --git a/internal/controller/telemetry/collector_test.go b/internal/controller/telemetry/collector_test.go index 530e28db0f..b73f236863 100644 --- a/internal/controller/telemetry/collector_test.go +++ b/internal/controller/telemetry/collector_test.go @@ -172,7 +172,7 @@ var _ = Describe("Collector", Ordered, func() { NGFResourceCounts: telemetry.NGFResourceCounts{}, ControlPlanePodCount: 1, ImageSource: "local", - BuildOS: "ubi", + BuildOS: "alpine", FlagNames: flags.Names, FlagValues: flags.Values, SnippetsFiltersDirectives: []string{}, @@ -194,7 +194,7 @@ var _ = Describe("Collector", Ordered, func() { Version: version, PodNSName: podNSName, ImageSource: "local", - BuildOS: "ubi", + BuildOS: "alpine", Flags: flags, NginxOneConsoleConnection: true, }) @@ -521,6 +521,7 @@ var _ = Describe("Collector", Ordered, func() { expData.NginxPodCount = int64(8) expData.ControlPlanePodCount = int64(2) expData.NginxOneConnectionEnabled = true + expData.BuildOS = "alpine" data, err := dataCollector.Collect(ctx) Expect(err).ToNot(HaveOccurred()) From f56e9f20fb2841f6f7b3223cb73a5ccbb1092133 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Fri, 10 Oct 2025 16:48:04 +0100 Subject: [PATCH 14/15] Update buildOS comment and run `make generate` --- internal/controller/telemetry/collector.go | 4 ++-- internal/controller/telemetry/data.avdl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/controller/telemetry/collector.go b/internal/controller/telemetry/collector.go index 61ae534f94..0c33c8c2f6 100644 --- a/internal/controller/telemetry/collector.go +++ b/internal/controller/telemetry/collector.go @@ -67,7 +67,7 @@ type Data struct { //nolint //required to skip golangci-lint-full fieldalignment ControlPlanePodCount int64 // NginxOneConnectionEnabled is a boolean that indicates whether the connection to the Nginx One Console is enabled. NginxOneConnectionEnabled bool - // BuildOS is the OS the NGF and NGINX binary was built on. + // BuildOS is the base operating system the control plane was built on (e.g. alpine, ubi). BuildOS string } @@ -124,7 +124,7 @@ type DataCollectorConfig struct { Version string // ImageSource is the source of the NGF image. ImageSource string - // BuildOS is the OS the NGF and NGINX binary was built on. + // BuildOS is the base operating system the control plane was built on (e.g. alpine, ubi). BuildOS string // Flags contains the command-line NGF flag keys and values. Flags config.Flags diff --git a/internal/controller/telemetry/data.avdl b/internal/controller/telemetry/data.avdl index 50a3b35cb8..a131d91bc4 100644 --- a/internal/controller/telemetry/data.avdl +++ b/internal/controller/telemetry/data.avdl @@ -114,7 +114,7 @@ attached at the Gateway level. */ /** NginxOneConnectionEnabled is a boolean that indicates whether the connection to the Nginx One Console is enabled. */ boolean? NginxOneConnectionEnabled = null; - /** BuildOS is the OS the NGF and NGINX binary was built on. */ + /** BuildOS is the base operating system the control plane was built on (e.g. alpine, ubi). */ string? BuildOS = null; } From f8cfab607dbd73244a617ba23f965b1352052fe7 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Mon, 13 Oct 2025 17:57:26 +0100 Subject: [PATCH 15/15] Add `ENv BUILD_OS` to Dockerfiles --- build/Dockerfile | 1 + build/ubi/Dockerfile | 1 + 2 files changed, 2 insertions(+) diff --git a/build/Dockerfile b/build/Dockerfile index fa96a66180..6e80a70bb6 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -17,6 +17,7 @@ COPY --from=ca-certs-provider --link /etc/ssl/certs/ca-certificates.crt /etc/ssl USER 101:1001 ARG BUILD_AGENT ENV BUILD_AGENT=${BUILD_AGENT} +ENV BUILD_OS=alpine ENTRYPOINT [ "/usr/bin/gateway" ] FROM common AS container diff --git a/build/ubi/Dockerfile b/build/ubi/Dockerfile index 58edad536b..d3acf9e0aa 100644 --- a/build/ubi/Dockerfile +++ b/build/ubi/Dockerfile @@ -17,6 +17,7 @@ COPY --from=ca-certs-provider --link /etc/ssl/certs/ca-certificates.crt /etc/ssl USER 101:1001 ARG BUILD_AGENT ENV BUILD_AGENT=${BUILD_AGENT} +ENV BUILD_OS=ubi LABEL name="F5 NGINX Gateway Fabric NGINX Plus" \ maintainer="kubernetes@nginx.com" \