diff --git a/.chloggen/fix-k8s-image-parsing.yaml b/.chloggen/fix-k8s-image-parsing.yaml new file mode 100644 index 000000000000..4d21584120ea --- /dev/null +++ b/.chloggen/fix-k8s-image-parsing.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: processor/k8sattribute + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: fixes parsing of k8s image names to support images with tags and digests. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [36131] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/processor/k8sattributesprocessor/README.md b/processor/k8sattributesprocessor/README.md index 12a3e4d32f8a..19c12d738c53 100644 --- a/processor/k8sattributesprocessor/README.md +++ b/processor/k8sattributesprocessor/README.md @@ -170,7 +170,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 @@ -193,7 +193,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 ce1387846719..6e8acb1d19fb 100644 --- a/processor/k8sattributesprocessor/e2e_test.go +++ b/processor/k8sattributesprocessor/e2e_test.go @@ -54,7 +54,7 @@ func newExpectedValue(mode int, value string) *expectedValue { // TestE2E_ClusterRBAC tests the k8s attributes processor in a k8s cluster with the collector's service account having // cluster-wide permissions to list/watch namespaces, nodes, pods and replicasets. The config in the test does not -// set filter::namespace. +// set filter::namespace, and the telemetrygen image has a latest tag but no digest. // The test requires a prebuilt otelcontribcol image uploaded to a kind k8s cluster defined in // `/tmp/kube-config-otelcol-e2e-testing`. Run the following command prior to running the test locally: // @@ -540,7 +540,8 @@ func TestE2E_ClusterRBAC(t *testing.T) { } } -// Test with `filter::namespace` set and only role binding to collector's SA. We can't get node and namespace labels/annotations. +// Test with `filter::namespace` set and only role binding to collector's SA. We can't get node and namespace labels/annotations, +// and the telemetrygen image has a digest but no tag. func TestE2E_NamespacedRBAC(t *testing.T) { testDir := filepath.Join("testdata", "e2e", "namespacedrbac") @@ -615,7 +616,7 @@ func TestE2E_NamespacedRBAC(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(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(equal, "latest"), + "container.image.tag": newExpectedValue(shouldnotexist, ""), "container.id": newExpectedValue(exist, ""), }, }, @@ -639,7 +640,7 @@ func TestE2E_NamespacedRBAC(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(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(equal, "latest"), + "container.image.tag": newExpectedValue(shouldnotexist, ""), "container.id": newExpectedValue(exist, ""), }, }, @@ -663,7 +664,7 @@ func TestE2E_NamespacedRBAC(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(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(equal, "latest"), + "container.image.tag": newExpectedValue(shouldnotexist, ""), "container.id": newExpectedValue(exist, ""), }, }, @@ -712,7 +713,7 @@ func TestE2E_NamespacedRBAC(t *testing.T) { } // Test with `filter::namespace` set, role binding for namespace-scoped objects (pod, replicaset) and clusterrole -// binding for node and namespace objects. +// binding for node and namespace objects, and the telemetrygen image has a tag and digest. func TestE2E_MixRBAC(t *testing.T) { testDir := filepath.Join("testdata", "e2e", "mixrbac") @@ -802,7 +803,7 @@ func TestE2E_MixRBAC(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(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(equal, "latest"), + "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"), @@ -829,7 +830,7 @@ func TestE2E_MixRBAC(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(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(equal, "latest"), + "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"), @@ -856,7 +857,7 @@ func TestE2E_MixRBAC(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(regex, "ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:[0-9a-fA-f]{64}"), - "container.image.tag": newExpectedValue(equal, "latest"), + "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"), @@ -914,7 +915,8 @@ func TestE2E_MixRBAC(t *testing.T) { // While `k8s.pod.ip` is not set in `k8sattributes:extract:metadata` and the `pod_association` is not `connection` // we expect that the `k8s.pod.ip` metadata is not added. // While `container.image.repo_digests` is not set in `k8sattributes::extract::metadata`, we expect -// that the `container.image.repo_digests` metadata is not added +// that the `container.image.repo_digests` metadata is not added. +// The telemetrygen image has neither a tag nor digest (implicitly latest version) func TestE2E_NamespacedRBACNoPodIP(t *testing.T) { testDir := filepath.Join("testdata", "e2e", "namespaced_rbac_no_pod_ip") diff --git a/processor/k8sattributesprocessor/internal/kube/client.go b/processor/k8sattributesprocessor/internal/kube/client.go index bf8746b3e8ef..a984e7f85cbd 100644 --- a/processor/k8sattributesprocessor/internal/kube/client.go +++ b/processor/k8sattributesprocessor/internal/kube/client.go @@ -666,6 +666,30 @@ func removeUnnecessaryPodData(pod *api_v1.Pod, rules ExtractionRules) *api_v1.Po return &transformedPod } +// parseNameAndTagFromImage 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 { + return + } + namedRef, ok := ref.(reference.Named) + if !ok { + return "", "", errors.New("cannot retrieve image name") + } + name = namedRef.Name() + if taggedRef, ok := namedRef.(reference.Tagged); ok { + tag = taggedRef.Tag() + } + if tag == "" { + if digestedRef, ok := namedRef.(reference.Digested); !ok || digestedRef.String() == "" { + tag = "latest" + } + } + return +} + func (c *WatchClient) extractPodContainersAttributes(pod *api_v1.Pod) PodContainers { containers := PodContainers{ ByID: map[string]*Container{}, @@ -677,16 +701,14 @@ func (c *WatchClient) extractPodContainersAttributes(pod *api_v1.Pod) PodContain if c.Rules.ContainerImageName || c.Rules.ContainerImageTag { for _, spec := range append(pod.Spec.Containers, pod.Spec.InitContainers...) { container := &Container{} - nameTagSep := strings.LastIndex(spec.Image, ":") - if c.Rules.ContainerImageName { - if nameTagSep > 0 { - container.ImageName = spec.Image[:nameTagSep] - } else { - container.ImageName = spec.Image + name, tag, err := parseNameAndTagFromImage(spec.Image) + if err == nil { + if c.Rules.ContainerImageName { + container.ImageName = name + } + if c.Rules.ContainerImageTag { + container.ImageTag = tag } - } - if c.Rules.ContainerImageTag && nameTagSep > 0 { - container.ImageTag = spec.Image[nameTagSep+1:] } containers.ByName[spec.Name] = container } diff --git a/processor/k8sattributesprocessor/internal/kube/client_test.go b/processor/k8sattributesprocessor/internal/kube/client_test.go index f5e9cd03bfdc..f05e84f227d4 100644 --- a/processor/k8sattributesprocessor/internal/kube/client_test.go +++ b/processor/k8sattributesprocessor/internal/kube/client_test.go @@ -1495,17 +1495,21 @@ func Test_extractPodContainersAttributes(t *testing.T) { Containers: []api_v1.Container{ { Name: "container1", - Image: "test/image1:0.1.0", + Image: "example.com:5000/test/image1:0.1.0", }, { Name: "container2", - Image: "example.com:port1/image2:0.2.0", + Image: "example.com:81/image2@sha256:430ac608abaa332de4ce45d68534447c7a206edc5e98aaff9923ecc12f8a80d9", + }, + { + Name: "container3", + Image: "example-website.com/image3:1.0@sha256:4b0b1b6f6cdd3e5b9e55f74a1e8d19ed93a3f5a04c6b6c3c57c4e6d19f6b7c4d", }, }, InitContainers: []api_v1.Container{ { Name: "init_container", - Image: "test/init-image:1.0.2", + Image: "test/init-image", }, }, }, @@ -1520,7 +1524,13 @@ func Test_extractPodContainersAttributes(t *testing.T) { { Name: "container2", ContainerID: "docker://container2-id-456", - ImageID: "sha256:430ac608abaa332de4ce45d68534447c7a206edc5e98aaff9923ecc12f8a80d9", + ImageID: "sha256:4b0b1b6f6cdd3e5b9e55f74a1e8d19ed93a3f5a04c6b6c3c57c4e6d19f6b7c4d", + RestartCount: 2, + }, + { + Name: "container3", + ContainerID: "docker://container3-id-abc", + ImageID: "docker.io/otel/collector:2.0.0@sha256:430ac608abaa332de4ce45d68534447c7a206edc5e98aaff9923ecc12f8a80d9", RestartCount: 2, }, }, @@ -1564,13 +1574,15 @@ func Test_extractPodContainersAttributes(t *testing.T) { pod: &pod, want: PodContainers{ ByID: map[string]*Container{ - "container1-id-123": {ImageName: "test/image1"}, - "container2-id-456": {ImageName: "example.com:port1/image2"}, + "container1-id-123": {ImageName: "example.com:5000/test/image1"}, + "container2-id-456": {ImageName: "example.com:81/image2"}, + "container3-id-abc": {ImageName: "example-website.com/image3"}, "init-container-id-789": {ImageName: "test/init-image"}, }, ByName: map[string]*Container{ - "container1": {ImageName: "test/image1"}, - "container2": {ImageName: "example.com:port1/image2"}, + "container1": {ImageName: "example.com:5000/test/image1"}, + "container2": {ImageName: "example.com:81/image2"}, + "container3": {ImageName: "example-website.com/image3"}, "init_container": {ImageName: "test/init-image"}, }, }, @@ -1615,6 +1627,11 @@ func Test_extractPodContainersAttributes(t *testing.T) { 2: {ContainerID: "container2-id-456"}, }, }, + "container3-id-abc": { + Statuses: map[int]ContainerStatus{ + 2: {ContainerID: "container3-id-abc"}, + }, + }, "init-container-id-789": { Statuses: map[int]ContainerStatus{ 0: {ContainerID: "init-container-id-789"}, @@ -1632,6 +1649,11 @@ func Test_extractPodContainersAttributes(t *testing.T) { 2: {ContainerID: "container2-id-456"}, }, }, + "container3": { + Statuses: map[int]ContainerStatus{ + 2: {ContainerID: "container3-id-abc"}, + }, + }, "init_container": { Statuses: map[int]ContainerStatus{ 0: {ContainerID: "init-container-id-789"}, @@ -1658,6 +1680,11 @@ func Test_extractPodContainersAttributes(t *testing.T) { 2: {}, }, }, + "container3-id-abc": { + Statuses: map[int]ContainerStatus{ + 2: {ImageRepoDigest: "docker.io/otel/collector:2.0.0@sha256:430ac608abaa332de4ce45d68534447c7a206edc5e98aaff9923ecc12f8a80d9"}, + }, + }, "init-container-id-789": { Statuses: map[int]ContainerStatus{ 0: {ImageRepoDigest: "ghcr.io/initimage1@sha256:42e8ba40f9f70d604684c3a2a0ed321206b7e2e3509fdb2c8836d34f2edfb57b"}, @@ -1675,6 +1702,11 @@ func Test_extractPodContainersAttributes(t *testing.T) { 2: {}, }, }, + "container3": { + Statuses: map[int]ContainerStatus{ + 2: {ImageRepoDigest: "docker.io/otel/collector:2.0.0@sha256:430ac608abaa332de4ce45d68534447c7a206edc5e98aaff9923ecc12f8a80d9"}, + }, + }, "init_container": { Statuses: map[int]ContainerStatus{ 0: {ImageRepoDigest: "ghcr.io/initimage1@sha256:42e8ba40f9f70d604684c3a2a0ed321206b7e2e3509fdb2c8836d34f2edfb57b"}, @@ -1695,22 +1727,28 @@ func Test_extractPodContainersAttributes(t *testing.T) { want: PodContainers{ ByID: map[string]*Container{ "container1-id-123": { - ImageName: "test/image1", + ImageName: "example.com:5000/test/image1", ImageTag: "0.1.0", Statuses: map[int]ContainerStatus{ 0: {ContainerID: "container1-id-123", ImageRepoDigest: "docker.io/otel/collector@sha256:55d008bc28344c3178645d40e7d07df30f9d90abe4b53c3fc4e5e9c0295533da"}, }, }, "container2-id-456": { - ImageName: "example.com:port1/image2", - ImageTag: "0.2.0", + ImageName: "example.com:81/image2", Statuses: map[int]ContainerStatus{ 2: {ContainerID: "container2-id-456"}, }, }, + "container3-id-abc": { + ImageName: "example-website.com/image3", + ImageTag: "1.0", + Statuses: map[int]ContainerStatus{ + 2: {ContainerID: "container3-id-abc", ImageRepoDigest: "docker.io/otel/collector:2.0.0@sha256:430ac608abaa332de4ce45d68534447c7a206edc5e98aaff9923ecc12f8a80d9"}, + }, + }, "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"}, }, @@ -1718,22 +1756,28 @@ func Test_extractPodContainersAttributes(t *testing.T) { }, ByName: map[string]*Container{ "container1": { - ImageName: "test/image1", + ImageName: "example.com:5000/test/image1", ImageTag: "0.1.0", Statuses: map[int]ContainerStatus{ 0: {ContainerID: "container1-id-123", ImageRepoDigest: "docker.io/otel/collector@sha256:55d008bc28344c3178645d40e7d07df30f9d90abe4b53c3fc4e5e9c0295533da"}, }, }, "container2": { - ImageName: "example.com:port1/image2", - ImageTag: "0.2.0", + ImageName: "example.com:81/image2", Statuses: map[int]ContainerStatus{ 2: {ContainerID: "container2-id-456"}, }, }, + "container3": { + ImageName: "example-website.com/image3", + ImageTag: "1.0", + Statuses: map[int]ContainerStatus{ + 2: {ContainerID: "container3-id-abc", ImageRepoDigest: "docker.io/otel/collector:2.0.0@sha256:430ac608abaa332de4ce45d68534447c7a206edc5e98aaff9923ecc12f8a80d9"}, + }, + }, "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 edfb8bbc414d..fb4d8f863eca 100644 --- a/processor/k8sattributesprocessor/metadata.yaml +++ b/processor/k8sattributesprocessor/metadata.yaml @@ -108,7 +108,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 diff --git a/processor/k8sattributesprocessor/processor_test.go b/processor/k8sattributesprocessor/processor_test.go index 790c612549b2..875d9119bb60 100644 --- a/processor/k8sattributesprocessor/processor_test.go +++ b/processor/k8sattributesprocessor/processor_test.go @@ -1192,7 +1192,7 @@ func TestProcessorAddContainerAttributes(t *testing.T) { ByName: map[string]*kube.Container{ "app": { Statuses: map[int]kube.ContainerStatus{ - 2: {ImageRepoDigest: "docker.io/otel/collector@sha256:deadbeef02"}, + 2: {ImageRepoDigest: "docker.io/otel/collector:1.2.3@sha256:deadbeef02"}, }, }, }, @@ -1206,7 +1206,7 @@ func TestProcessorAddContainerAttributes(t *testing.T) { wantAttrs: map[string]any{ kube.K8sIPLabelName: "1.1.1.1", conventions.AttributeK8SContainerName: "app", - containerImageRepoDigests: []string{"docker.io/otel/collector@sha256:deadbeef02"}, + containerImageRepoDigests: []string{"docker.io/otel/collector:1.2.3@sha256:deadbeef02"}, }, }, { diff --git a/processor/k8sattributesprocessor/testdata/e2e/mixrbac/telemetrygen/deployment.yaml b/processor/k8sattributesprocessor/testdata/e2e/mixrbac/telemetrygen/deployment.yaml index a09257347f5e..32a2f063566e 100644 --- a/processor/k8sattributesprocessor/testdata/e2e/mixrbac/telemetrygen/deployment.yaml +++ b/processor/k8sattributesprocessor/testdata/e2e/mixrbac/telemetrygen/deployment.yaml @@ -28,7 +28,7 @@ spec: {{- if eq .DataType "traces" }} - --status-code= {{- end }} - image: ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:latest + image: ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:0.112.0@sha256:b248ef911f93ae27cbbc85056d1ffacc87fd941bbdc2ffd951b6df8df72b8096 imagePullPolicy: IfNotPresent name: telemetrygen restartPolicy: Always diff --git a/processor/k8sattributesprocessor/testdata/e2e/namespaced_rbac_no_pod_ip/telemetrygen/deployment.yaml b/processor/k8sattributesprocessor/testdata/e2e/namespaced_rbac_no_pod_ip/telemetrygen/deployment.yaml index 953e21514e60..b64a7ac87acf 100644 --- a/processor/k8sattributesprocessor/testdata/e2e/namespaced_rbac_no_pod_ip/telemetrygen/deployment.yaml +++ b/processor/k8sattributesprocessor/testdata/e2e/namespaced_rbac_no_pod_ip/telemetrygen/deployment.yaml @@ -30,7 +30,7 @@ spec: {{- if eq .DataType "traces" }} - --status-code= {{- end }} - image: ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:latest + image: ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen imagePullPolicy: IfNotPresent name: telemetrygen restartPolicy: Always diff --git a/processor/k8sattributesprocessor/testdata/e2e/namespacedrbac/telemetrygen/deployment.yaml b/processor/k8sattributesprocessor/testdata/e2e/namespacedrbac/telemetrygen/deployment.yaml index fd56c39d4eff..18f35425807a 100644 --- a/processor/k8sattributesprocessor/testdata/e2e/namespacedrbac/telemetrygen/deployment.yaml +++ b/processor/k8sattributesprocessor/testdata/e2e/namespacedrbac/telemetrygen/deployment.yaml @@ -29,7 +29,7 @@ spec: {{- if eq .DataType "traces" }} - --status-code= {{- end }} - image: ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:latest + image: ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen@sha256:b248ef911f93ae27cbbc85056d1ffacc87fd941bbdc2ffd951b6df8df72b8096 imagePullPolicy: IfNotPresent name: telemetrygen restartPolicy: Always