From 3859c705b4bc85c8349b88e8d27313caae88766c Mon Sep 17 00:00:00 2001 From: Ryan Min Date: Thu, 7 Nov 2024 10:50:10 -0500 Subject: [PATCH] add to documentation and add latest by default logic --- processor/k8sattributesprocessor/README.md | 5 +- .../k8sattributesprocessor/documentation.md | 2 +- processor/k8sattributesprocessor/e2e_test.go | 54 +++++++++---------- .../internal/kube/client.go | 7 +++ .../internal/kube/client_test.go | 6 +-- .../k8sattributesprocessor/metadata.yaml | 2 +- 6 files changed, 39 insertions(+), 37 deletions(-) diff --git a/processor/k8sattributesprocessor/README.md b/processor/k8sattributesprocessor/README.md index 35c8bfa53d9f..7bd4d917e951 100644 --- a/processor/k8sattributesprocessor/README.md +++ b/processor/k8sattributesprocessor/README.md @@ -168,7 +168,7 @@ spec: - --duration=10s - --rate=1 - --otlp-attributes=k8s.container.name="telemetrygen" - image: ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:latest + image: ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:0.112.0@sha256:b248ef911f93ae27cbbc85056d1ffacc87fd941bbdc2ffd951b6df8df72b8096 name: telemetrygen status: podIP: 10.244.0.11 @@ -191,7 +191,8 @@ the processor associates the received trace to the pod, based on the connection "k8s.pod.name": "telemetrygen-pod", "k8s.pod.uid": "038e2267-b473-489b-b48c-46bafdb852eb", "container.image.name": "telemetrygen", - "container.image.tag": "latest" + "container.image.tag": "0.112.0", + "container.image.repo_digests": "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:b248ef911f93ae27cbbc85056d1ffacc87fd941bbdc2ffd951b6df8df72b8096" } } ``` diff --git a/processor/k8sattributesprocessor/documentation.md b/processor/k8sattributesprocessor/documentation.md index 67bcb77d2741..fd68ea6a2372 100644 --- a/processor/k8sattributesprocessor/documentation.md +++ b/processor/k8sattributesprocessor/documentation.md @@ -9,7 +9,7 @@ | container.id | Container ID. Usually a UUID, as for example used to identify Docker containers. The UUID might be abbreviated. Requires k8s.container.restart_count. | Any Str | false | | container.image.name | Name of the image the container was built on. Requires container.id or k8s.container.name. | Any Str | true | | container.image.repo_digests | Repo digests of the container image as provided by the container runtime. | Any Slice | false | -| container.image.tag | Container image tag. Requires container.id or k8s.container.name. | Any Str | true | +| container.image.tag | Container image tag. Defaults to "latest" if not provided (unless digest also in image path) Requires container.id or k8s.container.name. | Any Str | true | | k8s.cluster.uid | Gives cluster uid identified with kube-system namespace | Any Str | false | | k8s.container.name | The name of the Container in a Pod template. Requires container.id. | Any Str | false | | k8s.cronjob.name | The name of the CronJob. | Any Str | false | diff --git a/processor/k8sattributesprocessor/e2e_test.go b/processor/k8sattributesprocessor/e2e_test.go index ddb81633cdf5..3e149270af7a 100644 --- a/processor/k8sattributesprocessor/e2e_test.go +++ b/processor/k8sattributesprocessor/e2e_test.go @@ -504,9 +504,8 @@ func TestE2E_NamespacedRBAC(t *testing.T) { "k8s.labels.app": newExpectedValue(equal, "telemetrygen-"+testID+"-traces-deployment"), "k8s.container.name": newExpectedValue(equal, "telemetrygen"), "container.image.name": newExpectedValue(equal, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen"), - "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(shouldnotexist, ""), - "container.id": newExpectedValue(exist, ""), + "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), "container.image.tag": newExpectedValue(shouldnotexist, ""), + "container.id": newExpectedValue(exist, ""), }, }, { @@ -528,9 +527,8 @@ func TestE2E_NamespacedRBAC(t *testing.T) { "k8s.labels.app": newExpectedValue(equal, "telemetrygen-"+testID+"-metrics-deployment"), "k8s.container.name": newExpectedValue(equal, "telemetrygen"), "container.image.name": newExpectedValue(equal, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen"), - "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(shouldnotexist, ""), - "container.id": newExpectedValue(exist, ""), + "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), "container.image.tag": newExpectedValue(shouldnotexist, ""), + "container.id": newExpectedValue(exist, ""), }, }, { @@ -552,9 +550,8 @@ func TestE2E_NamespacedRBAC(t *testing.T) { "k8s.labels.app": newExpectedValue(equal, "telemetrygen-"+testID+"-logs-deployment"), "k8s.container.name": newExpectedValue(equal, "telemetrygen"), "container.image.name": newExpectedValue(equal, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen"), - "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(shouldnotexist, ""), - "container.id": newExpectedValue(exist, ""), + "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), "container.image.tag": newExpectedValue(shouldnotexist, ""), + "container.id": newExpectedValue(exist, ""), }, }, } @@ -662,12 +659,11 @@ func TestE2E_MixRBAC(t *testing.T) { "k8s.labels.app": newExpectedValue(equal, "telemetrygen-"+testID+"-traces-deployment"), "k8s.container.name": newExpectedValue(equal, "telemetrygen"), "container.image.name": newExpectedValue(equal, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen"), - "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(equal, "0.112.0"), - "container.id": newExpectedValue(exist, ""), - "k8s.namespace.labels.foons": newExpectedValue(equal, "barns"), - "k8s.node.labels.foo": newExpectedValue(equal, "too"), - "k8s.cluster.uid": newExpectedValue(regex, uidRe), + "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), "container.image.tag": newExpectedValue(equal, "0.112.0"), + "container.id": newExpectedValue(exist, ""), + "k8s.namespace.labels.foons": newExpectedValue(equal, "barns"), + "k8s.node.labels.foo": newExpectedValue(equal, "too"), + "k8s.cluster.uid": newExpectedValue(regex, uidRe), }, }, { @@ -689,12 +685,11 @@ func TestE2E_MixRBAC(t *testing.T) { "k8s.labels.app": newExpectedValue(equal, "telemetrygen-"+testID+"-metrics-deployment"), "k8s.container.name": newExpectedValue(equal, "telemetrygen"), "container.image.name": newExpectedValue(equal, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen"), - "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(equal, "0.112.0"), - "container.id": newExpectedValue(exist, ""), - "k8s.namespace.labels.foons": newExpectedValue(equal, "barns"), - "k8s.node.labels.foo": newExpectedValue(equal, "too"), - "k8s.cluster.uid": newExpectedValue(regex, uidRe), + "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), "container.image.tag": newExpectedValue(equal, "0.112.0"), + "container.id": newExpectedValue(exist, ""), + "k8s.namespace.labels.foons": newExpectedValue(equal, "barns"), + "k8s.node.labels.foo": newExpectedValue(equal, "too"), + "k8s.cluster.uid": newExpectedValue(regex, uidRe), }, }, { @@ -716,12 +711,11 @@ func TestE2E_MixRBAC(t *testing.T) { "k8s.labels.app": newExpectedValue(equal, "telemetrygen-"+testID+"-logs-deployment"), "k8s.container.name": newExpectedValue(equal, "telemetrygen"), "container.image.name": newExpectedValue(equal, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen"), - "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(equal, "0.112.0"), - "container.id": newExpectedValue(exist, ""), - "k8s.namespace.labels.foons": newExpectedValue(equal, "barns"), - "k8s.node.labels.foo": newExpectedValue(equal, "too"), - "k8s.cluster.uid": newExpectedValue(regex, uidRe), + "container.image.repo_digests": newExpectedValue(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), "container.image.tag": newExpectedValue(equal, "0.112.0"), + "container.id": newExpectedValue(exist, ""), + "k8s.namespace.labels.foons": newExpectedValue(equal, "barns"), + "k8s.node.labels.foo": newExpectedValue(equal, "too"), + "k8s.cluster.uid": newExpectedValue(regex, uidRe), }, }, } @@ -818,7 +812,7 @@ func TestE2E_NamespacedRBACNoPodIP(t *testing.T) { "k8s.container.name": newExpectedValue(equal, "telemetrygen"), "container.image.name": newExpectedValue(equal, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen"), "container.image.repo_digests": newExpectedValue(shouldnotexist, ""), - "container.image.tag": newExpectedValue(shouldnotexist, ""), + "container.image.tag": newExpectedValue(equal, "latest"), "container.id": newExpectedValue(exist, ""), }, }, @@ -842,7 +836,7 @@ func TestE2E_NamespacedRBACNoPodIP(t *testing.T) { "k8s.container.name": newExpectedValue(equal, "telemetrygen"), "container.image.name": newExpectedValue(equal, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen"), "container.image.repo_digests": newExpectedValue(shouldnotexist, ""), - "container.image.tag": newExpectedValue(shouldnotexist, ""), + "container.image.tag": newExpectedValue(equal, "latest"), "container.id": newExpectedValue(exist, ""), }, }, @@ -866,7 +860,7 @@ func TestE2E_NamespacedRBACNoPodIP(t *testing.T) { "k8s.container.name": newExpectedValue(equal, "telemetrygen"), "container.image.name": newExpectedValue(equal, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen"), "container.image.repo_digests": newExpectedValue(shouldnotexist, ""), - "container.image.tag": newExpectedValue(shouldnotexist, ""), + "container.image.tag": newExpectedValue(equal, "latest"), "container.id": newExpectedValue(exist, ""), }, }, diff --git a/processor/k8sattributesprocessor/internal/kube/client.go b/processor/k8sattributesprocessor/internal/kube/client.go index 0631dc1699ab..f92a10465403 100644 --- a/processor/k8sattributesprocessor/internal/kube/client.go +++ b/processor/k8sattributesprocessor/internal/kube/client.go @@ -634,6 +634,8 @@ func removeUnnecessaryPodData(pod *api_v1.Pod, rules ExtractionRules) *api_v1.Po } // parseAttributesFromImage parses the image name and tag for differently-formatted image names. +// returns "latest" as the default if tag not present. also checks if the image contains a digest. +// if it does, no latest tag is assumed. func parseNameAndTagFromImage(image string) (name, tag string, err error) { ref, err := reference.Parse(image) if err != nil { @@ -647,6 +649,11 @@ func parseNameAndTagFromImage(image string) (name, tag string, err error) { if taggedRef, ok := namedRef.(reference.Tagged); ok { tag = taggedRef.Tag() } + if tag == "" { + if digestedRef, ok := namedRef.(reference.Digested); !ok || digestedRef.String() == "" { + tag = "latest" + } + } return } diff --git a/processor/k8sattributesprocessor/internal/kube/client_test.go b/processor/k8sattributesprocessor/internal/kube/client_test.go index f414aa93f63e..b4e26017aec6 100644 --- a/processor/k8sattributesprocessor/internal/kube/client_test.go +++ b/processor/k8sattributesprocessor/internal/kube/client_test.go @@ -1483,7 +1483,7 @@ func Test_extractPodContainersAttributes(t *testing.T) { InitContainers: []api_v1.Container{ { Name: "init_container", - Image: "test/init-image:1.0.2", + Image: "test/init-image", }, }, }, @@ -1722,7 +1722,7 @@ func Test_extractPodContainersAttributes(t *testing.T) { }, "init-container-id-789": { ImageName: "test/init-image", - ImageTag: "1.0.2", + ImageTag: "latest", Statuses: map[int]ContainerStatus{ 0: {ContainerID: "init-container-id-789", ImageRepoDigest: "ghcr.io/initimage1@sha256:42e8ba40f9f70d604684c3a2a0ed321206b7e2e3509fdb2c8836d34f2edfb57b"}, }, @@ -1751,7 +1751,7 @@ func Test_extractPodContainersAttributes(t *testing.T) { }, "init_container": { ImageName: "test/init-image", - ImageTag: "1.0.2", + ImageTag: "latest", Statuses: map[int]ContainerStatus{ 0: {ContainerID: "init-container-id-789", ImageRepoDigest: "ghcr.io/initimage1@sha256:42e8ba40f9f70d604684c3a2a0ed321206b7e2e3509fdb2c8836d34f2edfb57b"}, }, diff --git a/processor/k8sattributesprocessor/metadata.yaml b/processor/k8sattributesprocessor/metadata.yaml index dd129a014a6f..0f0a0d65b208 100644 --- a/processor/k8sattributesprocessor/metadata.yaml +++ b/processor/k8sattributesprocessor/metadata.yaml @@ -107,7 +107,7 @@ resource_attributes: type: slice enabled: false container.image.tag: - description: Container image tag. Requires container.id or k8s.container.name. + description: Container image tag. Defaults to "latest" if not provided (unless digest also in image path) Requires container.id or k8s.container.name. type: string enabled: true