diff --git a/controllers/consoleplugin/config/static-frontend-config.yaml b/controllers/consoleplugin/config/static-frontend-config.yaml index 714ca98c6..561ee60fc 100644 --- a/controllers/consoleplugin/config/static-frontend-config.yaml +++ b/controllers/consoleplugin/config/static-frontend-config.yaml @@ -1049,7 +1049,7 @@ scopes: name: Node shortName: Node description: Node on which the resources are running - labels: + labels: - SrcK8S_HostName - DstK8S_HostName groups: @@ -1064,7 +1064,7 @@ scopes: name: Namespace shortName: NS description: Resource namespace - labels: + labels: - SrcK8S_Namespace - DstK8S_Namespace groups: @@ -1082,7 +1082,7 @@ scopes: name: Owner shortName: Own description: Controller owner, such as a Deployment - labels: + labels: - SrcK8S_OwnerName - SrcK8S_OwnerType - DstK8S_OwnerName @@ -1108,7 +1108,7 @@ scopes: name: Resource shortName: Res description: Base resource, such as a Pod, a Service or a Node - labels: + labels: - SrcK8S_Name - SrcK8S_Type - SrcK8S_OwnerName @@ -1170,6 +1170,7 @@ fields: description: Source namespace - name: SrcAddr type: string + format: IP description: Source IP address (ipv4 or ipv6) - name: SrcPort type: number @@ -1179,6 +1180,7 @@ fields: description: Source MAC address - name: SrcK8S_HostIP type: string + format: IP description: Source node IP - name: SrcK8S_HostName type: string @@ -1206,6 +1208,7 @@ fields: description: Destination namespace - name: DstAddr type: string + format: IP description: Destination IP address (ipv4 or ipv6) - name: DstPort type: number @@ -1215,6 +1218,7 @@ fields: description: Destination MAC address - name: DstK8S_HostIP type: string + format: IP description: Destination node IP - name: DstK8S_HostName type: string @@ -1254,21 +1258,21 @@ fields: - 1: Egress (outgoing traffic, from the node observation point) + - 2: Inner (with the same source and destination node) - name: IfDirections - type: number + type: number[] description: | Flow directions from the network interface observation point. Can be one of: + - 0: Ingress (interface incoming traffic) + - 1: Egress (interface outgoing traffic) - name: Interfaces - type: string + type: string[] description: Network interfaces - name: Flags - type: string + type: string[] description: | - Logical OR combination of unique TCP flags comprised in the flow, as per RFC-9293, with additional custom flags to represent the following per-packet combinations: + - - SYN+ACK (0x100) + - - FIN+ACK (0x200) + - - RST+ACK (0x400) + List of TCP flags comprised in the flow, as per RFC-9293, with additional custom flags to represent the following per-packet combinations: + + - SYN_ACK + + - FIN_ACK + + - RST_ACK - name: Bytes type: number description: Number of bytes @@ -1311,8 +1315,16 @@ fields: type: number description: TCP Smoothed Round Trip Time (SRTT), in nanoseconds - name: NetworkEvents - type: string - description: Network events flow monitoring + type: string[] + docType: object[] + description: | + Network events, such as network policy actions, composed of nested fields: + + - Feature (such as "acl" for network policies) + + - Type (such as an "AdminNetworkPolicy") + + - Namespace (namespace where the event applies, if any) + + - Name (name of the resource that triggered the event) + + - Action (such as "allow" or "drop") + + - Direction (Ingress or Egress) - name: ZoneId type: number description: packet translation zone id diff --git a/controllers/flp/flp_controller_flowmetrics_test.go b/controllers/flp/flp_controller_flowmetrics_test.go index bead11938..a4ebd573e 100644 --- a/controllers/flp/flp_controller_flowmetrics_test.go +++ b/controllers/flp/flp_controller_flowmetrics_test.go @@ -60,13 +60,24 @@ func ControllerFlowMetricsSpecs() { Labels: []string{"DstAddr"}, }, } + metric3 := metricslatest.FlowMetric{ // With nested labels + ObjectMeta: metav1.ObjectMeta{ + Name: "metric-3", + Namespace: operatorNamespace, + }, + Spec: metricslatest.FlowMetricSpec{ + MetricName: "m_3", + Type: metricslatest.CounterMetric, + Labels: []string{"NetworkEvents>Type", "NetworkEvents>Name"}, + }, + } metricUnwatched := metricslatest.FlowMetric{ ObjectMeta: metav1.ObjectMeta{ Name: "metric-unwatched", Namespace: otherNamespace, }, Spec: metricslatest.FlowMetricSpec{ - MetricName: "m_3", + MetricName: "m_unwatched", Type: metricslatest.CounterMetric, }, } @@ -121,6 +132,7 @@ func ControllerFlowMetricsSpecs() { Expect(k8sClient.Create(ctx, &metric1)).Should(Succeed()) Expect(k8sClient.Create(ctx, &metricUnwatched)).Should(Succeed()) Expect(k8sClient.Create(ctx, &metric2)).Should(Succeed()) + Expect(k8sClient.Create(ctx, &metric3)).Should(Succeed()) }) It("Should update configmap with custom metrics", func() { @@ -139,6 +151,7 @@ func ControllerFlowMetricsSpecs() { names := getSortedMetricsNames(metrics) return slices.Contains(names, metric1.Spec.MetricName) && slices.Contains(names, metric2.Spec.MetricName) && + slices.Contains(names, metric3.Spec.MetricName) && !slices.Contains(names, metricUnwatched.Spec.MetricName) })) }) @@ -153,6 +166,7 @@ func ControllerFlowMetricsSpecs() { }, timeout, interval).Should(Satisfy(func(conds []metav1.Condition) bool { ready := meta.FindStatusCondition(conds, fmstatus.ConditionReady) card := meta.FindStatusCondition(conds, fmstatus.ConditionCardinalityOK) + // Metrics 1 has cardinality FINE (no label) return ready != nil && card != nil && ready.Status == metav1.ConditionTrue && card.Status == metav1.ConditionTrue && ready.Reason == "Ready" && card.Reason == string(cardinality.WarnFine) })) @@ -164,11 +178,26 @@ func ControllerFlowMetricsSpecs() { } return metric2.Status.Conditions }, timeout, interval).Should(Satisfy(func(conds []metav1.Condition) bool { + // Metrics 2 has cardinality AVOID (Addr label) ready := meta.FindStatusCondition(conds, fmstatus.ConditionReady) card := meta.FindStatusCondition(conds, fmstatus.ConditionCardinalityOK) return ready != nil && card != nil && ready.Status == metav1.ConditionTrue && card.Status == metav1.ConditionFalse && ready.Reason == "Ready" && card.Reason == string(cardinality.WarnAvoid) })) + + Eventually(func() interface{} { + err := k8sClient.Get(ctx, helper.NamespacedName(&metric3), &metric3) + if err != nil { + return err + } + return metric3.Status.Conditions + }, timeout, interval).Should(Satisfy(func(conds []metav1.Condition) bool { + // Metrics 3 has cardinality FINE (NetworkEvents nested labels) + ready := meta.FindStatusCondition(conds, fmstatus.ConditionReady) + card := meta.FindStatusCondition(conds, fmstatus.ConditionCardinalityOK) + return ready != nil && card != nil && ready.Status == metav1.ConditionTrue && card.Status == metav1.ConditionTrue && + ready.Reason == "Ready" && card.Reason == string(cardinality.WarnFine) + })) }) }) diff --git a/hack/asciidoc-flows-gen.sh b/hack/asciidoc-flows-gen.sh index b7cc85c46..95443f702 100755 --- a/hack/asciidoc-flows-gen.sh +++ b/hack/asciidoc-flows-gen.sh @@ -19,11 +19,15 @@ nbfields=$(yq '.fields | length' $FE_SOURCE) lokiLabels=$(cat $LOKI_LABEL_SOURCE) cardinalityMap=$(cat $CARDINALITY_SOURCE) otelMap=$(cat $OTEL_SOURCE) +errors="" for i in $(seq 0 $(( $nbfields-1 )) ); do frontEntry=$(yq ".fields | sort_by(.name) | .[$i]" $FE_SOURCE) name=$(printf "$frontEntry" | yq ".name") - type=$(printf "$frontEntry" | yq ".type") + type=$(printf "$frontEntry" | yq ".docType") + if [[ "$type" == "null" ]]; then + type=$(printf "$frontEntry" | yq ".type") + fi desc=$(printf "$frontEntry" | yq ".description") filter=$(printf "$frontEntry" | yq ".filter") if [[ "$filter" == "null" ]]; then @@ -44,8 +48,7 @@ for i in $(seq 0 $(( $nbfields-1 )) ); do fi cardWarn=$(printf "$cardinalityMap" | jq -r ".$name") if [[ "$cardWarn" == "null" ]]; then - echo "missing cardinality for field $name" - exit 1 + errors="$errors\nmissing cardinality for field $name" fi otel=$(printf "$otelMap" | jq -r ".$name") if [[ "$otel" == "null" ]]; then @@ -60,4 +63,9 @@ for i in $(seq 0 $(( $nbfields-1 )) ); do echo -e "| $otel" >> $ADOC done +if [[ $errors != "" ]]; then + echo -e $errors + exit 1 +fi + echo -e '|===' >> $ADOC diff --git a/pkg/helper/cardinality/cardinality.json b/pkg/helper/cardinality/cardinality.json index 4df48dfd3..1f19d555e 100644 --- a/pkg/helper/cardinality/cardinality.json +++ b/pkg/helper/cardinality/cardinality.json @@ -50,7 +50,20 @@ "DnsErrno": "fine", "TimeFlowRttNs": "avoid", "NetworkEvents": "avoid", + "NetworkEvents>Feature": "fine", + "NetworkEvents>Type": "fine", + "NetworkEvents>Namespace": "fine", + "NetworkEvents>Name": "fine", + "NetworkEvents>Action": "fine", + "NetworkEvents>Direction": "fine", "K8S_ClusterName": "fine", + "Sampling": "fine", + "ZoneId": "avoid", + "XlatSrcPort": "careful", + "XlatSrcAddr": "avoid", + "XlatIcmpId": "avoid", + "XlatDstPort": "careful", + "XlatDstAddr": "avoid", "_RecordType": "fine", "_HashId": "avoid" -} \ No newline at end of file +}