From 3746bf04740bc8343a45445f1e5b7922a760b893 Mon Sep 17 00:00:00 2001 From: Saloni Choudhary <146118978+salonichf5@users.noreply.github.com> Date: Thu, 14 Aug 2025 04:11:31 +0530 Subject: [PATCH] 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)", }, ) })