diff --git a/packages/apps/kubernetes/tests/monitoring_agents_application_identity_test.yaml b/packages/apps/kubernetes/tests/monitoring_agents_application_identity_test.yaml new file mode 100644 index 000000000..9fbc1c45b --- /dev/null +++ b/packages/apps/kubernetes/tests/monitoring_agents_application_identity_test.yaml @@ -0,0 +1,38 @@ +suite: guest fluent-bit never ships application identity stream fields + +templates: + - templates/helmreleases/monitoring-agents.yaml + +values: + - values/common.yaml + +release: + name: kubernetes-test + namespace: tenant-test + +# Pods in a guest cluster are tenant-controlled, so their +# apps.cozystack.io/application.* labels are not a trustworthy application +# identity, and the platform must not promote them to the stream fields the +# parent scopes application logs by. The guest release replaces the +# monitoring-agents filters and outputs, so it is the guest overrides that keep +# the parent's label lift out. This does not stop a guest admin who edits the +# guest's own fluent-bit or writes to the parent's vlinsert directly; that is +# the write-path control the logs proposal leaves open. + +tests: + - it: does not lift pod labels or declare lineage stream fields in the guest + set: + addons.monitoringAgents.enabled: true + _namespace.monitoring: tenant-test + asserts: + - isKind: + of: HelmRelease + - notMatchRegex: + path: spec.values.fluent-bit.config.filters + pattern: 'kubernetes_labels|apps_cozystack_io_application_' + - notMatchRegex: + path: spec.values.fluent-bit.config.outputs + pattern: 'apps_cozystack_io_application_' + - matchRegex: + path: spec.values.fluent-bit.config.outputs + pattern: '_stream_fields=stream,kubernetes_pod_name,kubernetes_container_name,kubernetes_namespace_name&' diff --git a/packages/system/monitoring-agents/tests/fluent-bit_application_identity_test.yaml b/packages/system/monitoring-agents/tests/fluent-bit_application_identity_test.yaml new file mode 100644 index 000000000..d1815eb1b --- /dev/null +++ b/packages/system/monitoring-agents/tests/fluent-bit_application_identity_test.yaml @@ -0,0 +1,67 @@ +suite: fluent-bit keeps the application identity of a container log line + +# The lineage webhook labels a pod with apps.cozystack.io/application.{group, +# kind,name}. A container log line keeps them as top-level +# apps_cozystack_io_application_{group,kind,name}, the names the metrics side +# uses, and they are stream fields so a reader can scope to one application +# with extra_stream_filters. The kubernetes map, labels included, is otherwise +# dropped by Remove_wildcard kubernetes_, so the three keys have to be lifted +# and renamed out of the kubernetes_ prefix before that filter runs. +templates: + - charts/fluent-bit/templates/configmap.yaml +release: + name: monitoring-agents + namespace: cozy-monitoring +set: + global: + target: tenant-root +kubernetesProvider: + scheme: + "v1/Namespace": + gvr: + version: v1 + resource: namespaces + namespaced: false + objects: + - kind: Namespace + apiVersion: v1 + metadata: + name: tenant-a + labels: + namespace.cozystack.io/monitoring: tenant-a +tests: + - it: lifts the pod labels after the kubernetes map is lifted + asserts: + - matchRegex: + path: data["fluent-bit.conf"] + pattern: '(?s)Operation lift\n\s+Nested_under kubernetes\n.*Name nest\n\s+Match kube\.\*\n\s+Operation lift\n\s+Nested_under kubernetes_labels\n\s+Add_prefix kubernetes_labels_\n' + + - it: renames the three lineage labels out of the kubernetes_ prefix before Remove_wildcard + asserts: + - matchRegex: + path: data["fluent-bit.conf"] + pattern: '(?s)Nested_under kubernetes_labels\n.*Rename kubernetes_labels_apps\.cozystack\.io/application\.group apps_cozystack_io_application_group\n\s+Rename kubernetes_labels_apps\.cozystack\.io/application\.kind apps_cozystack_io_application_kind\n\s+Rename kubernetes_labels_apps\.cozystack\.io/application\.name apps_cozystack_io_application_name\n.*Remove_wildcard kubernetes_\n' + + - it: makes the lineage keys stream fields on the default container-log output + asserts: + - matchRegex: + path: data["fluent-bit.conf"] + pattern: 'Match kube\.\*\n\s+Host vlinsert-generic\.tenant-root\.svc\n\s+port 9481\n\s+compress gzip\n\s+uri /insert/jsonline\?_stream_fields=log_source,stream,kubernetes_pod_name,kubernetes_container_name,kubernetes_namespace_name,apps_cozystack_io_application_group,apps_cozystack_io_application_kind,apps_cozystack_io_application_name&' + + - it: makes the lineage keys stream fields on a routed tenant's container-log output + asserts: + - matchRegex: + path: data["fluent-bit.conf"] + pattern: 'Match tenant\.tenant-a\.\*\n\s+Host vlinsert-generic\.tenant-a\.svc\n\s+port 9481\n\s+compress gzip\n\s+uri /insert/jsonline\?_stream_fields=log_source,stream,kubernetes_pod_name,kubernetes_container_name,kubernetes_namespace_name,apps_cozystack_io_application_group,apps_cozystack_io_application_kind,apps_cozystack_io_application_name&' + + - it: leaves the events and audit outputs without lineage stream fields + asserts: + - matchRegex: + path: data["fluent-bit.conf"] + pattern: 'uri /insert/jsonline\?_stream_fields=log_source,reason,metadata_namespace,metadata_name&' + - matchRegex: + path: data["fluent-bit.conf"] + pattern: 'uri /insert/jsonline\?_stream_fields=log_source,stage,user_username,verb,requestUri&' + - notMatchRegex: + path: data["fluent-bit.conf"] + pattern: 'Match (events\.\*|audit\.\*|\*)\n[^\[]*Nested_under kubernetes_labels' diff --git a/packages/system/monitoring-agents/values.yaml b/packages/system/monitoring-agents/values.yaml index 84c39ce44..d7dd870b0 100644 --- a/packages/system/monitoring-agents/values.yaml +++ b/packages/system/monitoring-agents/values.yaml @@ -411,7 +411,7 @@ fluent-bit: Host vlinsert-generic.{{ .Values.global.target }}.svc port 9481 compress gzip - uri /insert/jsonline?_stream_fields=log_source,stream,kubernetes_pod_name,kubernetes_container_name,kubernetes_namespace_name&_msg_field=log&_time_field=date + uri /insert/jsonline?_stream_fields=log_source,stream,kubernetes_pod_name,kubernetes_container_name,kubernetes_namespace_name,apps_cozystack_io_application_group,apps_cozystack_io_application_kind,apps_cozystack_io_application_name&_msg_field=log&_time_field=date format json_lines json_date_format iso8601 header AccountID 0 @@ -445,7 +445,7 @@ fluent-bit: Host vlinsert-generic.{{ $target }}.svc port 9481 compress gzip - uri /insert/jsonline?_stream_fields=log_source,stream,kubernetes_pod_name,kubernetes_container_name,kubernetes_namespace_name&_msg_field=log&_time_field=date + uri /insert/jsonline?_stream_fields=log_source,stream,kubernetes_pod_name,kubernetes_container_name,kubernetes_namespace_name,apps_cozystack_io_application_group,apps_cozystack_io_application_kind,apps_cozystack_io_application_name&_msg_field=log&_time_field=date format json_lines json_date_format iso8601 header AccountID 0 @@ -467,6 +467,19 @@ fluent-bit: Operation lift Nested_under kubernetes Add_prefix kubernetes_ + {{- /* + The pod's lineage labels name the application it belongs to. lift + cannot pick keys, so every label comes up; all but these three keep + the kubernetes_ prefix and fall to Remove_wildcard below. An absent + label stays absent, and VictoriaLogs builds _stream from the stream + fields that are present, so an unlabelled pod keeps its stream. + */}} + [FILTER] + Name nest + Match kube.* + Operation lift + Nested_under kubernetes_labels + Add_prefix kubernetes_labels_ [FILTER] Name modify Match kube.* @@ -507,6 +520,9 @@ fluent-bit: Rename kubernetes_pod_name keep_kubernetes_pod_name Rename kubernetes_namespace_name keep_kubernetes_namespace_name Rename kubernetes_container_name keep_kubernetes_container_name + Rename kubernetes_labels_apps.cozystack.io/application.group apps_cozystack_io_application_group + Rename kubernetes_labels_apps.cozystack.io/application.kind apps_cozystack_io_application_kind + Rename kubernetes_labels_apps.cozystack.io/application.name apps_cozystack_io_application_name [FILTER] Name modify Match kube.*