diff --git a/apis/flowcollector/v1beta1/flowcollector_webhook_test.go b/apis/flowcollector/v1beta1/flowcollector_webhook_test.go
index 41534eead..904b64b8d 100644
--- a/apis/flowcollector/v1beta1/flowcollector_webhook_test.go
+++ b/apis/flowcollector/v1beta1/flowcollector_webhook_test.go
@@ -123,7 +123,14 @@ func TestBeta1ConversionRoundtrip_Metrics(t *testing.T) {
err := initial.ConvertTo(&converted)
assert.NoError(err)
- expectedDefaultMetrics := []v1beta2.FLPMetric{"namespace_egress_packets_total", "namespace_flows_total", "namespace_rtt_seconds", "namespace_drop_packets_total", "namespace_dns_latency_seconds"}
+ expectedDefaultMetrics := []v1beta2.FLPMetric{
+ "namespace_egress_packets_total",
+ "namespace_flows_total",
+ "namespace_rtt_seconds",
+ "namespace_drop_packets_total",
+ "namespace_dns_latency_seconds",
+ "namespace_network_policy_events_total",
+ }
assert.Equal([]v1beta2.FLPAlert{v1beta2.AlertLokiError}, converted.Spec.Processor.Metrics.DisableAlerts)
assert.NotNil(converted.Spec.Processor.Metrics.IncludeList)
assert.Equal(expectedDefaultMetrics, *converted.Spec.Processor.Metrics.IncludeList)
diff --git a/apis/flowcollector/v1beta2/flowcollector_types.go b/apis/flowcollector/v1beta2/flowcollector_types.go
index 96a46c8cd..80cfe66b8 100644
--- a/apis/flowcollector/v1beta2/flowcollector_types.go
+++ b/apis/flowcollector/v1beta2/flowcollector_types.go
@@ -531,7 +531,7 @@ const (
)
// Metric name. More information in https://github.com/netobserv/network-observability-operator/blob/main/docs/Metrics.md.
-// +kubebuilder:validation:Enum:="namespace_egress_bytes_total";"namespace_egress_packets_total";"namespace_ingress_bytes_total";"namespace_ingress_packets_total";"namespace_flows_total";"node_egress_bytes_total";"node_egress_packets_total";"node_ingress_bytes_total";"node_ingress_packets_total";"node_flows_total";"workload_egress_bytes_total";"workload_egress_packets_total";"workload_ingress_bytes_total";"workload_ingress_packets_total";"workload_flows_total";"namespace_drop_bytes_total";"namespace_drop_packets_total";"node_drop_bytes_total";"node_drop_packets_total";"workload_drop_bytes_total";"workload_drop_packets_total";"namespace_rtt_seconds";"node_rtt_seconds";"workload_rtt_seconds";"namespace_dns_latency_seconds";"node_dns_latency_seconds";"workload_dns_latency_seconds"
+// +kubebuilder:validation:Enum:="namespace_egress_bytes_total";"namespace_egress_packets_total";"namespace_ingress_bytes_total";"namespace_ingress_packets_total";"namespace_flows_total";"node_egress_bytes_total";"node_egress_packets_total";"node_ingress_bytes_total";"node_ingress_packets_total";"node_flows_total";"workload_egress_bytes_total";"workload_egress_packets_total";"workload_ingress_bytes_total";"workload_ingress_packets_total";"workload_flows_total";"namespace_drop_bytes_total";"namespace_drop_packets_total";"node_drop_bytes_total";"node_drop_packets_total";"workload_drop_bytes_total";"workload_drop_packets_total";"namespace_rtt_seconds";"node_rtt_seconds";"workload_rtt_seconds";"namespace_dns_latency_seconds";"node_dns_latency_seconds";"workload_dns_latency_seconds";"node_network_policy_events_total";"namespace_network_policy_events_total";"workload_network_policy_events_total"
type FLPMetric string
// `FLPMetrics` define the desired FLP configuration regarding metrics
@@ -547,7 +547,8 @@ type FLPMetrics struct {
// Metrics enabled by default are:
// `namespace_flows_total`, `node_ingress_bytes_total`, `node_egress_bytes_total`, `workload_ingress_bytes_total`,
// `workload_egress_bytes_total`, `namespace_drop_packets_total` (when `PacketDrop` feature is enabled),
- // `namespace_rtt_seconds` (when `FlowRTT` feature is enabled), `namespace_dns_latency_seconds` (when `DNSTracking` feature is enabled).
+ // `namespace_rtt_seconds` (when `FlowRTT` feature is enabled), `namespace_dns_latency_seconds` (when `DNSTracking` feature is enabled),
+ // `namespace_network_policy_events_total` (when `NetworkEvents` feature is enabled).
// More information, with full list of available metrics: https://github.com/netobserv/network-observability-operator/blob/main/docs/Metrics.md
// +optional
IncludeList *[]FLPMetric `json:"includeList,omitempty"`
diff --git a/apis/flowmetrics/v1alpha1/flowmetric_types.go b/apis/flowmetrics/v1alpha1/flowmetric_types.go
index 8545d5ecf..6b8ce9a67 100644
--- a/apis/flowmetrics/v1alpha1/flowmetric_types.go
+++ b/apis/flowmetrics/v1alpha1/flowmetric_types.go
@@ -93,6 +93,11 @@ type FlowMetricSpec struct {
// +optional
Labels []string `json:"labels"`
+ // `flatten` is a list of list-type fields that must be flattened, such as Interfaces and NetworkEvents. Flattened fields generate one metric per item in that field.
+ // For instance, when flattening `Interfaces` on a bytes counter, a flow having Interfaces [br-ex, ens5] increases one counter for `br-ex` and another for `ens5`.
+ // +optional
+ Flatten []string `json:"flatten"`
+
// Set the `remap` property to use different names for the generated metric labels than the flow fields. Use the origin flow fields as keys, and the desired label names as values.
// +optional
Remap map[string]string `json:"remap"`
diff --git a/apis/flowmetrics/v1alpha1/flowmetric_webhook.go b/apis/flowmetrics/v1alpha1/flowmetric_webhook.go
index e48aa13d0..f3379373f 100644
--- a/apis/flowmetrics/v1alpha1/flowmetric_webhook.go
+++ b/apis/flowmetrics/v1alpha1/flowmetric_webhook.go
@@ -80,17 +80,17 @@ func checkFlowMetricCartinality(fMetric *FlowMetric) admission.Warnings {
}
func validateFlowMetric(_ context.Context, fMetric *FlowMetric) (admission.Warnings, error) {
- var str []string
+ var fields []string
var allErrs field.ErrorList
for _, f := range fMetric.Spec.Filters {
- str = append(str, f.Field)
+ fields = append(fields, f.Field)
}
- if len(str) != 0 {
- if !helper.FindFields(str, false) {
- allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "filters"), str,
- fmt.Sprintf("invalid filter field: %s", str)))
+ if len(fields) != 0 {
+ if !helper.FindFields(fields, false) {
+ allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "filters"), fields,
+ fmt.Sprintf("invalid filter field: %s", fields)))
}
}
@@ -100,12 +100,13 @@ func validateFlowMetric(_ context.Context, fMetric *FlowMetric) (admission.Warni
fmt.Sprintf("invalid label name: %s", fMetric.Spec.Labels)))
}
+ labelsMap := make(map[string]any, len(fMetric.Spec.Labels))
+ for _, label := range fMetric.Spec.Labels {
+ labelsMap[label] = nil
+ }
+
// Only fields defined as Labels are valid for remapping
if len(fMetric.Spec.Remap) != 0 {
- labelsMap := make(map[string]any, len(fMetric.Spec.Labels))
- for _, label := range fMetric.Spec.Labels {
- labelsMap[label] = nil
- }
var invalidMapping []string
for toRemap := range fMetric.Spec.Remap {
if _, ok := labelsMap[toRemap]; !ok {
@@ -117,6 +118,14 @@ func validateFlowMetric(_ context.Context, fMetric *FlowMetric) (admission.Warni
fmt.Sprintf("some fields defined for remapping are not defined as labels: %v", invalidMapping)))
}
}
+
+ // Check for valid fields
+ if len(fMetric.Spec.Flatten) != 0 {
+ if !helper.FindFields(fMetric.Spec.Flatten, false) {
+ allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "flatten"), fMetric.Spec.Flatten,
+ fmt.Sprintf("invalid fields to flatten: %s", fMetric.Spec.Flatten)))
+ }
+ }
}
if fMetric.Spec.ValueField != "" {
diff --git a/apis/flowmetrics/v1alpha1/flowmetric_webhook_test.go b/apis/flowmetrics/v1alpha1/flowmetric_webhook_test.go
index 5c5ca5bba..e7dafaee3 100644
--- a/apis/flowmetrics/v1alpha1/flowmetric_webhook_test.go
+++ b/apis/flowmetrics/v1alpha1/flowmetric_webhook_test.go
@@ -105,6 +105,27 @@ func TestFlowMetric(t *testing.T) {
},
expectedError: "invalid value field",
},
+ {
+ desc: "Valid nested fields",
+ m: &FlowMetric{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test1",
+ Namespace: "test-namespace",
+ },
+ Spec: FlowMetricSpec{
+ Labels: []string{"NetworkEvents>Name"},
+ Flatten: []string{"NetworkEvents"},
+ Filters: []MetricFilter{
+ {
+ Field: "NetworkEvents>Type",
+ Value: "acl",
+ },
+ },
+ Remap: map[string]string{"NetworkEvents>Name": "name"},
+ },
+ },
+ expectedError: "",
+ },
}
for _, test := range tests {
diff --git a/apis/flowmetrics/v1alpha1/zz_generated.deepcopy.go b/apis/flowmetrics/v1alpha1/zz_generated.deepcopy.go
index b0e40268b..9c6ed0a3b 100644
--- a/apis/flowmetrics/v1alpha1/zz_generated.deepcopy.go
+++ b/apis/flowmetrics/v1alpha1/zz_generated.deepcopy.go
@@ -117,6 +117,11 @@ func (in *FlowMetricSpec) DeepCopyInto(out *FlowMetricSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
+ if in.Flatten != nil {
+ in, out := &in.Flatten, &out.Flatten
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
if in.Remap != nil {
in, out := &in.Remap, &out.Remap
*out = make(map[string]string, len(*in))
diff --git a/bundle/manifests/flows.netobserv.io_flowcollectors.yaml b/bundle/manifests/flows.netobserv.io_flowcollectors.yaml
index 03ccc8a07..b724066d2 100644
--- a/bundle/manifests/flows.netobserv.io_flowcollectors.yaml
+++ b/bundle/manifests/flows.netobserv.io_flowcollectors.yaml
@@ -8378,7 +8378,8 @@ spec:
Metrics enabled by default are:
`namespace_flows_total`, `node_ingress_bytes_total`, `node_egress_bytes_total`, `workload_ingress_bytes_total`,
`workload_egress_bytes_total`, `namespace_drop_packets_total` (when `PacketDrop` feature is enabled),
- `namespace_rtt_seconds` (when `FlowRTT` feature is enabled), `namespace_dns_latency_seconds` (when `DNSTracking` feature is enabled).
+ `namespace_rtt_seconds` (when `FlowRTT` feature is enabled), `namespace_dns_latency_seconds` (when `DNSTracking` feature is enabled),
+ `namespace_network_policy_events_total` (when `NetworkEvents` feature is enabled).
More information, with full list of available metrics: https://github.com/netobserv/network-observability-operator/blob/main/docs/Metrics.md
items:
description: Metric name. More information in https://github.com/netobserv/network-observability-operator/blob/main/docs/Metrics.md.
@@ -8410,6 +8411,9 @@ spec:
- namespace_dns_latency_seconds
- node_dns_latency_seconds
- workload_dns_latency_seconds
+ - node_network_policy_events_total
+ - namespace_network_policy_events_total
+ - workload_network_policy_events_total
type: string
type: array
server:
diff --git a/bundle/manifests/flows.netobserv.io_flowmetrics.yaml b/bundle/manifests/flows.netobserv.io_flowmetrics.yaml
index 23273e35c..ad3b13f7d 100644
--- a/bundle/manifests/flows.netobserv.io_flowmetrics.yaml
+++ b/bundle/manifests/flows.netobserv.io_flowmetrics.yaml
@@ -196,6 +196,13 @@ spec:
- matchType
type: object
type: array
+ flatten:
+ description: |-
+ `flatten` is a list of list-type fields that must be flattened, such as Interfaces and NetworkEvents. Flattened fields generate one metric per item in that field.
+ For instance, when flattening `Interfaces` on a bytes counter, a flow having Interfaces [br-ex, ens5] increases one counter for `br-ex` and another for `ens5`.
+ items:
+ type: string
+ type: array
labels:
description: |-
`labels` is a list of fields that should be used as Prometheus labels, also known as dimensions.
diff --git a/config/crd/bases/flows.netobserv.io_flowcollectors.yaml b/config/crd/bases/flows.netobserv.io_flowcollectors.yaml
index 9ccefcfd3..eaa0e25b5 100644
--- a/config/crd/bases/flows.netobserv.io_flowcollectors.yaml
+++ b/config/crd/bases/flows.netobserv.io_flowcollectors.yaml
@@ -7733,7 +7733,8 @@ spec:
Metrics enabled by default are:
`namespace_flows_total`, `node_ingress_bytes_total`, `node_egress_bytes_total`, `workload_ingress_bytes_total`,
`workload_egress_bytes_total`, `namespace_drop_packets_total` (when `PacketDrop` feature is enabled),
- `namespace_rtt_seconds` (when `FlowRTT` feature is enabled), `namespace_dns_latency_seconds` (when `DNSTracking` feature is enabled).
+ `namespace_rtt_seconds` (when `FlowRTT` feature is enabled), `namespace_dns_latency_seconds` (when `DNSTracking` feature is enabled),
+ `namespace_network_policy_events_total` (when `NetworkEvents` feature is enabled).
More information, with full list of available metrics: https://github.com/netobserv/network-observability-operator/blob/main/docs/Metrics.md
items:
description: Metric name. More information in https://github.com/netobserv/network-observability-operator/blob/main/docs/Metrics.md.
@@ -7765,6 +7766,9 @@ spec:
- namespace_dns_latency_seconds
- node_dns_latency_seconds
- workload_dns_latency_seconds
+ - node_network_policy_events_total
+ - namespace_network_policy_events_total
+ - workload_network_policy_events_total
type: string
type: array
server:
diff --git a/config/crd/bases/flows.netobserv.io_flowmetrics.yaml b/config/crd/bases/flows.netobserv.io_flowmetrics.yaml
index 2bf92b9d6..f8d868b2a 100644
--- a/config/crd/bases/flows.netobserv.io_flowmetrics.yaml
+++ b/config/crd/bases/flows.netobserv.io_flowmetrics.yaml
@@ -186,6 +186,13 @@ spec:
- matchType
type: object
type: array
+ flatten:
+ description: |-
+ `flatten` is a list of list-type fields that must be flattened, such as Interfaces and NetworkEvents. Flattened fields generate one metric per item in that field.
+ For instance, when flattening `Interfaces` on a bytes counter, a flow having Interfaces [br-ex, ens5] increases one counter for `br-ex` and another for `ens5`.
+ items:
+ type: string
+ type: array
labels:
description: |-
`labels` is a list of fields that should be used as Prometheus labels, also known as dimensions.
diff --git a/config/samples/flowmetrics/network-policies.yaml b/config/samples/flowmetrics/network-policies.yaml
new file mode 100644
index 000000000..c2d1b347d
--- /dev/null
+++ b/config/samples/flowmetrics/network-policies.yaml
@@ -0,0 +1,21 @@
+# Count network policy events
+# More examples in https://github.com/netobserv/network-observability-operator/tree/main/config/samples/flowmetrics
+apiVersion: flows.netobserv.io/v1alpha1
+kind: FlowMetric
+metadata:
+ name: network-policy-events
+ namespace: netobserv
+spec:
+ metricName: network_policy_events_total
+ type: Counter
+ labels: [NetworkEvents>Type, NetworkEvents>Namespace, NetworkEvents>Name, NetworkEvents>Action, NetworkEvents>Direction]
+ filters:
+ - field: NetworkEvents>Feature
+ value: acl
+ flatten: [NetworkEvents]
+ remap:
+ "NetworkEvents>Type": type
+ "NetworkEvents>Namespace": namespace
+ "NetworkEvents>Name": name
+ "NetworkEvents>Action": action
+ "NetworkEvents>Direction": direction
diff --git a/config/samples/flowmetrics/per-interface.yaml b/config/samples/flowmetrics/per-interface.yaml
new file mode 100644
index 000000000..ec6b9be51
--- /dev/null
+++ b/config/samples/flowmetrics/per-interface.yaml
@@ -0,0 +1,14 @@
+# Count flows per network interface
+# More examples in https://github.com/netobserv/network-observability-operator/tree/main/config/samples/flowmetrics
+apiVersion: flows.netobserv.io/v1alpha1
+kind: FlowMetric
+metadata:
+ name: per-interface
+ namespace: netobserv
+spec:
+ metricName: per_interface
+ type: Counter
+ labels: [Interfaces]
+ flatten: [Interfaces]
+ remap:
+ Interfaces: interface
diff --git a/controllers/consoleplugin/config/static-frontend-config.yaml b/controllers/consoleplugin/config/static-frontend-config.yaml
index d596519b3..a73d0b312 100644
--- a/controllers/consoleplugin/config/static-frontend-config.yaml
+++ b/controllers/consoleplugin/config/static-frontend-config.yaml
@@ -888,7 +888,7 @@ filters:
component: number
hint: Specify a TCP smoothed Round Trip Time in nanoseconds.
- id: network_events
- name: Network events flow monitoring
+ name: Network Events
component: text
hint: Specify a single network event.
scopes:
diff --git a/controllers/flp/flp_pipeline_builder.go b/controllers/flp/flp_pipeline_builder.go
index 621b1719f..e8ba15df0 100644
--- a/controllers/flp/flp_pipeline_builder.go
+++ b/controllers/flp/flp_pipeline_builder.go
@@ -399,6 +399,7 @@ func flowMetricToFLP(flowMetric *metricslatest.FlowMetricSpec) (*api.MetricsItem
Filters: []api.MetricsFilter{},
Labels: flowMetric.Labels,
Remap: flowMetric.Remap,
+ Flatten: flowMetric.Flatten,
ValueKey: flowMetric.ValueField,
}
for _, f := range metrics.GetFilters(flowMetric) {
diff --git a/docs/FlowCollector.md b/docs/FlowCollector.md
index 39277a71c..02ea40fc5 100644
--- a/docs/FlowCollector.md
+++ b/docs/FlowCollector.md
@@ -17179,7 +17179,8 @@ Note that the more metrics you add, the bigger is the impact on Prometheus workl
Metrics enabled by default are:
`namespace_flows_total`, `node_ingress_bytes_total`, `node_egress_bytes_total`, `workload_ingress_bytes_total`,
`workload_egress_bytes_total`, `namespace_drop_packets_total` (when `PacketDrop` feature is enabled),
-`namespace_rtt_seconds` (when `FlowRTT` feature is enabled), `namespace_dns_latency_seconds` (when `DNSTracking` feature is enabled).
+`namespace_rtt_seconds` (when `FlowRTT` feature is enabled), `namespace_dns_latency_seconds` (when `DNSTracking` feature is enabled),
+`namespace_network_policy_events_total` (when `NetworkEvents` feature is enabled).
More information, with full list of available metrics: https://github.com/netobserv/network-observability-operator/blob/main/docs/Metrics.md