diff --git a/internal/controller/telemetry/collector.go b/internal/controller/telemetry/collector.go index 0369b3b740..ff45dbb81a 100644 --- a/internal/controller/telemetry/collector.go +++ b/internal/controller/telemetry/collector.go @@ -71,6 +71,12 @@ type Data struct { //nolint //required to skip golangci-lint-full fieldalignment InferencePoolCount int64 // BuildOS is the base operating system the control plane was built on (e.g. alpine, ubi). BuildOS string + // GatewayAttachedProxySettingsPolicyCount is the number of relevant ProxySettingsPolicies + // attached at the Gateway level. + GatewayAttachedProxySettingsPolicyCount int64 + // RouteAttachedProxySettingsPolicyCount is the number of relevant ProxySettingsPolicies + // attached at the Route level. + RouteAttachedProxySettingsPolicyCount int64 } // NGFResourceCounts stores the counts of all relevant resources that NGF processes and generates configuration from. @@ -112,6 +118,53 @@ type NGFResourceCounts struct { GatewayAttachedNpCount int64 } +func (rc *NGFResourceCounts) CountPolicies(g *graph.Graph) { + rc.BackendTLSPolicyCount = int64(len(g.BackendTLSPolicies)) + + for policyKey, policy := range g.NGFPolicies { + switch policyKey.GVK.Kind { + case kinds.ClientSettingsPolicy: + if len(policy.TargetRefs) == 0 { + continue + } + + if policy.TargetRefs[0].Kind == kinds.Gateway { + rc.GatewayAttachedClientSettingsPolicyCount++ + } else { + rc.RouteAttachedClientSettingsPolicyCount++ + } + case kinds.ObservabilityPolicy: + rc.ObservabilityPolicyCount++ + case kinds.UpstreamSettingsPolicy: + rc.UpstreamSettingsPolicyCount++ + } + } +} + +func CountProxySettingsPolicies(g *graph.Graph) (int64, int64) { + gatewayAttachedProxySettingsPolicyCount := int64(0) + routeAttachedProxySettingsPolicyCount := int64(0) + + for policyKey, policy := range g.NGFPolicies { + if policyKey.GVK.Kind == kinds.ProxySettingsPolicy { + if len(policy.TargetRefs) == 0 { + continue + } + + for _, tr := range policy.TargetRefs { + switch tr.Kind { + case kinds.Gateway: + gatewayAttachedProxySettingsPolicyCount++ + case kinds.HTTPRoute, kinds.GRPCRoute: + routeAttachedProxySettingsPolicyCount++ + } + } + } + } + + return gatewayAttachedProxySettingsPolicyCount, routeAttachedProxySettingsPolicyCount +} + // DataCollectorConfig holds configuration parameters for DataCollectorImpl. type DataCollectorConfig struct { // K8sClientReader is a Kubernetes API client Reader. @@ -186,6 +239,7 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { buildOs = "alpine" } inferencePoolCount := int64(len(g.ReferencedInferencePools)) + gatewayAttachedProxySettingsPolicyCount, routeAttachedProxySettingsPolicyCount := CountProxySettingsPolicies(g) data := Data{ Data: tel.Data{ @@ -198,17 +252,19 @@ func (c DataCollectorImpl) Collect(ctx context.Context) (Data, error) { InstallationID: deploymentID, ClusterNodeCount: int64(clusterInfo.NodeCount), }, - NGFResourceCounts: graphResourceCount, - ImageSource: c.cfg.ImageSource, - BuildOS: buildOs, - FlagNames: c.cfg.Flags.Names, - FlagValues: c.cfg.Flags.Values, - SnippetsFiltersDirectives: snippetsFiltersDirectives, - SnippetsFiltersDirectivesCount: snippetsFiltersDirectivesCount, - NginxPodCount: nginxPodCount, - ControlPlanePodCount: int64(replicaCount), - NginxOneConnectionEnabled: c.cfg.NginxOneConsoleConnection, - InferencePoolCount: inferencePoolCount, + NGFResourceCounts: graphResourceCount, + ImageSource: c.cfg.ImageSource, + BuildOS: buildOs, + FlagNames: c.cfg.Flags.Names, + FlagValues: c.cfg.Flags.Values, + SnippetsFiltersDirectives: snippetsFiltersDirectives, + SnippetsFiltersDirectivesCount: snippetsFiltersDirectivesCount, + NginxPodCount: nginxPodCount, + ControlPlanePodCount: int64(replicaCount), + NginxOneConnectionEnabled: c.cfg.NginxOneConsoleConnection, + InferencePoolCount: inferencePoolCount, + GatewayAttachedProxySettingsPolicyCount: gatewayAttachedProxySettingsPolicyCount, + RouteAttachedProxySettingsPolicyCount: routeAttachedProxySettingsPolicyCount, } return data, nil @@ -244,26 +300,7 @@ func collectGraphResourceCount( } } - ngfResourceCounts.BackendTLSPolicyCount = int64(len(g.BackendTLSPolicies)) - - for policyKey, policy := range g.NGFPolicies { - switch policyKey.GVK.Kind { - case kinds.ClientSettingsPolicy: - if len(policy.TargetRefs) == 0 { - continue - } - - if policy.TargetRefs[0].Kind == kinds.Gateway { - ngfResourceCounts.GatewayAttachedClientSettingsPolicyCount++ - } else { - ngfResourceCounts.RouteAttachedClientSettingsPolicyCount++ - } - case kinds.ObservabilityPolicy: - ngfResourceCounts.ObservabilityPolicyCount++ - case kinds.UpstreamSettingsPolicy: - ngfResourceCounts.UpstreamSettingsPolicyCount++ - } - } + ngfResourceCounts.CountPolicies(g) ngfResourceCounts.NginxProxyCount = int64(len(g.ReferencedNginxProxies)) ngfResourceCounts.SnippetsFilterCount = int64(len(g.SnippetsFilters)) diff --git a/internal/controller/telemetry/collector_test.go b/internal/controller/telemetry/collector_test.go index 2316d9414e..bb32fc5292 100644 --- a/internal/controller/telemetry/collector_test.go +++ b/internal/controller/telemetry/collector_test.go @@ -384,6 +384,22 @@ var _ = Describe("Collector", Ordered, func() { NsName: types.NamespacedName{Namespace: "test", Name: "UpstreamSettingsPolicy-1"}, GVK: schema.GroupVersionKind{Kind: kinds.UpstreamSettingsPolicy}, }: {}, + { + NsName: types.NamespacedName{Namespace: "test", Name: "ProxySettingsPolicy-1"}, + GVK: schema.GroupVersionKind{Kind: kinds.ProxySettingsPolicy}, + }: {TargetRefs: []graph.PolicyTargetRef{{Kind: kinds.Gateway}}}, + { + NsName: types.NamespacedName{Namespace: "test", Name: "ProxySettingsPolicy-2"}, + GVK: schema.GroupVersionKind{Kind: kinds.ProxySettingsPolicy}, + }: {TargetRefs: []graph.PolicyTargetRef{{Kind: kinds.HTTPRoute}}}, + { + NsName: types.NamespacedName{Namespace: "test", Name: "ProxySettingsPolicy-3"}, + GVK: schema.GroupVersionKind{Kind: kinds.ProxySettingsPolicy}, + }: {TargetRefs: []graph.PolicyTargetRef{{Kind: kinds.GRPCRoute}}}, + { + NsName: types.NamespacedName{Namespace: "test", Name: "ProxySettingsPolicy-4"}, + GVK: schema.GroupVersionKind{Kind: kinds.ProxySettingsPolicy}, + }: {TargetRefs: []graph.PolicyTargetRef{{Kind: kinds.Gateway}, {Kind: kinds.HTTPRoute}, {Kind: kinds.GRPCRoute}}}, }, ReferencedNginxProxies: map[types.NamespacedName]*graph.NginxProxy{ {Namespace: "test", Name: "NginxProxy-1"}: &gcNP, @@ -529,6 +545,8 @@ var _ = Describe("Collector", Ordered, func() { expData.BuildOS = "alpine" expData.InferencePoolCount = 3 + expData.GatewayAttachedProxySettingsPolicyCount = 2 + expData.RouteAttachedProxySettingsPolicyCount = 4 data, err := dataCollector.Collect(ctx) Expect(err).ToNot(HaveOccurred()) @@ -700,6 +718,22 @@ var _ = Describe("Collector", Ordered, func() { NsName: types.NamespacedName{Namespace: "test", Name: "UpstreamSettingsPolicy-1"}, GVK: schema.GroupVersionKind{Kind: kinds.UpstreamSettingsPolicy}, }: {}, + { + NsName: types.NamespacedName{Namespace: "test", Name: "ProxySettingsPolicy-1"}, + GVK: schema.GroupVersionKind{Kind: kinds.ProxySettingsPolicy}, + }: {TargetRefs: []graph.PolicyTargetRef{{Kind: kinds.Gateway}}}, + { + NsName: types.NamespacedName{Namespace: "test", Name: "ProxySettingsPolicy-2"}, + GVK: schema.GroupVersionKind{Kind: kinds.ProxySettingsPolicy}, + }: {TargetRefs: []graph.PolicyTargetRef{{Kind: kinds.HTTPRoute}}}, + { + NsName: types.NamespacedName{Namespace: "test", Name: "ProxySettingsPolicy-plural"}, + GVK: schema.GroupVersionKind{Kind: kinds.ProxySettingsPolicy}, + }: {TargetRefs: []graph.PolicyTargetRef{{Kind: kinds.Gateway}, {Kind: kinds.HTTPRoute}, {Kind: kinds.GRPCRoute}}}, + { + NsName: types.NamespacedName{Namespace: "test", Name: "ProxySettingsPolicy-empty"}, + GVK: schema.GroupVersionKind{Kind: kinds.ProxySettingsPolicy}, + }: {}, }, ReferencedNginxProxies: map[types.NamespacedName]*graph.NginxProxy{ {Namespace: "test", Name: "NginxProxy-1"}: {Valid: true}, @@ -797,6 +831,8 @@ var _ = Describe("Collector", Ordered, func() { } expData.NginxPodCount = 1 expData.InferencePoolCount = 1 + expData.GatewayAttachedProxySettingsPolicyCount = 2 + expData.RouteAttachedProxySettingsPolicyCount = 3 data, err := dataCollector.Collect(ctx) diff --git a/internal/controller/telemetry/data.avdl b/internal/controller/telemetry/data.avdl index 9b56755400..e3b2b02af3 100644 --- a/internal/controller/telemetry/data.avdl +++ b/internal/controller/telemetry/data.avdl @@ -120,5 +120,13 @@ attached at the Gateway level. */ /** BuildOS is the base operating system the control plane was built on (e.g. alpine, ubi). */ string? BuildOS = null; + /** GatewayAttachedProxySettingsPolicyCount is the number of relevant ProxySettingsPolicies +attached at the Gateway level. */ + long? GatewayAttachedProxySettingsPolicyCount = null; + + /** RouteAttachedProxySettingsPolicyCount is the number of relevant ProxySettingsPolicies +attached at the Route level. */ + long? RouteAttachedProxySettingsPolicyCount = null; + } } diff --git a/internal/controller/telemetry/data_attributes_generated.go b/internal/controller/telemetry/data_attributes_generated.go index ebc4eee057..7b82744512 100644 --- a/internal/controller/telemetry/data_attributes_generated.go +++ b/internal/controller/telemetry/data_attributes_generated.go @@ -25,6 +25,8 @@ func (d *Data) Attributes() []attribute.KeyValue { attrs = append(attrs, attribute.Bool("NginxOneConnectionEnabled", d.NginxOneConnectionEnabled)) attrs = append(attrs, attribute.Int64("InferencePoolCount", d.InferencePoolCount)) attrs = append(attrs, attribute.String("BuildOS", d.BuildOS)) + attrs = append(attrs, attribute.Int64("GatewayAttachedProxySettingsPolicyCount", d.GatewayAttachedProxySettingsPolicyCount)) + attrs = append(attrs, attribute.Int64("RouteAttachedProxySettingsPolicyCount", d.RouteAttachedProxySettingsPolicyCount)) return attrs } diff --git a/internal/controller/telemetry/data_test.go b/internal/controller/telemetry/data_test.go index f6dbcfc333..88434a25f4 100644 --- a/internal/controller/telemetry/data_test.go +++ b/internal/controller/telemetry/data_test.go @@ -42,12 +42,14 @@ func TestDataAttributes(t *testing.T) { UpstreamSettingsPolicyCount: 14, GatewayAttachedNpCount: 15, }, - SnippetsFiltersDirectives: []string{"main-three-count", "http-two-count", "server-one-count"}, - SnippetsFiltersDirectivesCount: []int64{3, 2, 1}, - NginxPodCount: 3, - ControlPlanePodCount: 3, - NginxOneConnectionEnabled: true, - InferencePoolCount: 16, + SnippetsFiltersDirectives: []string{"main-three-count", "http-two-count", "server-one-count"}, + SnippetsFiltersDirectivesCount: []int64{3, 2, 1}, + NginxPodCount: 3, + ControlPlanePodCount: 3, + NginxOneConnectionEnabled: true, + InferencePoolCount: 16, + GatewayAttachedProxySettingsPolicyCount: 17, + RouteAttachedProxySettingsPolicyCount: 18, } expected := []attribute.KeyValue{ @@ -89,6 +91,8 @@ func TestDataAttributes(t *testing.T) { attribute.Bool("NginxOneConnectionEnabled", true), attribute.Int64("InferencePoolCount", 16), attribute.String("BuildOS", ""), + attribute.Int64("GatewayAttachedProxySettingsPolicyCount", 17), + attribute.Int64("RouteAttachedProxySettingsPolicyCount", 18), } result := data.Attributes() @@ -137,6 +141,8 @@ func TestDataAttributesWithEmptyData(t *testing.T) { attribute.Bool("NginxOneConnectionEnabled", false), attribute.Int64("InferencePoolCount", 0), attribute.String("BuildOS", ""), + attribute.Int64("GatewayAttachedProxySettingsPolicyCount", 0), + attribute.Int64("RouteAttachedProxySettingsPolicyCount", 0), } result := data.Attributes() diff --git a/tests/suite/telemetry_test.go b/tests/suite/telemetry_test.go index 51d227ed2d..644576a864 100644 --- a/tests/suite/telemetry_test.go +++ b/tests/suite/telemetry_test.go @@ -98,6 +98,8 @@ var _ = Describe("Telemetry test with OTel collector", Label("telemetry"), func( "NginxOneConnectionEnabled: Bool(false)", "InferencePoolCount: Int(0)", "BuildOS:", + "GatewayAttachedProxySettingsPolicyCount: Int(0)", + "RouteAttachedProxySettingsPolicyCount: Int(0)", }, ) })