diff --git a/run-integration-test/README.md b/run-integration-test/README.md index d4eb274..9408b80 100644 --- a/run-integration-test/README.md +++ b/run-integration-test/README.md @@ -94,6 +94,7 @@ profiles: | Input | Required | Description | | ---------------------- | -------- | ---------------------------------------------------------------------- | | `replicated-api-token` | Yes | Replicated API Token, available via `secrets.REPLICATED_API_TOKEN` | +| `otlp-bearer-token` | Yes | Bearer token for the OTLP ingester (otlp.stackable.build) | | `test-mode` | Yes | Either run a `profile` or a `custom` test | | `test-mode-input` | Yes | The name of the profile or runner, based on the `test-mode` | | `test-suite` | No | The name of the BeKu test-suite (only used if running a `custom` test) | diff --git a/run-integration-test/action.yaml b/run-integration-test/action.yaml index f4471c2..1e14b4f 100644 --- a/run-integration-test/action.yaml +++ b/run-integration-test/action.yaml @@ -17,6 +17,14 @@ inputs: # Tokens replicated-api-token: description: Replicated API token + otlp-bearer-token: + description: Bearer token for the OTLP ingester (otlp.stackable.build) + # TODO: Add an input to control the k8sobjects receiver error_mode at runtime, eg: + # otel-k8sobjects-error-mode: + # description: k8sobjects receiver error_mode (propagate|ignore|silent) + # default: ignore + # Wire it into integration-test-info.env (see the collectors apply step) and reference it + # via ${env:OTEL_K8SOBJECTS_ERROR_MODE:-ignore} in the kubernetes-objects collector config. # Tool versions interu-version: @@ -38,7 +46,7 @@ inputs: helm-version: description: Version of helm # See https://github.com/helm/helm/releases for latest version - default: v3.19.0 + default: v3.21.1 stackablectl-version: description: Version of stackablectl # See https://github.com/stackabletech/stackable-cockpit/releases for latest version @@ -62,7 +70,6 @@ runs: - name: Install interu env: INTERU_VERSION: ${{ inputs.interu-version }} - RUNNER_DEBUG: ${{ runner.debug }} shell: bash run: "$GITHUB_ACTION_PATH/../.scripts/actions/install_interu.sh" @@ -73,8 +80,8 @@ runs: TEST_SUITE: ${{ inputs.test-suite }} TEST_MODE: ${{ inputs.test-mode }} TEST: ${{ inputs.test }} - RUNNER_DEBUG: ${{ runner.debug }} GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }}" GITHUB_RUN_ID: ${{ github.run_id }}" shell: bash run: | @@ -82,7 +89,7 @@ runs: [ -n "${RUNNER_DEBUG+set}" ] && set -x # Generate the cluster name - echo "KUBERNETES_CLUSTER_NAME=integration-test-${GITHUB_REPOSITORY}-${GITHUB_RUN_ID}" | tee -a "$GITHUB_OUTPUT" + echo "KUBERNETES_CLUSTER_NAME=integration-test-${GITHUB_REPOSITORY}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" | tee -a "$GITHUB_OUTPUT" # Run interu to expand parameters into GITHUB_OUTPUT for use as env vars in later steps. if [ "$TEST_MODE" == "profile" ]; then @@ -105,7 +112,8 @@ runs: KUBECTL_VERSION: ${{ inputs.kubectl-version }} KUTTL_VERSION: ${{ inputs.kuttl-version }} HELM_VERSION: ${{ inputs.helm-version }} - RUNNER_DEBUG: ${{ runner.debug }} + # The helm signature is expired since a couple of years... + VERIFY_SIGNATURE: "false" shell: bash run: | "$GITHUB_ACTION_PATH/../.scripts/actions/install_kubectl.sh" @@ -145,7 +153,7 @@ runs: - name: Prepare Replicated Cluster id: prepare-replicated-cluster - uses: replicatedhq/replicated-actions/create-cluster@291bef61a059631e39e84f8470f86152171c4c20 # v1.26.0 + uses: replicatedhq/replicated-actions/create-cluster@0fbf5395cf3e8c744f447bbc92b7de9135eead8e # v1.27.1 with: # See: https://github.com/replicatedhq/replicated-actions/tree/main/create-cluster#inputs api-token: ${{ inputs.replicated-api-token }} @@ -196,6 +204,24 @@ runs: kubectl -n opentelemetry-operator get pods echo "::endgroup::" + - name: Install OTLP ingester auth Secret + shell: bash + env: + OTLP_BEARER_TOKEN: ${{ inputs.otlp-bearer-token }} + run: | + set -euo pipefail + # No 'set -x' here: it would risk exposing the token. Mask defensively in case the + # value did not arrive via secrets.* (which GitHub redacts automatically). + echo "::add-mask::${OTLP_BEARER_TOKEN}" + + echo "::group::kubectl apply secret" + # The collectors read this via spec.env -> secretKeyRef (otlp-auth / bearer-token). + kubectl create secret generic otlp-auth \ + --namespace opentelemetry-operator \ + --from-literal=bearer-token="${OTLP_BEARER_TOKEN}" \ + --dry-run=client -o yaml | kubectl apply -f - + echo "::endgroup::" + - name: Apply OpenTelemetry Collectors configurations shell: bash env: @@ -205,6 +231,7 @@ runs: INTERU_KUBERNETES_DISTRIBUTION: ${{ steps.extract.outputs.INTERU_KUBERNETES_DISTRIBUTION }} INTERU_KUBERNETES_VERSION: ${{ steps.extract.outputs.INTERU_KUBERNETES_VERSION }} GITHUB_TRIGGERED_BY: ${{ github.triggering_actor }} + GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }} run: | set -euo pipefail @@ -214,6 +241,11 @@ runs: echo "KUBERNETES_DISTRIBUTION=${INTERU_KUBERNETES_DISTRIBUTION}" | tee -a "$INTEGRATION_TEST_INFO" echo "KUBERNETES_VERSION=${INTERU_KUBERNETES_VERSION}" | tee -a "$INTEGRATION_TEST_INFO" echo "TRIGGERED_BY=${GITHUB_TRIGGERED_BY}" | tee -a "$INTEGRATION_TEST_INFO" + echo "RUN_ATTEMPT=${GITHUB_RUN_ATTEMPT}" | tee -a "$INTEGRATION_TEST_INFO" + # TODO: To make the k8sobjects receiver error_mode runtime-controllable, expose the + # otel-k8sobjects-error-mode input in this step's `env:` block above and write it here: + # echo "OTEL_K8SOBJECTS_ERROR_MODE=${OTEL_K8SOBJECTS_ERROR_MODE}" | tee -a "$INTEGRATION_TEST_INFO" + # Then reference it via ${env:OTEL_K8SOBJECTS_ERROR_MODE:-ignore} in the collector config. echo "::endgroup::" echo "::group::kubectl apply" @@ -240,6 +272,9 @@ runs: REF_NAME: ${{ github.ref_name }} GH_TOKEN: ${{ github.token }} OPERATOR_NAME: ${{ steps.extract_operator_name.outputs.OPERATOR_NAME }} + BEKU_TEST_PARALLELISM: ${{ steps.extract.outputs.BEKU_TEST_PARALLELISM }} + BEKU_TEST_SUITE: ${{ steps.extract.outputs.BEKU_TEST_SUITE }} + BEKU_TEST: ${{ steps.extract.outputs.BEKU_TEST }} shell: bash run: | set -euo pipefail @@ -263,7 +298,7 @@ runs: if: always() # If the creation of the cluster failed, we don't want to error and abort continue-on-error: true - uses: replicatedhq/replicated-actions/remove-cluster@291bef61a059631e39e84f8470f86152171c4c20 # v1.26.0 + uses: replicatedhq/replicated-actions/remove-cluster@0fbf5395cf3e8c744f447bbc92b7de9135eead8e # v1.27.1 with: # See: https://github.com/replicatedhq/replicated-actions/tree/main/remove-cluster#inputs api-token: ${{ inputs.replicated-api-token }} diff --git a/run-integration-test/kustomize/.gitignore b/run-integration-test/kustomize/.gitignore index ee3892e..ec0187c 100644 --- a/run-integration-test/kustomize/.gitignore +++ b/run-integration-test/kustomize/.gitignore @@ -1 +1,4 @@ charts/ + +# Local-only secrets (eg: overlays/local/otlp-auth.secret.env). Never commit tokens. +*.secret.env diff --git a/run-integration-test/kustomize/bases/opentelemetry-collectors/container-log-scrape/opentelemetrycollector.yml b/run-integration-test/kustomize/bases/opentelemetry-collectors/container-log-scrape/opentelemetrycollector.yml index b318966..2fa557e 100644 --- a/run-integration-test/kustomize/bases/opentelemetry-collectors/container-log-scrape/opentelemetrycollector.yml +++ b/run-integration-test/kustomize/bases/opentelemetry-collectors/container-log-scrape/opentelemetrycollector.yml @@ -36,7 +36,7 @@ spec: config: receivers: # https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/receiver/filelogreceiver - filelog/varlogpods: + file_log/varlogpods: # A storage extension (eg: redis, or file) can be used for storing log offsets. Otherwise it is held in memory. # See: https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/storage # storage: {} @@ -105,7 +105,7 @@ spec: processors: # https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/k8sattributesprocessor - k8sattributes: + k8s_attributes: filter: # https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/k8sattributesprocessor/README.md#as-an-agent node_from_env_var: KUBE_NODE_NAME # this should be same as the var set from the downward API further up @@ -124,7 +124,7 @@ spec: # This key exists so it can be easily extended in an overlay: attributes: [] - resourcedetection/env: + resource_detection/env: detectors: [env] timeout: 2s override: false @@ -146,8 +146,8 @@ spec: extensions: [] pipelines: logs: - receivers: [filelog/varlogpods] + receivers: [file_log/varlogpods] # processors: [memory_limiter, batch] - processors: [k8sattributes, resourcedetection/env, resource] + processors: [k8s_attributes, resource_detection/env, resource] # Enable configured exporters in the overlay exporters: [] diff --git a/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-events/opentelemetrycollector.yml b/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-events/opentelemetrycollector.yml index ab11ec7..69e4bfc 100644 --- a/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-events/opentelemetrycollector.yml +++ b/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-events/opentelemetrycollector.yml @@ -29,10 +29,25 @@ spec: processors: # https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/k8sattributesprocessor - k8sattributes: - # Use the k8s attributes set by the receiver - # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/k8sattributesprocessor#as-a-gateway - passthrough: true + k8s_attributes: + # Enrich telemetry with pod metadata (including the owning workload) via the k8s API. + # The k8s_cluster/k8s_events receivers describe other objects and are not "sent" by + # those pods, so there is no source connection IP to match on. Associate by the + # k8s.pod.uid the k8s_cluster receiver stamps as a resource attribute instead. + passthrough: false + pod_association: + - sources: + - from: resource_attribute + name: k8s.pod.uid + extract: + metadata: + # Owning workload of each pod (deployment is resolved via its replicaset). + - k8s.deployment.name + - k8s.replicaset.name + - k8s.daemonset.name + - k8s.statefulset.name + - k8s.job.name + - k8s.cronjob.name # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/attributesprocessor # These are attributes for the specific spans, log events, etc... @@ -51,7 +66,7 @@ spec: key: service.name value: kubernetes-events - resourcedetection/env: + resource_detection/env: detectors: [env] timeout: 2s override: false @@ -75,12 +90,12 @@ spec: logs: receivers: [k8s_events] # processors: [memory_limiter, batch] - processors: [k8sattributes, resourcedetection/env, resource] + processors: [k8s_attributes, resource_detection/env, resource] # Enable configured exporters in the overlay exporters: [] metrics: receivers: [k8s_cluster] # processors: [memory_limiter, batch] - processors: [k8sattributes, resourcedetection/env, resource] + processors: [k8s_attributes, resource_detection/env, resource] # Enable configured exporters in the overlay exporters: [] diff --git a/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-objects/clusterrole-kubernetes-objects.yml b/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-objects/clusterrole-kubernetes-objects.yml index 76e4664..e603899 100644 --- a/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-objects/clusterrole-kubernetes-objects.yml +++ b/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-objects/clusterrole-kubernetes-objects.yml @@ -6,20 +6,102 @@ metadata: labels: app: kubernetes-objects rules: - # TODO: Add Stackable objects, and other common k8s objects + # Read-only across the object types watched by the k8sobjects receiver. + # NOTE: core "secrets" is deliberately omitted - the receiver emits full object data. - apiGroups: - "" resources: - - events - pods + - services + - endpoints + - configmaps + - persistentvolumeclaims + - persistentvolumes + - namespaces + - nodes + - serviceaccounts + - resourcequotas + - limitranges verbs: - get - list - watch - apiGroups: - - "events.k8s.io" + - "apps" resources: - - events + - deployments + - statefulsets + - daemonsets + - replicasets verbs: + - get + - list - watch + - apiGroups: + - "batch" + resources: + - jobs + - cronjobs + verbs: + - get - list + - watch + - apiGroups: + - "networking.k8s.io" + resources: + - ingresses + - networkpolicies + verbs: + - get + - list + - watch + - apiGroups: + - "autoscaling" + resources: + - horizontalpodautoscalers + verbs: + - get + - list + - watch + - apiGroups: + - "policy" + resources: + - poddisruptionbudgets + verbs: + - get + - list + - watch + - apiGroups: + - "storage.k8s.io" + resources: + - storageclasses + verbs: + - get + - list + - watch + # All Stackable CRDs, by API group. Wildcard resources so this survives plural typos and + # new CRDs across SDP releases. Read-only. Groups are far more stable than plural names. + - apiGroups: + - airflow.stackable.tech + - druid.stackable.tech + - hbase.stackable.tech + - hdfs.stackable.tech + - hive.stackable.tech + - kafka.stackable.tech + - nifi.stackable.tech + - spark.stackable.tech + - superset.stackable.tech + - trino.stackable.tech + - zookeeper.stackable.tech + - opa.stackable.tech + - opensearch.stackable.tech + - authentication.stackable.tech + - s3.stackable.tech + - listeners.stackable.tech + - secrets.stackable.tech + resources: + - "*" + verbs: + - get + - list + - watch diff --git a/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-objects/opentelemetrycollector.yml b/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-objects/opentelemetrycollector.yml index 5113b56..046a733 100644 --- a/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-objects/opentelemetrycollector.yml +++ b/run-integration-test/kustomize/bases/opentelemetry-collectors/kubernetes-objects/opentelemetrycollector.yml @@ -13,21 +13,173 @@ spec: receivers: # https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/receiver/k8sobjectsreceiver/testdata/config.yaml k8sobjects: + # This action runs across operator repos, so most Stackable CRDs below will not be + # installed on any given run. error_mode: ignore makes a missing/unknown object type + # non-fatal - the receiver logs it and skips it at startup instead of failing. + # See handleError() in the receiver's Start(): missing types hit `continue`. + # TODO: Make error_mode runtime-controllable from the workflow (no action bump) by + # sourcing it from an env var with a safe default: + # error_mode: "${env:OTEL_K8SOBJECTS_ERROR_MODE:-ignore}" + # Requires: an action input, writing it into integration-test-info.env, and this + # collector receiving that ConfigMap via envFrom (already true in the replicated overlay). + error_mode: ignore objects: - # TODO: Add Stackable objects, and other common k8s objects + # NOTE: events are intentionally NOT watched here - they are already collected by the + # k8s_events receiver in the kubernetes-events collector. Core Secrets are intentionally + # excluded: k8sobjects emits full object data with no field stripping (would exfiltrate + # secret material, including this stack's own otlp-auth token). + + # --- Common core (v1) resources --- - name: pods mode: watch - - name: events + - name: services + mode: watch + - name: endpoints + mode: watch + - name: configmaps + mode: watch + - name: persistentvolumeclaims + mode: watch + - name: persistentvolumes + mode: watch + - name: namespaces + mode: watch + - name: nodes + mode: watch + - name: serviceaccounts + mode: watch + - name: resourcequotas + mode: watch + - name: limitranges + mode: watch + + # --- apps --- + - name: deployments + group: apps + mode: watch + - name: statefulsets + group: apps + mode: watch + - name: daemonsets + group: apps + mode: watch + - name: replicasets + group: apps + mode: watch + + # --- batch --- + - name: jobs + group: batch + mode: watch + - name: cronjobs + group: batch + mode: watch + + # --- networking / scaling / policy / storage --- + - name: ingresses + group: networking.k8s.io + mode: watch + - name: networkpolicies + group: networking.k8s.io + mode: watch + - name: horizontalpodautoscalers + group: autoscaling + mode: watch + - name: poddisruptionbudgets + group: policy + mode: watch + - name: storageclasses + group: storage.k8s.io + mode: watch + + # --- Stackable CRDs (https://hub.stackable.tech/crds) --- + # Verify plurals against `kubectl get crds` - a wrong plural is silently skipped + # (error_mode: ignore), so it fails as missing coverage rather than a crash. + - name: airflowclusters + group: airflow.stackable.tech + mode: watch + - name: druidclusters + group: druid.stackable.tech + mode: watch + - name: hbaseclusters + group: hbase.stackable.tech + mode: watch + - name: hdfsclusters + group: hdfs.stackable.tech + mode: watch + - name: hiveclusters + group: hive.stackable.tech + mode: watch + - name: kafkaclusters + group: kafka.stackable.tech + mode: watch + - name: nificlusters + group: nifi.stackable.tech + mode: watch + - name: sparkapplications + group: spark.stackable.tech + mode: watch + - name: sparkhistoryservers + group: spark.stackable.tech + mode: watch + - name: sparkconnectservers + group: spark.stackable.tech + mode: watch + - name: supersetclusters + group: superset.stackable.tech + mode: watch + - name: druidconnections + group: superset.stackable.tech + mode: watch + - name: trinoclusters + group: trino.stackable.tech + mode: watch + - name: trinocatalogs + group: trino.stackable.tech + mode: watch + - name: zookeeperclusters + group: zookeeper.stackable.tech + mode: watch + - name: zookeeperznodes + group: zookeeper.stackable.tech + mode: watch + - name: opaclusters + group: opa.stackable.tech + mode: watch + - name: opensearchclusters + group: opensearch.stackable.tech + mode: watch + - name: authenticationclasses + group: authentication.stackable.tech + mode: watch + - name: s3connections + group: s3.stackable.tech + mode: watch + - name: s3buckets + group: s3.stackable.tech + mode: watch + - name: listeners + group: listeners.stackable.tech + mode: watch + - name: listenerclasses + group: listeners.stackable.tech + mode: watch + - name: podlisteners + group: listeners.stackable.tech + mode: watch + - name: secretclasses + group: secrets.stackable.tech + mode: watch + - name: truststores + group: secrets.stackable.tech mode: watch - group: events.k8s.io - exclude_watch_type: [DELETED] # This key exists so it can be easily extended in an overlay: extensions: {} processors: # https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/k8sattributesprocessor - k8sattributes: + k8s_attributes: # Use the k8s attributes set by the receiver # https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/k8sattributesprocessor#as-a-gateway passthrough: false @@ -49,7 +201,7 @@ spec: key: service.name value: kubernetes-objects - resourcedetection/env: + resource_detection/env: detectors: [env] timeout: 2s override: false @@ -73,6 +225,6 @@ spec: logs: receivers: [k8sobjects] # processors: [memory_limiter, batch] - processors: [k8sattributes, resourcedetection/env, resource] + processors: [k8s_attributes, resource_detection/env, resource] # Enable configured exporters in the overlay exporters: [] diff --git a/run-integration-test/kustomize/bases/opentelemetry-operator/kustomization.yml b/run-integration-test/kustomize/bases/opentelemetry-operator/kustomization.yml index 53775d8..204de95 100644 --- a/run-integration-test/kustomize/bases/opentelemetry-operator/kustomization.yml +++ b/run-integration-test/kustomize/bases/opentelemetry-operator/kustomization.yml @@ -9,7 +9,10 @@ helmCharts: - name: opentelemetry-operator repo: https://open-telemetry.github.io/opentelemetry-helm-charts # Find the latest release here: https://github.com/open-telemetry/opentelemetry-helm-charts/releases - version: 0.93.0 + # helm repo add opentelemetry-helm-charts https://open-telemetry.github.io/opentelemetry-helm-charts --force-update + # helm search repo opentelemetry-helm-charts/opentelemetry-operator + # renovate: registryUrl=https://open-telemetry.github.io/opentelemetry-helm-charts + version: 0.120.0 # 0.156.0 releaseName: opentelemetry-operator includeCRDs: true skipTests: true @@ -22,7 +25,7 @@ helmCharts: # See which plugins the opentelemetry-collector-k8s image contains here: # https://github.com/open-telemetry/opentelemetry-collector-releases/blob/main/distributions/otelcol-k8s/manifest.yaml repository: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-k8s - tag: 0.132.4 # Often the chart has old values for the collector image + tag: 0.157.0 # Often the chart has old values for the collector image admissionWebhooks: certManager: enabled: false diff --git a/run-integration-test/kustomize/overlays/local/kustomization.yml b/run-integration-test/kustomize/overlays/local/kustomization.yml new file mode 100644 index 0000000..fd255b8 --- /dev/null +++ b/run-integration-test/kustomize/overlays/local/kustomization.yml @@ -0,0 +1,102 @@ +--- +# Local testing overlay: a self-contained sibling of ../replicated for running on a +# local cluster (kind/minikube/k3d) without the run-integration-test GitHub Action. +# +# Differences from ../replicated: +# - Resource attributes are set to static literal values instead of ${env:...} vars +# populated by the CI action, so no integration-test-info.env / configMapGenerator +# is needed (the collector errors on startup if an ${env:...} var is unset). +# - Adds a `debug` exporter to the logs pipeline so telemetry is visible on the +# collector pod's stdout locally (kubectl logs) in addition to the OTLP/HTTP export. +namePrefix: local- + +resources: +- ../../bases/opentelemetry-collectors + +patches: +# Update all collectors to set the exporter endpoints and any other common overrides. +- target: + group: opentelemetry.io + version: v1beta1 + kind: OpenTelemetryCollector + patch: |- + - op: add + path: /spec/config/exporters/otlp_http + value: + # otlp_http appends the signal-specific path (eg: /v1/logs) to this endpoint. + endpoint: https://otlp.stackable.build + auth: + authenticator: bearertokenauth + - op: add + path: /spec/config/exporters/debug + value: + verbosity: detailed + # The ingester at otlp.stackable.build requires Bearer auth. The token is read from + # the OTLP_BEARER_TOKEN env var, sourced from the otlp-auth Secret (spec/env below). + # Locally that Secret is built by the secretGenerator from a gitignored otlp-auth.env. + - op: add + path: /spec/config/extensions/bearertokenauth + value: + token: ${env:OTLP_BEARER_TOKEN} + - op: add + path: /spec/config/service/extensions/- + value: bearertokenauth + - op: add + path: /spec/env/- + value: + name: OTLP_BEARER_TOKEN + valueFrom: + secretKeyRef: + name: otlp-auth + key: bearer-token + - op: add + path: /spec/config/service/pipelines/logs/exporters/- + value: otlp_http + - op: add + path: /spec/config/service/pipelines/logs/exporters/- + value: debug + - op: add + path: /spec/config/processors/resource/attributes/- + value: + action: upsert + key: k8s.cluster.name + value: local + - op: add + path: /spec/config/processors/resource/attributes/- + value: + action: upsert + key: k8s.cluster.distribution + value: local + - op: add + path: /spec/config/processors/resource/attributes/- + value: + action: upsert + key: k8s.cluster.version + value: local + - op: add + path: /spec/config/processors/resource/attributes/- + value: + action: upsert + key: github.actions.triggered_by + value: local + +# Specifically override config for the kubernetes-events collector. +- target: + group: opentelemetry.io + version: v1beta1 + kind: OpenTelemetryCollector + name: kubernetes-events + patch: |- + # OpenSearch Metrics collector is not yet available + - op: remove + path: /spec/config/service/pipelines/metrics + +secretGenerator: +# Local-only: builds the otlp-auth Secret from a gitignored otlp-auth.secret.env so the +# token is never committed. Copy otlp-auth.secret.env.example to otlp-auth.secret.env and +# set the real token. The generated (hashed) Secret name is rewritten into each collector's +# spec.env via the Secret nameReference in ../../bases/opentelemetry-collectors/crds.yml. +- name: otlp-auth + namespace: opentelemetry-operator + envs: + - otlp-auth.secret.env diff --git a/run-integration-test/kustomize/overlays/local/otlp-auth.secret.env.example b/run-integration-test/kustomize/overlays/local/otlp-auth.secret.env.example new file mode 100644 index 0000000..7ffa562 --- /dev/null +++ b/run-integration-test/kustomize/overlays/local/otlp-auth.secret.env.example @@ -0,0 +1,4 @@ +# Copy this file to otlp-auth.secret.env and set the real Bearer token for +# otlp.stackable.build. Files matching *.secret.env are gitignored and must never +# be committed. +bearer-token=REPLACE_WITH_BEARER_TOKEN diff --git a/run-integration-test/kustomize/overlays/replicated/kustomization.yml b/run-integration-test/kustomize/overlays/replicated/kustomization.yml index 7119214..9d76d12 100644 --- a/run-integration-test/kustomize/overlays/replicated/kustomization.yml +++ b/run-integration-test/kustomize/overlays/replicated/kustomization.yml @@ -12,14 +12,35 @@ patches: kind: OpenTelemetryCollector patch: |- - op: add - path: /spec/config/exporters/otlp + path: /spec/config/exporters/otlp_http value: - endpoint: otel-logs-source.nick.stackable.build:443 - # tls: - # insecure: true + # otlp_http appends the signal-specific path (eg: /v1/logs) to this endpoint. + # Note: the exporter was renamed from `otlphttp` to `otlp_http`; the old name + # is a deprecated alias that still works but will be removed in a future release. + endpoint: https://otlp.stackable.build + auth: + authenticator: bearertokenauth + # The ingester at otlp.stackable.build requires Bearer auth. The token is read from + # the OTLP_BEARER_TOKEN env var, sourced from the otlp-auth Secret (spec/env below). + # In CI this Secret is created by the run-integration-test action from a GHA secret. + - op: add + path: /spec/config/extensions/bearertokenauth + value: + token: ${env:OTLP_BEARER_TOKEN} + - op: add + path: /spec/config/service/extensions/- + value: bearertokenauth + - op: add + path: /spec/env/- + value: + name: OTLP_BEARER_TOKEN + valueFrom: + secretKeyRef: + name: otlp-auth + key: bearer-token - op: add path: /spec/config/service/pipelines/logs/exporters/- - value: otlp + value: otlp_http - op: add path: /spec/envFrom/- value: @@ -49,6 +70,12 @@ patches: action: upsert key: github.actions.triggered_by value: ${env:TRIGGERED_BY} + - op: add + path: /spec/config/processors/resource/attributes/- + value: + action: upsert + key: github.actions.run_attempt + value: ${env:RUN_ATTEMPT} # Specifically override config for the kubernetes-events collector. - target: @@ -57,13 +84,9 @@ patches: kind: OpenTelemetryCollector name: kubernetes-events patch: |- - # OpenSearch Metrics collector is not yet available - - op: remove - path: /spec/config/service/pipelines/metrics - # - op: add - # - op: add - # path: /spec/config/service/pipelines/metrics/exporters/- - # value: otlphttp + - op: add + path: /spec/config/service/pipelines/metrics/exporters/- + value: otlp_http configMapGenerator: # These get used by the attributes processor in each collector diff --git a/send-slack-notification/action.yaml b/send-slack-notification/action.yaml index 90323c0..4e1d7ed 100644 --- a/send-slack-notification/action.yaml +++ b/send-slack-notification/action.yaml @@ -48,6 +48,8 @@ runs: TEST_HEALTH: ${{ inputs.test-health }} shell: bash run: | + set -euo pipefail + if [ -z "${NOTIFICATION_TYPE:-}" ]; then echo "The type input must be provided" exit 1 @@ -87,6 +89,8 @@ runs: if: steps.retrieve-slack-thread-id.outcome == 'success' shell: bash run: | + set -euo pipefail + echo "SLACK_THREAD_ID=$(cat slack-thread-id)" | tee -a "$GITHUB_OUTPUT" - name: Provide message template variables @@ -98,6 +102,7 @@ runs: BUILD_RESULT: ${{ steps.valid_inputs.outputs.BUILD_RESULT }} FAILED_TESTS: ${{ steps.valid_inputs.outputs.FAILED_TESTS }} TEST_HEALTH: ${{ steps.valid_inputs.outputs.TEST_HEALTH }} + TEST_RESULT: ${{ steps.valid_inputs.outputs.TEST_RESULT }} NOTIFICATION_TYPE: ${{ steps.valid_inputs.outputs.NOTIFICATION_TYPE }} GITHUB_RUN_ATTEMPT: ${{ github.run_attempt }} GITHUB_SERVER_URL: ${{ github.server_url }} @@ -110,6 +115,8 @@ runs: MESSAGE_SUBJECT: ${{ inputs.message-subject }} shell: bash run: | + set -euo pipefail + export WORKFLOW_RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/attempts/${GITHUB_RUN_ATTEMPT}" if [ "$NOTIFICATION_TYPE" == "container-image-build" ]; then @@ -127,24 +134,24 @@ runs: export MESSAGE_COLOR=10c400 fi - export MESSAGE_TEXT="*$MESSAGE_SUBJECT* $MESSAGE_VERB (attempt $GITHUB_RUN_ATTEMPT)" + export MESSAGE_TEXT="*${MESSAGE_SUBJECT}* ${MESSAGE_VERB} (attempt ${GITHUB_RUN_ATTEMPT})" PAYLOAD=$(envsubst < "${GITHUB_ACTION_PATH}/templates/container-image-build/failure.tpl") echo -e "PAYLOAD< slack-thread-id - name: Store Slack Thread ID as Artifact diff --git a/send-slack-notification/templates/integration-test/success.tpl b/send-slack-notification/templates/integration-test/success.tpl index 7f6d8bc..af1de92 100644 --- a/send-slack-notification/templates/integration-test/success.tpl +++ b/send-slack-notification/templates/integration-test/success.tpl @@ -8,7 +8,7 @@ blocks: - type: "section" text: type: "mrkdwn" - text: "${HEALTH_SLACK_EMOJI} (${HEALTH_RATE}) The integration test for *${{ github.repository }}* succeeded." + text: "${HEALTH_SLACK_EMOJI} (${HEALTH_RATE}) The integration test for *${MESSAGE_SUBJECT}* succeeded." - type: "actions" elements: - type: button