diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6a3ccefdffee5..4c47f9109d2cf 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -98,7 +98,6 @@ /.gitlab/common/test_infra_version.yml @DataDog/agent-devx-loops @DataDog/agent-devx-infra /.gitlab/e2e/e2e.yml @DataDog/container-integrations @DataDog/agent-devx-loops -/.gitlab/e2e_k8s/e2e_k8s.yml @DataDog/container-integrations @DataDog/agent-devx-loops /.gitlab/e2e/install_packages @DataDog/agent-delivery /.gitlab/container_build/fakeintake.yml @DataDog/agent-e2e-testing @DataDog/agent-devx-loops /.gitlab/binary_build/fakeintake.yml @DataDog/agent-e2e-testing @DataDog/agent-devx-loops @@ -565,10 +564,6 @@ /test/ @DataDog/agent-devx-loops /test/benchmarks/ @DataDog/agent-metrics-logs /test/benchmarks/kubernetes_state/ @DataDog/container-integrations -/test/e2e/ @DataDog/container-integrations @DataDog/agent-security -/test/e2e/cws-tests/ @DataDog/agent-security -/test/e2e/argo-workflows/otlp-workflow.yaml @DataDog/opentelemetry -/test/e2e/containers/otlp_sender/ @DataDog/opentelemetry /test/integration/ @DataDog/container-integrations /test/integration/serverless @DataDog/serverless @Datadog/serverless-aws /test/integration/serverless_perf @DataDog/serverless @Datadog/serverless-aws diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1a8b2b131c090..ff332605fd12f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,7 +22,6 @@ include: - .gitlab/deps_fetch/deps_fetch.yml - .gitlab/dev_container_deploy/include.yml - .gitlab/e2e/e2e.yml - - .gitlab/e2e_k8s/e2e_k8s.yml - .gitlab/e2e_install_packages/include.yml - .gitlab/e2e_pre_test/e2e_pre_test.yml - .gitlab/functional_test/include.yml @@ -1034,6 +1033,15 @@ workflow: - when: manual allow_failure: true +.on_cspm_or_e2e_changes: + - !reference [.on_e2e_main_release_or_rc] + - changes: + paths: + - pkg/security/**/* + - test/new-e2e/tests/cspm/**/* #TODO: Add other paths that should trigger the execution of CSPM e2e tests + compare_to: main # TODO: use a variable, when this is supported https://gitlab.com/gitlab-org/gitlab/-/issues/369916 + when: on_success + .on_windows_systemprobe_or_e2e_changes: - !reference [.on_e2e_main_release_or_rc] - changes: diff --git a/.gitlab/e2e/e2e.yml b/.gitlab/e2e/e2e.yml index 985274966430d..b0d1bc93e9427 100644 --- a/.gitlab/e2e/e2e.yml +++ b/.gitlab/e2e/e2e.yml @@ -463,6 +463,19 @@ new-e2e-package-signing-suse-a7-x86_64: - .new-e2e_package_signing rules: !reference [.on_default_new_e2e_tests] +new-e2e-cspm: + extends: .new_e2e_template + rules: + - !reference [.on_cspm_or_e2e_changes] + - !reference [.manual] + needs: + - !reference [.needs_new_e2e_template] + - qa_agent + - qa_dca + variables: + TARGETS: ./tests/cspm + TEAM: cspm + generate-flakes-finder-pipeline: image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent-buildimages/deb_x64$DATADOG_AGENT_BUILDIMAGES_SUFFIX:$DATADOG_AGENT_BUILDIMAGES stage: e2e diff --git a/.gitlab/e2e_k8s/e2e_k8s.yml b/.gitlab/e2e_k8s/e2e_k8s.yml deleted file mode 100644 index 45ffd2171a413..0000000000000 --- a/.gitlab/e2e_k8s/e2e_k8s.yml +++ /dev/null @@ -1,70 +0,0 @@ - ---- -# e2e stage -# Jobs with the k8s_e2e template - -.k8s_e2e_template: - stage: e2e_k8s - image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent-buildimages/gitlab_agent_deploy$DATADOG_AGENT_BUILDIMAGES_SUFFIX:$DATADOG_AGENT_BUILDIMAGES - tags: ["arch:amd64"] - dependencies: [] - variables: - LANG: C.UTF-8 - before_script: - - DOCKER_REGISTRY_LOGIN=$($CI_PROJECT_DIR/tools/ci/fetch_secret.sh $DOCKER_REGISTRY_LOGIN) || exit $?; export DOCKER_REGISTRY_LOGIN - - DOCKER_REGISTRY_PWD=$($CI_PROJECT_DIR/tools/ci/fetch_secret.sh $DOCKER_REGISTRY_PWD) || exit $?; export DOCKER_REGISTRY_PWD - - DD_API_KEY=$($CI_PROJECT_DIR/tools/ci/fetch_secret.sh $API_KEY_DDDEV) || exit $?; export DD_API_KEY - -.k8s-e2e-cws-cspm-init: - - set +x - - export DATADOG_AGENT_SITE=datadoghq.com - - DATADOG_AGENT_API_KEY=$($CI_PROJECT_DIR/tools/ci/fetch_secret.sh $E2E_TESTS_API_KEY) || exit $?; export DATADOG_AGENT_API_KEY - - DATADOG_AGENT_APP_KEY=$($CI_PROJECT_DIR/tools/ci/fetch_secret.sh $E2E_TESTS_APP_KEY) || exit $?; export DATADOG_AGENT_APP_KEY - - DATADOG_AGENT_RC_KEY=$($CI_PROJECT_DIR/tools/ci/fetch_secret.sh $E2E_TESTS_RC_KEY) || exit $?; export DATADOG_AGENT_RC_KEY - -.k8s_e2e_template_needs_dev: - extends: .k8s_e2e_template - needs: - - dev_branch_multiarch-a7 - - dca_dev_branch - -.k8s_e2e_template_dev: - extends: .k8s_e2e_template_needs_dev - script: - - inv -e e2e-tests --agent-image=datadog/agent-dev:${CI_COMMIT_REF_SLUG}-py3 --dca-image=datadog/cluster-agent-dev:${CI_COMMIT_REF_SLUG} --argo-workflow=$ARGO_WORKFLOW - -.k8s_e2e_template_dev_with_cws_cspm_init: - extends: .k8s_e2e_template_needs_dev - script: - - !reference [.k8s-e2e-cws-cspm-init] - - inv -e e2e-tests --agent-image=datadog/agent-dev:${CI_COMMIT_REF_SLUG}-py3 --dca-image=datadog/cluster-agent-dev:${CI_COMMIT_REF_SLUG} --argo-workflow=$ARGO_WORKFLOW - -.k8s_e2e_template_needs_main: - extends: .k8s_e2e_template - needs: - - dev_master-a7 - - dca_dev_master - -.k8s_e2e_template_main_with_cws_cspm_init: - extends: .k8s_e2e_template_needs_main - script: - - !reference [.k8s-e2e-cws-cspm-init] - - inv -e e2e-tests --agent-image=datadog/agent-dev:master-py3 --dca-image=datadog/cluster-agent-dev:master --argo-workflow=$ARGO_WORKFLOW - -.k8s_e2e_template_main: - extends: .k8s_e2e_template_needs_main - script: - - inv -e e2e-tests --agent-image=datadog/agent-dev:master-py3 --dca-image=datadog/cluster-agent-dev:master --argo-workflow=$ARGO_WORKFLOW - -k8s-e2e-cspm-dev: - extends: .k8s_e2e_template_dev_with_cws_cspm_init - rules: !reference [.on_dev_branch_manual] - variables: - ARGO_WORKFLOW: cspm - -k8s-e2e-cspm-main: - extends: .k8s_e2e_template_main_with_cws_cspm_init - rules: !reference [.on_main] - retry: 1 - variables: - ARGO_WORKFLOW: cspm diff --git a/tasks/modules.py b/tasks/modules.py index 1ae393619d2df..276f8106a753d 100644 --- a/tasks/modules.py +++ b/tasks/modules.py @@ -283,9 +283,6 @@ def dependency_path(self, agent_version): "pkg/util/uuid": GoModule("pkg/util/uuid", independent=True), "pkg/util/winutil": GoModule("pkg/util/winutil", independent=True, used_by_otel=True), "pkg/version": GoModule("pkg/version", independent=True, used_by_otel=True), - "test/e2e/containers/otlp_sender": GoModule( - "test/e2e/containers/otlp_sender", condition=lambda: False, should_tag=False - ), "test/fakeintake": GoModule("test/fakeintake", independent=True), "test/new-e2e": GoModule( "test/new-e2e", diff --git a/test/e2e/README.md b/test/e2e/README.md deleted file mode 100644 index 5bf55766a9b76..0000000000000 --- a/test/e2e/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# End to End testing - -# ToC -- [How it works](#how-it-works) - * [Setup instance](#setup-instance) - * [Run instance](#run-instance) - * [Command line](#command-line) - * [AWS development](#aws-development) - * [Locally](#locally) -- [Argo workflow](#argo-workflow) - * [argo assertion](#argo-assertion) - * [argo container](#argo-container) -- [Upgrade](#upgrade---bump) - -# How it works - -There are 3 main directories: -- [argo-workflows](./argo-workflows) - Specification of the end to end testing - -- [containers](./containers) - Custom container images needed within the workflows - -- [scripts](./scripts) - - [`setup-instance`](./scripts/setup-instance) - Entrypoint and scripts dedicated for environments (locally, AWS dev, AWS gitlab) - - [`run-instance`](./scripts/run-instance) - Scripts executed in the argo-machine (locally, AWS instance) - -## `setup-instance` - - - -## `run-instance` - - - -## Command line - -### AWS development - -```bash -$ cd ${GOPATH}/src/github.com/DataDog/datadog-agent -$ aws-vault exec ${DEV} -- inv -e e2e-tests -t dev --agent-image datadog/agent-dev:master --dca-image datadog/cluster-agent-dev:master -``` - -### Locally (Linux only) - -```bash -$ inv -e e2e-tests -t local --agent-image datadog/agent-dev:master --dca-image datadog/cluster-agent-dev:master -``` - -# Argo workflow - -The argo documentation is available [here](https://argo-cd.readthedocs.io/en/stable/), there are a lot of examples [here](https://github.com/argoproj/argo/tree/master/examples) too. - -## Argo assertion - -To assert something in an argo workflow, you need to create a mongodb query: -```yaml -name: find-kubernetes-state-deployments -activeDeadlineSeconds: 200 -script: - image: mongo:3.6.3 - command: [mongo, "fake-datadog.default.svc.cluster.local/datadog"] - source: | - while (1) { - var nb = db.series.find({ - metric: "kubernetes_state.deployment.replicas_available", - tags: {$all: ["namespace:default", "deployment:fake-datadog"] }, - "points.0.1": { $eq: 1} }); - print("find: " + nb) - if (nb != 0) { - break; - } - prevNb = nb; - sleep(2000); - } -``` - -This is an infinite loop with a timeout set by `activeDeadlineSeconds: 200`. -The source is EOF to the command, equivalent to: -```bash -mongo "fake-datadog.default.svc.cluster.local/datadog" << EOF -while (1) -[...] -EOF -``` - -Try to maximise the usage of MongoDB query system without rewriting too much logic in JavaScript. - -See some examples [here](./containers/fake_datadog/README.md#find) - -To discover more MongoDB capabilities: -- [find](https://docs.mongodb.com/manual/tutorial/query-documents/) -- [aggregation](https://docs.mongodb.com/manual/aggregation/) - -## Argo container - -If you need to add a non existing public container in the workflow, create it in the [container directory](./containers). - -But, keep in mind this become an additional piece of software to maintain. - -# Upgrade - bump - -This section helps you to upgrade any part of the end to end testing. - -The current end to end testing pipeline relies on: -* [Argo](https://github.com/argoproj/argo) - -Upgrade Argo version by changing version in `test/e2e/scripts/run-instance/20-argo-download.sh` and setting new checksum value in `test/e2e/scripts/run-instance/argo.sha512sum` - -* [Kind](https://kind.sigs.k8s.io/) - -Upgrade Kind version by changing version in `test/e2e/scripts/run-instance/10-setup-kind.sh`. -By default Kind will use the latest stable Kubernetes known at the time of Kind release. - -* [Fedora CoreOS](https://getfedora.org/en/coreos?stream=stable) - -You don't need to update CoreOS version as the setup script (`test/e2e/scripts/setup-instance/00-entrypoint-[dev|gitlab].sh`) always uses the latest `stable` version by default. - -If needed, use the [ignition-linter](https://coreos.com/validate/) to validate any changes. diff --git a/test/e2e/argo-workflows/cspm-workflow.yaml b/test/e2e/argo-workflows/cspm-workflow.yaml deleted file mode 100644 index c124dbf807d74..0000000000000 --- a/test/e2e/argo-workflows/cspm-workflow.yaml +++ /dev/null @@ -1,121 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: argo-datadog-agent- -spec: - entrypoint: main - onExit: exit-handler - arguments: - parameters: - - name: datadog-agent-image-repository - - name: datadog-agent-image-tag - - name: datadog-agent-site - - name: datadog-cluster-agent-image-repository - - name: datadog-cluster-agent-image-tag - - name: ci_commit_short_sha - - name: ci_pipeline_id - - name: ci_job_id - volumes: - - name: datadog-agent-volume - hostPath: - path: /host/datadog-agent - - name: host-root-proc - hostPath: - path: /proc - templates: - - name: main - inputs: - parameters: - - name: datadog-agent-image-repository - - name: datadog-agent-image-tag - - name: datadog-agent-site - - name: datadog-cluster-agent-image-repository - - name: datadog-cluster-agent-image-tag - - name: ci_commit_short_sha - - name: ci_pipeline_id - - name: ci_job_id - steps: - - - name: start-fake-datadog - templateRef: - name: fake-datadog - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: start-dsd-hostname - templateRef: - name: dsd-hostname - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - - name: start-datadog-agent - templateRef: - name: datadog-agent - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - name: agent-image-repository - value: "{{inputs.parameters.datadog-agent-image-repository}}" - - name: agent-image-tag - value: "{{inputs.parameters.datadog-agent-image-tag}}" - - name: cluster-agent-image-repository - value: "{{inputs.parameters.datadog-cluster-agent-image-repository}}" - - name: cluster-agent-image-tag - value: "{{inputs.parameters.datadog-cluster-agent-image-tag}}" - - name: site - value: "{{inputs.parameters.datadog-agent-site}}" - - name: dd-url - value: "" - - name: ci_commit_short_sha - value: "{{inputs.parameters.ci_commit_short_sha}}" - - name: ci_pipeline_id - value: "{{inputs.parameters.ci_pipeline_id}}" - - name: ci_job_id - value: "{{inputs.parameters.ci_job_id}}" - - name: remote_configuration_enabled - value: "false" - - name: networkmonitoring_enabled - value: "false" - - - - name: wait-datadog-agent - templateRef: - name: datadog-agent - template: wait - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - - name: test-cspm-e2e - templateRef: - name: datadog-agent - template: test-cspm-e2e - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - name: site - value: "{{inputs.parameters.datadog-agent-site}}" - - - name: exit-handler - steps: - - - name: diagnose - template: diagnose - - - name: diagnose - steps: - - - name: diagnose-datadog-agent - templateRef: - name: datadog-agent - template: diagnose - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" diff --git a/test/e2e/argo-workflows/default-workflow.yaml b/test/e2e/argo-workflows/default-workflow.yaml deleted file mode 100644 index 9c9f54e30d89c..0000000000000 --- a/test/e2e/argo-workflows/default-workflow.yaml +++ /dev/null @@ -1,352 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: argo-datadog-agent- -spec: - entrypoint: main - onExit: exit-handler - arguments: - parameters: - - name: datadog-agent-image-repository - - name: datadog-agent-image-tag - - name: datadog-cluster-agent-image-repository - - name: datadog-cluster-agent-image-tag - - name: ci_commit_short_sha - - name: ci_pipeline_id - - name: ci_job_id - volumes: - - name: datadog-agent-volume - hostPath: - path: /host/datadog-agent - templates: - - name: main - inputs: - parameters: - - name: datadog-agent-image-repository - - name: datadog-agent-image-tag - - name: datadog-cluster-agent-image-repository - - name: datadog-cluster-agent-image-tag - - name: ci_commit_short_sha - - name: ci_pipeline_id - - name: ci_job_id - steps: - - - name: start-fake-datadog - templateRef: - name: fake-datadog - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: start-redis - templateRef: - name: redis - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: start-cpu-stress - templateRef: - name: cpu-stress - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: start-dsd-hostname - templateRef: - name: dsd-hostname - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: start-logs-hello-world - templateRef: - name: logs-hello-world - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: start-nginx - templateRef: - name: nginx - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - - name: fake-dd-reset - templateRef: - name: fake-datadog - template: reset - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - - name: start-datadog-agent - templateRef: - name: datadog-agent - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - name: agent-image-repository - value: "{{inputs.parameters.datadog-agent-image-repository}}" - - name: agent-image-tag - value: "{{inputs.parameters.datadog-agent-image-tag}}" - - name: dd-url - value: "http://fake-datadog.{{workflow.namespace}}.svc.cluster.local" - - name: site - value: "" - - name: cluster-agent-image-repository - value: "{{inputs.parameters.datadog-cluster-agent-image-repository}}" - - name: cluster-agent-image-tag - value: "{{inputs.parameters.datadog-cluster-agent-image-tag}}" - - name: ci_commit_short_sha - value: "{{inputs.parameters.ci_commit_short_sha}}" - - name: ci_pipeline_id - value: "{{inputs.parameters.ci_pipeline_id}}" - - name: ci_job_id - value: "{{inputs.parameters.ci_job_id}}" - - name: remote_configuration_enabled - value: "false" - - name: networkmonitoring_enabled - value: "false" - - - - name: wait-datadog-agent - templateRef: - name: datadog-agent - template: wait - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - - name: start-busybox - templateRef: - name: busybox - template: create - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - - name: test-datadog-agent - templateRef: - name: datadog-agent - template: test - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: test-redis - templateRef: - name: redis - template: test - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: test-cpu - templateRef: - name: cpu-stress - template: test - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: test-dsd - templateRef: - name: dsd-hostname - template: test - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: test-nginx - templateRef: - name: nginx - template: test - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: test-busybox - templateRef: - name: busybox - template: test - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - - name: stop-redis - templateRef: - name: redis - template: delete - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: stop-nginx - templateRef: - name: nginx - template: delete - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - - name: no-more-redis - templateRef: - name: redis - template: no-more-metrics - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: no-more-nginx - templateRef: - name: nginx - template: no-more-metrics - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: exit-handler - steps: - - - name: delete - template: delete - when: "{{workflow.status}} == Succeeded" - - - name: diagnose - template: diagnose - when: "{{workflow.status}} != Succeeded" - - - name: delete - steps: - - - name: stop-datadog-agent - templateRef: - name: datadog-agent - template: delete - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: stop-redis - templateRef: - name: redis - template: delete - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: stop-cpu-stress - templateRef: - name: cpu-stress - template: delete - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: stop-dsd-hostname - templateRef: - name: dsd-hostname - template: delete - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: stop-logs-hello-world - templateRef: - name: logs-hello-world - template: delete - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: stop-nginx - templateRef: - name: nginx - template: delete - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: stop-fake-datadog - templateRef: - name: fake-datadog - template: delete - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: stop-busybox - templateRef: - name: busybox - template: delete - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - - name: diagnose - steps: - - - name: diagnose-datadog-agent - templateRef: - name: datadog-agent - template: diagnose - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - name: diagnose-fake-datadog - templateRef: - name: fake-datadog - template: diagnose - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - name: diagnose-nginx - templateRef: - name: nginx - template: diagnose - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" - - name: diagnose-busybox - templateRef: - name: busybox - template: diagnose - arguments: - parameters: - - name: namespace - value: "{{workflow.namespace}}" diff --git a/test/e2e/argo-workflows/templates/cpu-stress.yaml b/test/e2e/argo-workflows/templates/cpu-stress.yaml deleted file mode 100644 index e210d9aa0eaf2..0000000000000 --- a/test/e2e/argo-workflows/templates/cpu-stress.yaml +++ /dev/null @@ -1,175 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: WorkflowTemplate -metadata: - name: cpu-stress -spec: - templates: - - name: create - inputs: - parameters: - - name: namespace - resource: - action: apply - manifest: | - apiVersion: apps/v1 - kind: Deployment - metadata: - name: cpu-stress - namespace: {{inputs.parameters.namespace}} - spec: - replicas: 1 - selector: - matchLabels: - app: cpu-stress - template: - metadata: - labels: - app: cpu-stress - spec: - containers: - - name: cpu-stress - image: datadog/docker-library:progrium_stress - args: - - "--cpu" - - "2" - resources: - requests: - memory: "64Mi" - cpu: "1" - limits: - memory: "64Mi" - cpu: "1" - - - name: delete - inputs: - parameters: - - name: namespace - resource: - action: delete - manifest: | - apiVersion: apps/v1 - kind: Deployment - metadata: - name: cpu-stress - namespace: {{inputs.parameters.namespace}} - - - name: find-metrics-cpu-container-runtime - inputs: - parameters: - - name: namespace - activeDeadlineSeconds: 300 - script: - image: mongo:4.4.1 - command: [mongo, "fake-datadog.{{inputs.parameters.namespace}}.svc.cluster.local/datadog"] - source: | - while (1) { - var nb = db.series.find({ - metric: "cri.cpu.usage", - tags: { $all: ["kube_deployment:cpu-stress", "kube_container_name:cpu-stress"] }, - "points.0.1": { $gt: 950000000, $lt: 1010000000 } }).count(); - print("find: " + nb) - if (nb != 0) { - print("cpu value in target range") - break; - } - sleep(2000); - } - - - name: find-metrics-cpu-kubelet - inputs: - parameters: - - name: namespace - activeDeadlineSeconds: 300 - script: - image: mongo:4.4.1 - command: [mongo, "fake-datadog.{{inputs.parameters.namespace}}.svc.cluster.local/datadog"] - source: | - while (1) { - var nb = db.series.find({ - metric: "kubernetes.cpu.usage.total", - tags: { $all: ["kube_deployment:cpu-stress", "kube_container_name:cpu-stress"] }, - "points.0.1": { $gt: 800000000, $lt: 1200000000 } }).count(); - print("find: " + nb) - if (nb != 0) { - print("cpu value in target range") - break; - } - sleep(2000); - } - - - name: find-metrics-cpu-system - inputs: - parameters: - - name: namespace - activeDeadlineSeconds: 300 - script: - image: mongo:4.4.1 - command: [mongo, "fake-datadog.{{inputs.parameters.namespace}}.svc.cluster.local/datadog"] - source: | - while (1) { - sleep(2000); - - // Determine the hostname the cpu-stress pod is running on - var point = db.series.find({ - metric: "kubernetes.cpu.usage.total", - tags: {$all: ["kube_deployment:cpu-stress", "kube_container_name:cpu-stress"]} - }).limit(1).sort({$natural:-1})[0]; - if (!point) { - print("cannot get hostname for pod"); - continue; - } - hostname = point.host; - - // Get the number of CPUs on that host - var point = db.series.find({ - metric: "kubernetes_state.node.cpu_capacity", - host: hostname - }).limit(1).sort({$natural:-1})[0]; - if (!point) { - print("cannot get cpu capacity for host " + hostname); - continue; - } - cpucount = point.points[0][1]; - print("cpu count: " + cpucount) - - // Get the user CPU usage, make sure it's above 39% non-normalized - var point = db.series.find({ - metric: "system.cpu.user", - host: hostname - }).limit(1).sort({$natural:-1})[0]; - if (!point) { - print("no system.cpu.usage metric reported for host " + hostname) - continue; - } - print("raw value: " + point.points[0][1]) - value = point.points[0][1] * cpucount; - print("cpu value: " + value) - if (value > 95) { - print("cpu value in target range"); - break; - } - } - - - name: test - inputs: - parameters: - - name: namespace - steps: - - - name: find-metrics-cpu-container-runtime - template: find-metrics-cpu-container-runtime - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: find-metrics-cpu-kubelet - template: find-metrics-cpu-kubelet - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: find-metrics-cpu-system - template: find-metrics-cpu-system - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" diff --git a/test/e2e/argo-workflows/templates/datadog-agent.yaml b/test/e2e/argo-workflows/templates/datadog-agent.yaml deleted file mode 100644 index 2c040444f3104..0000000000000 --- a/test/e2e/argo-workflows/templates/datadog-agent.yaml +++ /dev/null @@ -1,666 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: WorkflowTemplate -metadata: - name: datadog-agent -spec: - templates: - - name: create - inputs: - parameters: - - name: namespace - - name: dd-url - - name: site - - name: agent-image-repository - - name: agent-image-tag - - name: cluster-agent-image-repository - - name: cluster-agent-image-tag - - name: ci_commit_short_sha - - name: ci_pipeline_id - - name: ci_job_id - - name: remote_configuration_enabled - - name: networkmonitoring_enabled - script: - image: alpine/k8s:1.27.1 - envFrom: - - secretRef: - name: dd-keys - command: [sh] - source: | - set -euo pipefail - - cat > /tmp/values.yaml <& /dev/null - sleep 0.01 - done ) & - - until [[ "$(kubectl --namespace {{inputs.parameters.namespace}} get hpa nginxext -o jsonpath='{.status.currentReplicas}')" -gt 1 ]]; do - kubectl --namespace {{inputs.parameters.namespace}} describe hpa nginxext - sleep 1 - done - - - name: test - inputs: - parameters: - - name: namespace - dag: - tasks: - - name: find-kube-state-metrics - template: find-kube-state-metrics - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: find-metrics-nginx - template: find-metrics-nginx - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: validate-hpa - template: validate-hpa - dependencies: - - find-metrics-nginx - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: run-hpa - template: run-hpa - dependencies: - - validate-hpa - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - - name: no-more-metrics - inputs: - parameters: - - name: namespace - activeDeadlineSeconds: 300 - script: - image: mongo:4.4.1 - command: [mongo, "fake-datadog.{{inputs.parameters.namespace}}.svc.cluster.local/datadog"] - source: | - var prevNb = -1; - while (1) { - var nb = db.series.find({ - metric: {$regex: "nginx*"} - }).count(); - - print("prev-find: " + prevNb) - print("find: " + nb) - if (nb == prevNb) { - break; - } - prevNb = nb; - sleep(30000); - } - - - name: describe-hpa - inputs: - parameters: - - name: namespace - activeDeadlineSeconds: 300 - script: - image: alpine/k8s:1.27.1 - command: [sh] - source: | - set -euo pipefail - - kubectl --namespace {{inputs.parameters.namespace}} describe hpa nginxext - - - name: diagnose - inputs: - parameters: - - name: namespace - steps: - - - name: describe-hpa - template: describe-hpa - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" diff --git a/test/e2e/argo-workflows/templates/redis.yaml b/test/e2e/argo-workflows/templates/redis.yaml deleted file mode 100644 index df3cbf79ea615..0000000000000 --- a/test/e2e/argo-workflows/templates/redis.yaml +++ /dev/null @@ -1,366 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: WorkflowTemplate -metadata: - name: redis -spec: - templates: - - name: create-service - inputs: - parameters: - - name: namespace - resource: - action: apply - manifest: | - apiVersion: v1 - kind: Service - metadata: - name: redis - namespace: {{inputs.parameters.namespace}} - spec: - ports: - - port: 6379 - protocol: TCP - targetPort: 6379 - name: redis - selector: - app: redis - type: ClusterIP - - - name: create-deployment - inputs: - parameters: - - name: namespace - resource: - action: apply - manifest: | - apiVersion: apps/v1 - kind: Deployment - metadata: - name: redis - namespace: {{inputs.parameters.namespace}} - spec: - selector: - matchLabels: - app: redis - replicas: 1 - template: - metadata: - labels: - app: redis - annotations: - ad.datadoghq.com/redis.check_names: '["redisdb"]' - ad.datadoghq.com/redis.init_configs: '[{}]' - ad.datadoghq.com/redis.instances: '[{"host": "%%host%%", "port": "%%port%%"}]' - spec: - initContainers: - - name: useless - image: busybox:latest - command: - - /bin/true - resources: - requests: - memory: "32Mi" - cpu: "25m" - limits: - memory: "64Mi" - cpu: "50m" - containers: - - name: redis - image: redis - ports: - - name: redis - containerPort: 6379 - resources: - requests: - memory: "64Mi" - cpu: "50m" - limits: - memory: "128Mi" - cpu: "100m" - - - name: create-deployment-unready - inputs: - parameters: - - name: namespace - resource: - action: apply - manifest: | - apiVersion: apps/v1 - kind: Deployment - metadata: - name: redis-unready - namespace: {{inputs.parameters.namespace}} - spec: - replicas: 1 - selector: - matchLabels: - app: redis - template: - metadata: - labels: - app: redis - annotations: - ad.datadoghq.com/tolerate-unready: "true" - spec: - containers: - - name: redis-unready - image: redis - ports: - - name: redis - containerPort: 6379 - resources: - requests: - memory: "64Mi" - cpu: "50m" - limits: - memory: "128Mi" - cpu: "100m" - readinessProbe: - tcpSocket: - port: 8080 - initialDelaySeconds: 1 - periodSeconds: 1 - - - name: delete-service - inputs: - parameters: - - name: namespace - resource: - action: delete - manifest: | - apiVersion: v1 - kind: Service - metadata: - name: redis - namespace: {{inputs.parameters.namespace}} - - - name: delete-deployment - inputs: - parameters: - - name: namespace - resource: - action: delete - manifest: | - apiVersion: apps/v1 - kind: Deployment - metadata: - name: redis - namespace: {{inputs.parameters.namespace}} - - - name: delete-deployment-unready - inputs: - parameters: - - name: namespace - resource: - action: delete - manifest: | - apiVersion: apps/v1 - kind: Deployment - metadata: - name: redis-unready - namespace: {{inputs.parameters.namespace}} - - - name: create - inputs: - parameters: - - name: namespace - steps: - - - name: service - template: create-service - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: deployment - template: create-deployment - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: deployment-unready - template: create-deployment-unready - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - - name: delete - inputs: - parameters: - - name: namespace - steps: - - - name: service - template: delete-service - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: deployment - template: delete-deployment - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: deployment-unready - template: delete-deployment-unready - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - - name: find-kube-state-metrics - inputs: - parameters: - - name: namespace - activeDeadlineSeconds: 300 - script: - image: mongo:4.4.1 - command: [mongo, "fake-datadog.{{inputs.parameters.namespace}}.svc.cluster.local/datadog"] - source: | - // This step is intended to test end-to-end scraping of prometheus metrics - // by asserting the value of a few simple metrics collected from the - // kubernetes_state integration. - - while (1) { - var nb = db.series.find({ - metric: "kubernetes_state.deployment.replicas_available", - tags: { $all: ["kube_namespace:{{inputs.parameters.namespace}}", "kube_deployment:redis"] }, - "points.0.1": { $eq: 1 } }).count(); - print("find: " + nb) - if (nb != 0) { - break; - } - sleep(2000); - } - - - name: find-metrics-redis - inputs: - parameters: - - name: namespace - activeDeadlineSeconds: 300 - script: - image: mongo:4.4.1 - command: [mongo, "fake-datadog.{{inputs.parameters.namespace}}.svc.cluster.local/datadog"] - source: | - while (1) { - var nb = db.series.find({ - metric: {$regex: "redis*"} - }).count(); - - print("find: " + nb) - if (nb != 0) { - break; - } - sleep(2000); - } - - - name: find-metrics-redis-unready - inputs: - parameters: - - name: namespace - activeDeadlineSeconds: 300 - script: - image: mongo:4.4.1 - command: [mongo, "fake-datadog.{{inputs.parameters.namespace}}.svc.cluster.local/datadog"] - source: | - while (1) { - var nb = db.series.find({ - metric: {$regex: "redis*"}, - tags: {$all: ["kube_deployment:redis-unready", "kube_container_name:redis-unready"]} - }).count(); - - print("find: " + nb) - if (nb != 0) { - break; - } - sleep(2000); - } - - - name: find-metrics-redis-tagged - inputs: - parameters: - - name: namespace - activeDeadlineSeconds: 300 - script: - image: mongo:4.4.1 - command: [mongo, "fake-datadog.{{inputs.parameters.namespace}}.svc.cluster.local/datadog"] - source: | - while (1) { - var nb = db.series.find({ - metric: {$regex: "redis*"}, - tags: "kube_service:redis" - }).count(); - print("find: " + nb) - if (nb != 0) { - break; - } - sleep(2000); - } - - - name: test - inputs: - parameters: - - name: namespace - steps: - - - name: find-kube-state-metrics - template: find-kube-state-metrics - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: find-metrics-redis - template: find-metrics-redis - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: find-metrics-redis-unready - template: find-metrics-redis-unready - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - name: find-metrics-redis-tagged - template: find-metrics-redis-tagged - arguments: - parameters: - - name: namespace - value: "{{inputs.parameters.namespace}}" - - - name: no-more-metrics - inputs: - parameters: - - name: namespace - activeDeadlineSeconds: 300 - script: - image: mongo:4.4.1 - command: [mongo, "fake-datadog.{{inputs.parameters.namespace}}.svc.cluster.local/datadog"] - source: | - var prevNb = -1; - while (1) { - var nb = db.series.find({ - metric: {$regex: "redis*"} - }).count(); - - print("prev-find: " + prevNb) - print("find: " + nb) - if (nb == prevNb) { - break; - } - prevNb = nb; - sleep(30000); - } - var prevNb = -1 - while (1) { - var nb = db.check_run.find({check: "datadog.agent.check_status", - tags: "check:redisdb", - status: {$ne: 0}}).count(); - - print("prev-find: " + prevNb) - print("find: " + nb) - if (nb == prevNb) { - break; - } - prevNb = nb; - sleep(30000); - } diff --git a/test/e2e/containers/dsd_sender/Dockerfile b/test/e2e/containers/dsd_sender/Dockerfile deleted file mode 100644 index 1b6a5ae33c311..0000000000000 --- a/test/e2e/containers/dsd_sender/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM datadog/docker-library:python_2_7-alpine3_6 - -RUN pip install datadog - -COPY sender.py /sender.py - -CMD [ "python", "/sender.py" ] diff --git a/test/e2e/containers/dsd_sender/Makefile b/test/e2e/containers/dsd_sender/Makefile deleted file mode 100644 index bfdc5e51e0272..0000000000000 --- a/test/e2e/containers/dsd_sender/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -TAG?=latest - -default: build push - -build: - docker build --force-rm -t datadog/docker-library:e2e-dsd-sender_$(TAG) . - -push: - docker push datadog/docker-library:e2e-dsd-sender_$(TAG) diff --git a/test/e2e/containers/dsd_sender/sender.py b/test/e2e/containers/dsd_sender/sender.py deleted file mode 100644 index a589f38a6fa7b..0000000000000 --- a/test/e2e/containers/dsd_sender/sender.py +++ /dev/null @@ -1,23 +0,0 @@ -import time - -import datadog - -client = datadog.dogstatsd.base.DogStatsd(socket_path="/var/run/dogstatsd/dsd.socket") - -while True: - # Nominal case, dsd will inject its hostname - client.gauge('dsd.hostname.e2e', 1, tags=["case:nominal"]) - client.service_check('dsd.hostname.e2e', 0, tags=["case:nominal"]) - client.event('dsd.hostname.e2e', 'text', tags=["case:nominal"]) - - # Force the hostname value - client.gauge('dsd.hostname.e2e', 1, tags=["case:forced", "host:forced"]) - client.service_check('dsd.hostname.e2e', 0, tags=["case:forced"], hostname="forced") - client.event('dsd.hostname.e2e', 'text', tags=["case:forced"], hostname="forced") - - # Force an empty hostname - client.gauge('dsd.hostname.e2e', 1, tags=["case:empty", "host:"]) - client.service_check('dsd.hostname.e2e', 0, tags=["case:empty", "host:"]) - client.event('dsd.hostname.e2e', 'text', tags=["case:empty", "host:"]) - - time.sleep(10) diff --git a/test/e2e/containers/fake_datadog/Dockerfile b/test/e2e/containers/fake_datadog/Dockerfile deleted file mode 100644 index 451b008e217c8..0000000000000 --- a/test/e2e/containers/fake_datadog/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM python:3.9-alpine - -COPY app /opt/fake_datadog - -RUN apk update && \ - apk add python3-dev gcc g++ musl-dev libstdc++ && \ - pip install -r /opt/fake_datadog/requirements.txt && \ - apk del python3-dev gcc g++ musl-dev && \ - rm -rf /var/cache/apk/* - -VOLUME /opt/fake_datadog/recorded - -ENV prometheus_multiproc_dir "/var/lib/prometheus" - -CMD ["gunicorn", "--bind", "0.0.0.0:80", "--pythonpath", "/opt/fake_datadog", "api:app"] diff --git a/test/e2e/containers/fake_datadog/Makefile b/test/e2e/containers/fake_datadog/Makefile deleted file mode 100644 index 27bcd71329f18..0000000000000 --- a/test/e2e/containers/fake_datadog/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -TAG?=$(shell date '+%Y%m%d') - -.PHONY: venv pip build default push multiarch - -default: pip - -venv: - virtualenv venv -p python3 - -pip: venv - venv/bin/pip install -r app/requirements.txt - -build: - docker build --force-rm -t datadog/fake-datadog:$(TAG) . - -multiarch: - docker buildx build --platform linux/amd64,linux/arm64 -t datadog/fake-datadog:$(TAG) . --push - -push: - docker push datadog/fake-datadog:$(TAG) diff --git a/test/e2e/containers/fake_datadog/README.md b/test/e2e/containers/fake_datadog/README.md deleted file mode 100644 index efaf81bc96624..0000000000000 --- a/test/e2e/containers/fake_datadog/README.md +++ /dev/null @@ -1,240 +0,0 @@ -# fake_datadog - - -Expose the needed API to make the agent submit payloads. - - -#### API - -Prefer using mongo. - -Get all series: -```bash -curl ${SERVICE_IP}/records/series | jq . -``` - -Get all check_run: -```bash -curl ${SERVICE_IP}/records/check_run | jq . -``` - -Get all intake: -```bash -curl ${SERVICE_IP}/records/intake | jq . -``` - -#### MongoDB - -Explore: -```bash -docker run --rm -it --net=host mongo mongo ${SERVICE_IP}/datadog -``` -```bash -apt-get install -yqq mongodb-clients && mongo ${SERVICE_IP}/datadog -``` -```bash -> show collections -check_run -intake -series - -``` - -#### Find - -Find a metric: -```text -> db.series.findOne() - -{ - "_id" : ObjectId("5ab3e567cd9a72000912abad"), - "metric" : "datadog.agent.running", - "points" : [ - [ - 1521739111, - 1 - ] - ], - "tags" : null, - "host" : "haf", - "type" : "gauge", - "interval" : 0, - "source_type_name" : "System" -} -``` - -Find a metric by metric name: -```text -db.series.findOne({metric: "kubernetes.network.tx_errors"}) - -{ - "_id" : ObjectId("5ab4cca8c914b50008c10615"), - "metric" : "kubernetes.network.tx_errors", - "points" : [ - [ - 1521798304, - 0 - ] - ], - "tags" : [ - "kube_deployment:workflow-controller", - "kube_namespace:kube-system", - "kube_replica_set:workflow-controller-58bbf49865", - "pod_name:workflow-controller-58bbf49865-55xdz" - ], - "host" : "v1704", - "type" : "gauge", - "interval" : 0, - "source_type_name" : "System" -} -``` - -Advanced find: -```js -db.series.find({ - metric: "kubernetes.cpu.usage.total", - tags: { $all: ["kube_namespace:kube-system", "pod_name:kube-controller-manager"] } -}, {_id: 0}) // .count() -``` - -#### Aggregation pipeline - -Aggregate all tags for a metric: -```js -db.series.aggregate([ - { $match: { metric: "kubernetes.cpu.usage.total"} }, - { $project: {tags: 1} }, - { $unwind: "$tags" }, - { $group: {_id: "allTags", tags: {$addToSet: "$tags" } } } -]) -``` - -Aggregate all tags for a metric regex: -```js -db.series.aggregate([ - { $match: { metric: {$regex: "kubernetes*"} } }, - { $project: {tags: 1} }, - { $unwind: "$tags" }, - { $group: {_id: "allTags", tags: {$addToSet: "$tags" } } } -]) -``` - -Aggregate all tags for each metric matched by a regex: -```js -db.series.aggregate([ - { $match: { metric: {$regex: "kubernetes*"} } }, - { $project: { metric: 1, tags: 1 } }, - { $unwind: "$tags" }, - { $group: {_id: "$metric", tags: {$addToSet: "$tags" } } } -]) -``` - -Aggregate all metrics from a tag: -```js -db.series.aggregate([ - { $match: { tags: "kube_deployment:fake-app-datadog"} }, - { $group: { _id: "kube_deployment:fake-app-datadog", metrics: { $addToSet: "$metric" } } } -]) -``` - -Aggregate all metrics from tags ($or || $and): -```js -db.series.aggregate([ - { $match: { $or: [ - {tags: "kube_deployment:fake-app-datadog"}, - {tags: "kube_service:fake-app-datadog"} - ] } }, - { $group: { _id: "metricsToTags", metrics: { $addToSet: "$metric" } } } -]) -``` - -Aggregate a metric and a tag as timeseries: -```js -db.series.aggregate([ - { $match: { tags: "kube_deployment:dd", metric: "kubernetes.cpu.usage.total"} }, - { $unwind: "$points" }, - { $project: { - _id: { $arrayElemAt: [ "$points", 0 ] }, - value: { $arrayElemAt: [ "$points", 1 ] }, - tags: "$tags" - } - }, - { $sort: { _id: 1 } } -]) -``` - -Count tag occurrences on a given metric: -```js -db.series.aggregate([ - { $match: { metric: "kubernetes.filesystem.usage", tags: { $all: ["pod_name:fake-app-datadog-7cfb79db4d-dd4jr"] } } }, - { $project: {tags: 1} }, - { $unwind: "$tags" }, - { $group: {_id: "$tags", count: { $sum: 1 } } }, - { $sort: {count: -1} } -]) -``` - -#### Use standalone - -This tool can be used as a debug proxy to inspect agent payloads. Here is how to do it for Kubernetes. - -##### K8S -- run the following from within this folder: - -```console -docker build -t fake-datadog:latest . -docker tag fake-datadog:latest -docker push -# replace in fake-datadog.yaml before running the next command -kubectl apply -f fake-datadog.yaml -``` - -- edit your Datadog Agent Daemonset to use the service deployed above as the Datadog API. Be aware that each agent has its own intake - configuring `DD_DD_URL` doesn't cover the logs agent for example. - -```yaml -... - env: - ... - - name: DD_DD_URL - # if you deployed the service & deployment in a separate namespace, add `..svc.cluster.local - value: "http://fake-datadog" -``` - -##### Docker - -1. Create a `agent-docker-compose-extra.yaml` file to override url and V2 series environment variables - -```yaml -services: - agent: # use your agent service name here - environment: - DD_DD_URL: "http://fake-datadog" - DD_USE_V2_API_SERIES: false -``` - -- `agent` is the docker service name used for Datadog Agent. Rename it if you are using another service id. -- `DD_DD_URL` overrides the URL for metric submission -- `DD_USE_V2_API_SERIES` force using v1 APIs - -2. Run `docker compose up` passing datadog agent compose, agent extra compose and fake datadog compose - -```bash -docker compose up -f "${PATH_TO_AGENT_COMPOSE}.yaml" -f "fake-datadog.yaml" -f "agent-docker-compose-extra.yaml" -``` - -3. Query `datadog` on `mongo` service, reachable from host at `localhost:27017` and from another container at `mongo:27017` - -##### VM - -1. Create `fake-datadog` compose - -```bash -docker compose up -f "fake-datadog.yaml" -``` - -2. Configure the agent to send requests to `fake-datadog` using `V1` endpoint passing following environment variables - -```txt -DD_DD_URL="http://fake-datadog" -DD_USE_V2_API_SERIES=false -``` diff --git a/test/e2e/containers/fake_datadog/app/__init__.py b/test/e2e/containers/fake_datadog/app/__init__.py deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/test/e2e/containers/fake_datadog/app/api.py b/test/e2e/containers/fake_datadog/app/api.py deleted file mode 100644 index 37445ac6d0ae1..0000000000000 --- a/test/e2e/containers/fake_datadog/app/api.py +++ /dev/null @@ -1,334 +0,0 @@ -import json -import logging -import os -import sys -import zlib -from os import path - -import monitoring -import pymongo -from flask import Flask, Response, jsonify, request - -app = application = Flask("datadoghq") -monitoring.monitor_flask(app) -handler = logging.StreamHandler(sys.stderr) -app.logger.addHandler(handler) -app.logger.setLevel("INFO") - -record_dir = path.join(path.dirname(path.abspath(__file__)), "recorded") - - -def get_collection(name: str): - c = pymongo.MongoClient("127.0.0.1", 27017, connectTimeoutMS=5000) - db = c.get_database("datadog") - return db.get_collection(name) - - -payload_names = [ - "check_run", - "series", - "intake", - "logs", -] - - -def reset_records(): - for elt in payload_names: - to_remove = path.join(record_dir, elt) - if path.isfile(to_remove): - app.logger.warning("rm %s", to_remove) - os.remove(to_remove) - - try: - get_collection(elt).drop() - - except Exception as e: - app.logger.error(e) - - -def record_and_loads(filename: str, content_type: str, content_encoding: str, content: str): - """ - :param filename: - :param content_type: - :param content_encoding: - :param content: - :return: list or dict - """ - if content_type != "application/json": - app.logger.error("Unsupported content-type: %s", content_type) - raise TypeError(content_type) - - if content_encoding == "deflate": - content = zlib.decompress(content) - - content = content.decode() - content = f"{content}\n" if content[-1] != "\n" else content - with open(path.join(record_dir, filename), "a") as f: - f.write(content) - - return json.loads(content) - - -def patch_data(data, patch_key, patch_leaf): - if isinstance(data, dict): - return {patch_key(k): patch_data(v, patch_key, patch_leaf) for k, v in iter(data.items())} - elif isinstance(data, list): - return [patch_data(i, patch_key, patch_leaf) for i in data] - else: - return patch_leaf(data) - - -def fix_data(data): - return patch_data( - data, - # Whereas dot (.) and dollar ($) are valid characters inside a JSON dict key, - # they are not allowed as keys in a MongoDB BSON object. - # The official MongoDB documentation suggests to replace them with their - # unicode full width equivalent: - # https://docs.mongodb.com/v2.6/faq/developers/#dollar-sign-operator-escaping - patch_key=lambda x: x.translate(str.maketrans('.$', '\uff0e\uff04')), - # Values that cannot fit in a 64 bits integer must be represented as a float. - patch_leaf=lambda x: float(x) if isinstance(x, int) and x > 2**63 - 1 else x, - ) - - -def insert_series(data: dict): - coll = get_collection("series") - coll.insert_many(data["series"]) - - -def insert_intake(data: dict): - coll = get_collection("intake") - coll.insert_one(data) - - -def insert_check_run(data: list): - coll = get_collection("check_run") - coll.insert_many(data) - - -def insert_logs(data: list): - coll = get_collection("logs") - coll.insert_many(data) - - -def get_series_from_query(q: dict): - app.logger.info("Query is %s", q["query"]) - query = q["query"].replace("avg:", "") - first_open_brace, first_close_brace = query.index("{"), query.index("}") - - metric_name = query[:first_open_brace] - from_ts, to_ts = int(q["from"]), int(q["to"]) - - # tags - all_tags = query[first_open_brace + 1 : first_close_brace] - all_tags = all_tags.split(",") if all_tags else [] - - # group by - # TODO - last_open_brace, last_close_brace = query.rindex("{"), query.rindex("}") - group_by = query[last_open_brace + 1 : last_close_brace].split(",") # noqa: F841 - - match_conditions = [ - {"metric": metric_name}, - {"points.0.0": {"$gt": from_ts}}, - {"points.0.0": {"$lt": to_ts}}, - ] - if all_tags: - match_conditions.append({'tags': {"$all": all_tags}}) - - c = get_collection("series") - aggregate = [ - {"$match": {"$and": match_conditions}}, - {"$unwind": "$points"}, - {"$group": {"_id": "$metric", "points": {"$push": "$points"}}}, - {"$sort": {"points.0": 1}}, - ] - app.logger.info("Mongodb aggregate is %s", aggregate) - cur = c.aggregate(aggregate) - points_list = [] - for elt in cur: - for p in elt["points"]: - p[0] *= 1000 - points_list.append(p) - - result = { - "status": "ok", - "res_type": "time_series", - "series": [ - { - "metric": metric_name, - "attributes": {}, - "display_name": metric_name, - "unit": None, - "pointlist": points_list, - "end": points_list[-1][0] if points_list else 0.0, - "interval": 600, - "start": points_list[0][0] if points_list else 0.0, - "length": len(points_list), - "aggr": None, - "scope": "host:vagrant-ubuntu-trusty-64", # TODO - "expression": query, - } - ], - "from_date": from_ts, - "group_by": ["host"], - "to_date": to_ts, - "query": q["query"], - "message": "", - } - return result - - -@app.route("/api/v1/validate", methods=["GET"]) -def validate(): - return Response(status=200) - - -@app.route("/api/v1/query", methods=["GET"]) -def metrics_query(): - """ - Honor a query like documented here: - https://docs.datadoghq.com/api/?lang=bash#query-time-series-points - :return: - """ - if "query" not in request.args or "from" not in request.args or "to" not in request.args: - return Response(status=400) - - return jsonify(get_series_from_query(request.args)) - - -@app.route("/api/v1/series", methods=["POST"]) -def series(): - data = record_and_loads( - filename="series", - content_type=request.content_type, - content_encoding=request.content_encoding, - content=request.data, - ) - data = fix_data(data) - insert_series(data) - return Response(status=200) - - -@app.route("/api/v1/check_run", methods=["POST"]) -def check_run(): - data = record_and_loads( - filename="check_run", - content_type=request.content_type, - content_encoding=request.content_encoding, - content=request.data, - ) - data = fix_data(data) - insert_check_run(data) - return Response(status=200) - - -@app.route("/intake/", methods=["POST"]) -def intake(): - data = record_and_loads( - filename="intake", - content_type=request.content_type, - content_encoding=request.content_encoding, - content=request.data, - ) - data = fix_data(data) - insert_intake(data) - return Response(status=200) - - -@app.route("/v1/input/", methods=["POST"]) -def logs(): - data = record_and_loads( - filename="logs", - content_type=request.content_type, - content_encoding=request.content_encoding, - content=request.data, - ) - data = fix_data(data) - insert_logs(data) - return Response(status=200) - - -@app.route("/api/v2/orch", methods=["POST"]) -def orchestrator(): - # TODO - return Response(status=200) - - -@app.before_request -def logging(): - # use only if you need to check headers - # mind where the logs of this container go since headers contain an API key - # app.logger.info( - # "path: %s, method: %s, content-type: %s, content-encoding: %s, content-length: %s, headers: %s", - # request.path, request.method, request.content_type, request.content_encoding, request.content_length, request.headers) - app.logger.info( - "path: %s, method: %s, content-type: %s, content-encoding: %s, content-length: %s", - request.path, - request.method, - request.content_type, - request.content_encoding, - request.content_length, - ) - - -def stat_records(): - j = {} - for elt in payload_names: - try: - p = path.join(record_dir, elt) - st = os.stat(p) - lines = 0 - with open(p) as f: - for _ in f: - lines += 1 - j[elt] = {"size": st.st_size, "lines": lines} - - except FileNotFoundError: - j[elt] = {"size": -1, "lines": -1} - return j - - -@app.route("/_/records") -def available_records(): - return jsonify(stat_records()) - - -@app.route("/_/records/") -def get_records(name): - if name not in payload_names: - return Response(status=404) - - if path.isfile(path.join(record_dir, name)) is False: - return Response(status=503) - - payloads = [] - with open(path.join(record_dir, name)) as f: - for line in f: - payloads.append(json.loads(line)) - return json.dumps(payloads), 200 - - -@application.route('/', methods=['GET']) -def api_mapper(): - rules = [k.rule for k in application.url_map.iter_rules()] - rules = list(set(rules)) - rules.sort() - return jsonify(rules) - - -@application.route('/_/reset', methods=['POST']) -def reset(): - reset_records() - return jsonify(stat_records()) - - -@application.errorhandler(404) -def not_found(_): - app.logger.warning("404 %s %s", request.path, request.method) - return Response("404", status=404, mimetype="text/plain") - - -if __name__ == '__main__': - app.run(host="0.0.0.0", debug=True, port=5000) diff --git a/test/e2e/containers/fake_datadog/app/monitoring.py b/test/e2e/containers/fake_datadog/app/monitoring.py deleted file mode 100644 index 15ae0a1a9e3c8..0000000000000 --- a/test/e2e/containers/fake_datadog/app/monitoring.py +++ /dev/null @@ -1,74 +0,0 @@ -import os -import sys -import time - -from flask import Flask, Response, g, request -from prometheus_client import CONTENT_TYPE_LATEST, CollectorRegistry, Counter, Histogram, generate_latest, multiprocess - - -def extract_exception_name(exc_info=None): - """ - Function to get the exception name and module - :param exc_info: - :return: - """ - if not exc_info: - exc_info = sys.exc_info() - return f'{exc_info[0].__module__}.{exc_info[0].__name__}' - - -def monitor_flask(app: Flask): - """ - Add components to monitor each route with prometheus - The monitoring is available at /metrics - :param app: Flask application - :return: - """ - prometheus_state_dir = os.getenv('prometheus_multiproc_dir', "") - if "gunicorn" not in os.getenv("SERVER_SOFTWARE", "") and prometheus_state_dir == "": - return - - if os.path.isdir(prometheus_state_dir) is False: - os.mkdir(prometheus_state_dir) - - metrics = CollectorRegistry() - - def collect(): - registry = CollectorRegistry() - multiprocess.MultiProcessCollector(registry) - data = generate_latest(registry) - return Response(data, mimetype=CONTENT_TYPE_LATEST) - - app.add_url_rule('/metrics', 'metrics', collect) - - additional_kwargs = {'registry': metrics} - request_latency = Histogram( - 'requests_duration_seconds', 'Backend API request latency', ['method', 'path'], **additional_kwargs - ) - status_count = Counter( - 'responses_total', 'Backend API response count', ['method', 'path', 'status_code'], **additional_kwargs - ) - exception_latency = Histogram( - 'exceptions_duration_seconds', - 'Backend API top-level exception latency', - ['method', 'path', 'type'], - **additional_kwargs, - ) - - @app.before_request - def start_measure(): - g._start_time = time.time() - - @app.after_request - def count_status(response: Response): - status_count.labels(request.method, request.url_rule, response.status_code).inc() - request_latency.labels(request.method, request.url_rule).observe(time.time() - g._start_time) - return response - - # Override log_exception to increment the exception counter - def log_exception(exc_info): - class_name = extract_exception_name(exc_info) - exception_latency.labels(request.method, request.url_rule, class_name).observe(time.time() - g._start_time) - app.logger.error('Exception on %s [%s]', request.path, request.method, exc_info=exc_info) - - app.log_exception = log_exception diff --git a/test/e2e/containers/fake_datadog/app/requirements.txt b/test/e2e/containers/fake_datadog/app/requirements.txt deleted file mode 100644 index 146792ede7f30..0000000000000 --- a/test/e2e/containers/fake_datadog/app/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -Flask==2.1.2 -gunicorn==20.1.0 -pymongo==4.1.1 -prometheus-client==0.14.1 diff --git a/test/e2e/containers/fake_datadog/docker-compose.yaml b/test/e2e/containers/fake_datadog/docker-compose.yaml deleted file mode 100644 index eb4ff70532c8d..0000000000000 --- a/test/e2e/containers/fake_datadog/docker-compose.yaml +++ /dev/null @@ -1,13 +0,0 @@ -version: "3.9" -services: - fake-datadog: - image: "datadog/fake-datadog:20220621" - ports: - - "8080:80" - - "27017:27017" - container_name: fake-datadog - mongo: - image: "mongo:5.0" - container_name: mongo - network_mode: "service:fake-datadog" - diff --git a/test/e2e/containers/fake_datadog/fake-datadog.yaml b/test/e2e/containers/fake_datadog/fake-datadog.yaml deleted file mode 100644 index ceeceda9b3b60..0000000000000 --- a/test/e2e/containers/fake_datadog/fake-datadog.yaml +++ /dev/null @@ -1,46 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: fake-datadog -spec: - ports: - - port: 80 - protocol: TCP - targetPort: 80 - name: api - - port: 27017 - protocol: TCP - targetPort: 27017 - name: mongo - selector: - app: fake-datadog - type: ClusterIP - ---- - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: fake-datadog -spec: - replicas: 1 - selector: - matchLabels: - app: fake-datadog - strategy: - type: RollingUpdate - rollingUpdate: - maxSurge: 1 - maxUnavailable: 0 - template: - metadata: - labels: - app: fake-datadog - spec: - containers: - - name: api - image: - imagePullPolicy: Always - - name: mongo - image: mongo:3.6.3 - diff --git a/test/e2e/containers/otlp_sender/Dockerfile b/test/e2e/containers/otlp_sender/Dockerfile deleted file mode 100644 index 5613d30c6c642..0000000000000 --- a/test/e2e/containers/otlp_sender/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM alpine:latest as prep -RUN apk --update add ca-certificates - -FROM scratch -ARG USER_UID=10001 -USER ${USER_UID} -COPY --from=prep /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -COPY otlpsender / -EXPOSE 4317 55680 55679 -ENTRYPOINT ["/otlpsender"] -CMD ["--config", "/etc/otel/config.yaml"] diff --git a/test/e2e/containers/otlp_sender/Makefile b/test/e2e/containers/otlp_sender/Makefile deleted file mode 100644 index 880e85dfca46c..0000000000000 --- a/test/e2e/containers/otlp_sender/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -TAG?=latest - -default: push - -otlpsender: - GOOS=linux GOARCH=amd64 go build -o $@ ./cmd/sender - -docker-build: otlpsender - docker build --force-rm -t datadog/docker-library:e2e-otlp-sender_$(TAG) . - -push: docker-build - docker push datadog/docker-library:e2e-otlp-sender_$(TAG) diff --git a/test/e2e/containers/otlp_sender/cmd/sender/main.go b/test/e2e/containers/otlp_sender/cmd/sender/main.go deleted file mode 100644 index b30813cc7f789..0000000000000 --- a/test/e2e/containers/otlp_sender/cmd/sender/main.go +++ /dev/null @@ -1,79 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2021-present Datadog, Inc. - -// Program otlp_sender sends telemetry data defined in a given file -package main - -import ( - "log" - - "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/exporter" - "go.opentelemetry.io/collector/exporter/debugexporter" - "go.opentelemetry.io/collector/exporter/otlpexporter" - "go.opentelemetry.io/collector/exporter/otlphttpexporter" - "go.opentelemetry.io/collector/extension" - "go.opentelemetry.io/collector/otelcol" - "go.opentelemetry.io/collector/processor" - "go.opentelemetry.io/collector/receiver" - "go.uber.org/multierr" - - "github.com/DataDog/datadog-agent/tests/e2e/containers/otlp_sender/internal/filereceiver" -) - -func components() ( - otelcol.Factories, - error, -) { - var errs error - - extensions, err := extension.MakeFactoryMap() - errs = multierr.Append(errs, err) - - receivers, err := receiver.MakeFactoryMap( - filereceiver.NewFactory(), - ) - errs = multierr.Append(errs, err) - - exporters, err := exporter.MakeFactoryMap( - otlpexporter.NewFactory(), - otlphttpexporter.NewFactory(), - debugexporter.NewFactory(), - ) - errs = multierr.Append(errs, err) - - processors, err := processor.MakeFactoryMap() - errs = multierr.Append(errs, err) - - factories := otelcol.Factories{ - Extensions: extensions, - Receivers: receivers, - Processors: processors, - Exporters: exporters, - } - - return factories, errs -} - -func main() { - factories, err := components() - if err != nil { - log.Fatalf("failed to build components: %v", err) - } - - cmd := otelcol.NewCommand(otelcol.CollectorSettings{ - BuildInfo: component.BuildInfo{ - Command: "otlpsender", - Description: "OpenTelemetry test sender", - Version: "latest", - }, - Factories: func() (otelcol.Factories, error) { - return factories, nil - }, - }) - if err := cmd.Execute(); err != nil { - log.Fatalf("collector server run finished with error: %v", err) - } -} diff --git a/test/e2e/containers/otlp_sender/go.mod b/test/e2e/containers/otlp_sender/go.mod deleted file mode 100644 index 3ae057624be2d..0000000000000 --- a/test/e2e/containers/otlp_sender/go.mod +++ /dev/null @@ -1,109 +0,0 @@ -module github.com/DataDog/datadog-agent/tests/e2e/containers/otlp_sender - -go 1.22.0 - -require ( - go.opentelemetry.io/collector/component v0.104.0 - go.opentelemetry.io/collector/consumer v0.104.0 - go.opentelemetry.io/collector/exporter v0.104.0 - go.opentelemetry.io/collector/exporter/debugexporter v0.104.0 - go.opentelemetry.io/collector/exporter/otlpexporter v0.104.0 - go.opentelemetry.io/collector/exporter/otlphttpexporter v0.104.0 - go.opentelemetry.io/collector/extension v0.104.0 - go.opentelemetry.io/collector/otelcol v0.104.0 - go.opentelemetry.io/collector/pdata v1.11.0 - go.opentelemetry.io/collector/processor v0.104.0 - go.opentelemetry.io/collector/receiver v0.104.0 - go.uber.org/multierr v1.11.0 - go.uber.org/zap v1.27.0 -) - -require ( - github.com/beorn7/perks v1.0.1 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/knadh/koanf/maps v0.1.1 // indirect - github.com/knadh/koanf/providers/confmap v0.1.0 // indirect - github.com/knadh/koanf/v2 v2.1.1 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect - github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/mostynb/go-grpc-compression v1.2.3 // indirect - github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/prometheus/client_golang v1.19.1 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.54.0 // indirect - github.com/prometheus/procfs v0.15.0 // indirect - github.com/rs/cors v1.10.1 // indirect - github.com/shirou/gopsutil/v4 v4.24.5 // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect - github.com/spf13/cobra v1.8.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/tklauser/go-sysconf v0.3.12 // indirect - github.com/tklauser/numcpus v0.6.1 // indirect - github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/collector v0.104.0 // indirect - go.opentelemetry.io/collector/config/configauth v0.104.0 // indirect - go.opentelemetry.io/collector/config/configcompression v1.11.0 // indirect - go.opentelemetry.io/collector/config/configgrpc v0.104.0 // indirect - go.opentelemetry.io/collector/config/confighttp v0.104.0 // indirect - go.opentelemetry.io/collector/config/confignet v0.104.0 // indirect - go.opentelemetry.io/collector/config/configopaque v1.11.0 // indirect - go.opentelemetry.io/collector/config/configretry v1.11.0 // indirect - go.opentelemetry.io/collector/config/configtelemetry v0.104.0 // indirect - go.opentelemetry.io/collector/config/configtls v0.104.0 // indirect - go.opentelemetry.io/collector/config/internal v0.104.0 // indirect - go.opentelemetry.io/collector/confmap v0.104.0 // indirect - go.opentelemetry.io/collector/connector v0.104.0 // indirect - go.opentelemetry.io/collector/extension/auth v0.104.0 // indirect - go.opentelemetry.io/collector/featuregate v1.11.0 // indirect - go.opentelemetry.io/collector/semconv v0.104.0 // indirect - go.opentelemetry.io/collector/service v0.104.0 // indirect - go.opentelemetry.io/contrib/config v0.7.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.27.0 // indirect - go.opentelemetry.io/otel v1.27.0 // indirect - go.opentelemetry.io/otel/bridge/opencensus v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.49.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.27.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - go.opentelemetry.io/otel/sdk v1.27.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.27.0 // indirect - go.opentelemetry.io/proto/otlp v1.2.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/grpc v1.64.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git a/test/e2e/containers/otlp_sender/go.sum b/test/e2e/containers/otlp_sender/go.sum deleted file mode 100644 index 5f88f0d5eafab..0000000000000 --- a/test/e2e/containers/otlp_sender/go.sum +++ /dev/null @@ -1,344 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsMBaUOKXq6HSv655U1c= -github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/knadh/koanf/maps v0.1.1 h1:G5TjmUh2D7G2YWf5SQQqSiHRJEjaicvU0KpypqB3NIs= -github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= -github.com/knadh/koanf/providers/confmap v0.1.0 h1:gOkxhHkemwG4LezxxN8DMOFopOPghxRVp7JbIvdvqzU= -github.com/knadh/koanf/providers/confmap v0.1.0/go.mod h1:2uLhxQzJnyHKfxG927awZC7+fyHFdQkd697K4MdLnIU= -github.com/knadh/koanf/v2 v2.1.1 h1:/R8eXqasSTsmDCsAyYj+81Wteg8AqrV9CP6gvsTsOmM= -github.com/knadh/koanf/v2 v2.1.1/go.mod h1:4mnTRbZCK+ALuBXHZMjDfG9y714L7TykVnZkXbMU3Es= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= -github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mostynb/go-grpc-compression v1.2.3 h1:42/BKWMy0KEJGSdWvzqIyOZ95YcR9mLPqKctH7Uo//I= -github.com/mostynb/go-grpc-compression v1.2.3/go.mod h1:AghIxF3P57umzqM9yz795+y1Vjs47Km/Y2FE6ouQ7Lg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= -github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= -github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= -github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= -github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil/v4 v4.24.5 h1:gGsArG5K6vmsh5hcFOHaPm87UD003CaDMkAOweSQjhM= -github.com/shirou/gopsutil/v4 v4.24.5/go.mod h1:aoebb2vxetJ/yIDZISmduFvVNPHqXQ9SEJwRXxkf0RA= -github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= -github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= -github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= -github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= -github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/collector v0.104.0 h1:R3zjM4O3K3+ttzsjPV75P80xalxRbwYTURlK0ys7uyo= -go.opentelemetry.io/collector v0.104.0/go.mod h1:Tm6F3na9ajnOm6I5goU9dURKxq1fSBK1yA94nvUix3k= -go.opentelemetry.io/collector/component v0.104.0 h1:jqu/X9rnv8ha0RNZ1a9+x7OU49KwSMsPbOuIEykHuQE= -go.opentelemetry.io/collector/component v0.104.0/go.mod h1:1C7C0hMVSbXyY1ycCmaMUAR9fVwpgyiNQqxXtEWhVpw= -go.opentelemetry.io/collector/config/configauth v0.104.0 h1:ULtjugImijpKuLgGVt0E0HwiZT7+uDUEtMquh1ODB24= -go.opentelemetry.io/collector/config/configauth v0.104.0/go.mod h1:Til+nLLrQwwhgmfcGTX4ZRcNuMhdaWhBW1jH9DLTabQ= -go.opentelemetry.io/collector/config/configcompression v1.11.0 h1:oTwbcLh7mWHSDUIZXkRJVdNAMoBGS39XF68goTMOQq8= -go.opentelemetry.io/collector/config/configcompression v1.11.0/go.mod h1:6+m0GKCv7JKzaumn7u80A2dLNCuYf5wdR87HWreoBO0= -go.opentelemetry.io/collector/config/configgrpc v0.104.0 h1:E3RtqryQPOm/trJmhlJZj6cCqJNKgv9fOEQvSEpzsFM= -go.opentelemetry.io/collector/config/configgrpc v0.104.0/go.mod h1:tu3ifnJ5pv+4rZcaqNWfvVLjNKb8icSPoClN3THN8PU= -go.opentelemetry.io/collector/config/confighttp v0.104.0 h1:KSY0FSHSjuPyrR6iA2g5oFTozYFpYcy0ssJny8gTNTQ= -go.opentelemetry.io/collector/config/confighttp v0.104.0/go.mod h1:YgSXwuMYHANzzv+IBjHXaBMG/4G2mrseIpICHj+LB3U= -go.opentelemetry.io/collector/config/confignet v0.104.0 h1:i7AOTJf4EQox3SEt1YtQFQR+BwXr3v5D9x3Ai9/ovy8= -go.opentelemetry.io/collector/config/confignet v0.104.0/go.mod h1:pfOrCTfSZEB6H2rKtx41/3RN4dKs+X2EKQbw3MGRh0E= -go.opentelemetry.io/collector/config/configopaque v1.11.0 h1:Pt06PXWVmRaiSX63mzwT8Z9SV/hOc6VHNZbfZ10YY4o= -go.opentelemetry.io/collector/config/configopaque v1.11.0/go.mod h1:0xURn2sOy5j4fbaocpEYfM97HPGsiffkkVudSPyTJlM= -go.opentelemetry.io/collector/config/configretry v1.11.0 h1:UdEDD0ThxPU7+n2EiKJxVTvDCGygXu9hTfT6LOQv9DY= -go.opentelemetry.io/collector/config/configretry v1.11.0/go.mod h1:P+RA0IA+QoxnDn4072uyeAk1RIoYiCbxYsjpKX5eFC4= -go.opentelemetry.io/collector/config/configtelemetry v0.104.0 h1:eHv98XIhapZA8MgTiipvi+FDOXoFhCYOwyKReOt+E4E= -go.opentelemetry.io/collector/config/configtelemetry v0.104.0/go.mod h1:WxWKNVAQJg/Io1nA3xLgn/DWLE/W1QOB2+/Js3ACi40= -go.opentelemetry.io/collector/config/configtls v0.104.0 h1:bMmLz2+r+REpO7cDOR+srOJHfitqTZfSZCffDpKfwWk= -go.opentelemetry.io/collector/config/configtls v0.104.0/go.mod h1:e33o7TWcKfe4ToLFyGISEPGMgp6ezf3yHRGY4gs9nKk= -go.opentelemetry.io/collector/config/internal v0.104.0 h1:h3OkxTfXWWrHRyPEGMpJb4fH+54puSBuzm6GQbuEZ2o= -go.opentelemetry.io/collector/config/internal v0.104.0/go.mod h1:KjH43jsAUFyZPeTOz7GrPORMQCK13wRMCyQpWk99gMo= -go.opentelemetry.io/collector/confmap v0.104.0 h1:d3yuwX+CHpoyCh0iMv3rqb/vwAekjSm4ZDL6UK1nZSA= -go.opentelemetry.io/collector/confmap v0.104.0/go.mod h1:F8Lue+tPPn2oldXcfqI75PPMJoyzgUsKVtM/uHZLA4w= -go.opentelemetry.io/collector/connector v0.104.0 h1:Y82ytwZZ+EruWafEebO0dgWMH+TdkcSONEqZ5bm9JYA= -go.opentelemetry.io/collector/connector v0.104.0/go.mod h1:78SEHel3B3taFnSBg/syW4OV9aU1Ec9KjgbgHf/L8JA= -go.opentelemetry.io/collector/consumer v0.104.0 h1:Z1ZjapFp5mUcbkGEL96ljpqLIUMhRgQQpYKkDRtxy+4= -go.opentelemetry.io/collector/consumer v0.104.0/go.mod h1:60zcIb0W9GW0z9uJCv6NmjpSbCfBOeRUyrtEwqK6Hzo= -go.opentelemetry.io/collector/exporter v0.104.0 h1:C2HmnfBa05IQ2T+p9T7K7gXVxjrBLd+JxEtAWo7JNbg= -go.opentelemetry.io/collector/exporter v0.104.0/go.mod h1:Rx0oB0E4Ccg1JuAnEWwhtrq1ygRBkfx4mco1DpR3WaQ= -go.opentelemetry.io/collector/exporter/debugexporter v0.104.0 h1:1Z63H/xxv6IzMP7GPmI6v/lQAqZwYZCVC0rWYcYOomw= -go.opentelemetry.io/collector/exporter/debugexporter v0.104.0/go.mod h1:NHVzTM0Z/bomgR7SAe3ysx4CZzh2UJ3TXWSCnaOB1Wo= -go.opentelemetry.io/collector/exporter/otlpexporter v0.104.0 h1:EFOdhnc2yGhqou0Tud1HsM7fsgWo/H3tdQhYYytDprQ= -go.opentelemetry.io/collector/exporter/otlpexporter v0.104.0/go.mod h1:fAF7Q3Xh0OkxYWUycdrNNDXkyz3nhHIRKDkez0aQ6zg= -go.opentelemetry.io/collector/exporter/otlphttpexporter v0.104.0 h1:JkNCOj7DdyJhcYIaRqtS/X+YtAPRjE4pcruyY6LoM7c= -go.opentelemetry.io/collector/exporter/otlphttpexporter v0.104.0/go.mod h1:6rs4Xugs7tIC3IFbAC+fj56zLiVc7osXC5UTjk/Mkw4= -go.opentelemetry.io/collector/extension v0.104.0 h1:bftkgFMKya/QIwK+bOxEAPVs/TvTez+s1mlaiUznJkA= -go.opentelemetry.io/collector/extension v0.104.0/go.mod h1:x7K0KyM1JGrtLbafEbRoVp0VpGBHpyx9hu87bsja6S4= -go.opentelemetry.io/collector/extension/auth v0.104.0 h1:SelhccGCrqLThPlkbv6lbAowHsjgOTAWcAPz085IEC4= -go.opentelemetry.io/collector/extension/auth v0.104.0/go.mod h1:s3/C7LTSfa91QK0JPMTRIvH/gCv+a4DGiiNeTAX9OhI= -go.opentelemetry.io/collector/extension/zpagesextension v0.104.0 h1:rJ9Sw6DR27s6bW7lWBjJhjth5CXpltAHBKIgUFgVwFs= -go.opentelemetry.io/collector/extension/zpagesextension v0.104.0/go.mod h1:85Exj8r237PIvaXL1a/S0KeVNnm3kQNpVXtu0O2Zk5k= -go.opentelemetry.io/collector/featuregate v1.11.0 h1:Z7puIymKoQRm3oNM/NH8reWc2zRPz2PNaJvuokh0lQY= -go.opentelemetry.io/collector/featuregate v1.11.0/go.mod h1:PsOINaGgTiFc+Tzu2K/X2jP+Ngmlp7YKGV1XrnBkH7U= -go.opentelemetry.io/collector/otelcol v0.104.0 h1:RnMx7RaSFmX4dq/l3wbXWwcUnFK7RU19AM/0FbMr0Ig= -go.opentelemetry.io/collector/otelcol v0.104.0/go.mod h1:hWFRiHIKT3zbUx6SRevusPRa6mfm+70bPG5CK0glqSU= -go.opentelemetry.io/collector/pdata v1.11.0 h1:rzYyV1zfTQQz1DI9hCiaKyyaczqawN75XO9mdXmR/hE= -go.opentelemetry.io/collector/pdata v1.11.0/go.mod h1:IHxHsp+Jq/xfjORQMDJjSH6jvedOSTOyu3nbxqhWSYE= -go.opentelemetry.io/collector/pdata/pprofile v0.104.0 h1:MYOIHvPlKEJbWLiBKFQWGD0xd2u22xGVLt4jPbdxP4Y= -go.opentelemetry.io/collector/pdata/pprofile v0.104.0/go.mod h1:7WpyHk2wJZRx70CGkBio8klrYTTXASbyIhf+rH4FKnA= -go.opentelemetry.io/collector/pdata/testdata v0.104.0 h1:BKTZ7hIyAX5DMPecrXkVB2e86HwWtJyOlXn/5vSVXNw= -go.opentelemetry.io/collector/pdata/testdata v0.104.0/go.mod h1:3SnYKu8gLfxURJMWS/cFEUFs+jEKS6jvfqKXnOZsdkQ= -go.opentelemetry.io/collector/processor v0.104.0 h1:KSvMDu4DWmK1/k2z2rOzMtTvAa00jnTabtPEK9WOSYI= -go.opentelemetry.io/collector/processor v0.104.0/go.mod h1:qU2/xCCYdvVORkN6aq0H/WUWkvo505VGYg2eOwPvaTg= -go.opentelemetry.io/collector/receiver v0.104.0 h1:URL1ExkYYd+qbndm7CdGvI2mxzsv/pNfmwJ+1QSQ9/o= -go.opentelemetry.io/collector/receiver v0.104.0/go.mod h1:+enTCZQLf6dRRANWvykXEzrlRw2JDppXJtoYWd/Dd54= -go.opentelemetry.io/collector/semconv v0.104.0 h1:dUvajnh+AYJLEW/XOPk0T0BlwltSdi3vrjO7nSOos3k= -go.opentelemetry.io/collector/semconv v0.104.0/go.mod h1:yMVUCNoQPZVq/IPfrHrnntZTWsLf5YGZ7qwKulIl5hw= -go.opentelemetry.io/collector/service v0.104.0 h1:DTpkoX4C6qiA3v3cfB2cHv/cH705o5JI9J3P77SFUrE= -go.opentelemetry.io/collector/service v0.104.0/go.mod h1:eq68zgpqRDYaVp60NeRu973J0rA5vZJkezfw/EzxLXc= -go.opentelemetry.io/contrib/config v0.7.0 h1:b1rK5tGTuhhPirJiMxOcyQfZs76j2VapY6ODn3b2Dbs= -go.opentelemetry.io/contrib/config v0.7.0/go.mod h1:8tdiFd8N5etOi3XzBmAoMxplEzI3TcL8dU5rM5/xcOQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 h1:vS1Ao/R55RNV4O7TA2Qopok8yN+X0LIP6RVWLFkprck= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0/go.mod h1:BMsdeOxN04K0L5FNUBfjFdvwWGNe/rkmSwH4Aelu/X0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= -go.opentelemetry.io/contrib/propagators/b3 v1.27.0 h1:IjgxbomVrV9za6bRi8fWCNXENs0co37SZedQilP2hm0= -go.opentelemetry.io/contrib/propagators/b3 v1.27.0/go.mod h1:Dv9obQz25lCisDvvs4dy28UPh974CxkahRDUPsY7y9E= -go.opentelemetry.io/contrib/zpages v0.52.0 h1:MPgkMy0Cp3O5EdfVXP0ss3ujhEibysTM4eszx7E7d+E= -go.opentelemetry.io/contrib/zpages v0.52.0/go.mod h1:fqG5AFdoYru3A3DnhibVuaaEfQV2WKxE7fYE1jgDRwk= -go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= -go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= -go.opentelemetry.io/otel/bridge/opencensus v1.27.0 h1:ao9aGGHd+G4YfjBpGs6vbkvt5hoC67STlJA9fCnOAcs= -go.opentelemetry.io/otel/bridge/opencensus v1.27.0/go.mod h1:uRvWtAAXzyVOST0WMPX5JHGBaAvBws+2F8PcC5gMnTk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 h1:QY7/0NeRPKlzusf40ZE4t1VlMKbqSNT7cJRYzWuja0s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0/go.mod h1:HVkSiDhTM9BoUJU8qE6j2eSWLLXvi1USXjyd2BXT8PY= -go.opentelemetry.io/otel/exporters/prometheus v0.49.0 h1:Er5I1g/YhfYv9Affk9nJLfH/+qCCVVg1f2R9AbJfqDQ= -go.opentelemetry.io/otel/exporters/prometheus v0.49.0/go.mod h1:KfQ1wpjf3zsHjzP149P4LyAwWRupc6c7t1ZJ9eXpKQM= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.27.0 h1:/jlt1Y8gXWiHG9FBx6cJaIC5hYx5Fe64nC8w5Cylt/0= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.27.0/go.mod h1:bmToOGOBZ4hA9ghphIc1PAf66VA8KOtsuy3+ScStG20= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0 h1:/0YaXu3755A/cFbtXp+21lkXgI0QE5avTWA2HjU9/WE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.27.0/go.mod h1:m7SFxp0/7IxmJPLIY3JhOcU9CoFzDaCPL6xxQIxhA+o= -go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= -go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= -go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= -go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= -go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= -go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= -go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= -go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= -go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= -go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= -gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 h1:Q2RxlXqh1cgzzUgV261vBO2jI5R/3DD1J2pM0nI4NhU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/test/e2e/containers/otlp_sender/internal/filereceiver/factory.go b/test/e2e/containers/otlp_sender/internal/filereceiver/factory.go deleted file mode 100644 index 29864597b910a..0000000000000 --- a/test/e2e/containers/otlp_sender/internal/filereceiver/factory.go +++ /dev/null @@ -1,157 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2021-present Datadog, Inc. - -// Package filereceiver implements a receiver that reads OTLP metrics from a given file. -package filereceiver - -import ( - "bufio" - "context" - "errors" - "fmt" - "log" - "os" - "time" - - "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/consumer" - "go.opentelemetry.io/collector/pdata/pmetric" - collectorreceiver "go.opentelemetry.io/collector/receiver" - - "go.uber.org/zap" -) - -const typeStr = "file" - -// NewFactory creates a new OTLP receiver factory. -func NewFactory() collectorreceiver.Factory { - cfgType, _ := component.NewType(typeStr) - return collectorreceiver.NewFactory( - cfgType, - createDefaultConfig, - collectorreceiver.WithMetrics(createMetricsReceiver, component.StabilityLevelAlpha), - ) -} - -// Config of filereceiver. -type Config struct { - collectorreceiver.Settings `mapstructure:",squash"` - // Path of metrics data. - Path string `mapstructure:"path"` - // LoopConfig is the loop configuration. - Loop LoopConfig `mapstructure:"loop"` -} - -// LoopConfig is the loop configuration. -type LoopConfig struct { - // Enabled states whether the feature is enabled. - Enabled bool `mapstructure:"enabled"` - // Period defines the loop period. - Period time.Duration `mapstructure:"period"` -} - -// Validate configuration of receiver. -func (cfg *Config) Validate() error { - if cfg.Path == "" { - return errors.New("path can't be empty") - } - return nil -} - -func createDefaultConfig() component.Config { - cfgType, _ := component.NewType(typeStr) - return &Config{ - Settings: collectorreceiver.Settings{ - ID: component.NewID(cfgType), - }, - Loop: LoopConfig{Enabled: false, Period: 10 * time.Second}, - } -} - -var _ collectorreceiver.Metrics = (*receiver)(nil) - -type receiver struct { - config *Config - logger *zap.Logger - unmarshaler pmetric.Unmarshaler - nextConsumer consumer.Metrics - stopCh chan struct{} -} - -func (r *receiver) Start(_ context.Context, host component.Host) error { - if r.config.Loop.Enabled { - r.logger.Info("Running in a loop") - go r.unmarshalLoop(host) - } else { - r.logger.Info("Running just once") - go r.unmarshalAndSend(host) - } - return nil -} - -func (r *receiver) unmarshalAndSend(_ component.Host) { - file, err := os.Open(r.config.Path) - if err != nil { - log.Fatal(fmt.Errorf("failed to open %q: %w", r.config.Path, err)) - return - } - - r.logger.Info("Sending metrics batch") - scanner := bufio.NewScanner(file) - for scanner.Scan() { - metrics, err := r.unmarshaler.UnmarshalMetrics(scanner.Bytes()) - if err != nil { - log.Fatal(fmt.Errorf("failed to unmarshal %q: %w", r.config.Path, err)) - return - } - - err = r.nextConsumer.ConsumeMetrics(context.Background(), metrics) - if err != nil { - log.Fatal(fmt.Errorf("failed to send %q: %w", r.config.Path, err)) - return - } - } - - if err := scanner.Err(); err != nil { - log.Fatal(fmt.Errorf("failed to scan %q: %w", r.config.Path, err)) - return - } - - if err := file.Close(); err != nil { - log.Fatal(fmt.Errorf("failed to close %q: %w", r.config.Path, err)) - return - } -} - -func (r *receiver) unmarshalLoop(host component.Host) { - for { - r.unmarshalAndSend(host) - select { - case <-time.After(r.config.Loop.Period): - case <-r.stopCh: - return - } - } -} - -func (r *receiver) Shutdown(context.Context) error { - close(r.stopCh) - return nil -} - -func createMetricsReceiver( - _ context.Context, - set collectorreceiver.Settings, - cfg component.Config, - consumer consumer.Metrics, -) (collectorreceiver.Metrics, error) { - return &receiver{ - config: cfg.(*Config), - logger: set.Logger, - unmarshaler: &pmetric.JSONUnmarshaler{}, - nextConsumer: consumer, - stopCh: make(chan struct{}), - }, nil -} diff --git a/test/e2e/cws-tests/README.md b/test/e2e/cws-tests/README.md deleted file mode 100644 index 5008231122df1..0000000000000 --- a/test/e2e/cws-tests/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# CSPM e2e tests - -## Docker flavors - -To run docker flavoured tests, local only, please run: - -For CSPM: -```sh -DD_API_KEY= \ -DD_APP_KEY= \ -DD_SITE=datadoghq.com \ -DD_AGENT_IMAGE=datadog/agent-dev:master \ -python3 tests/test_e2e_cspm_docker.py -``` - -Please change `DD_AGENT_IMAGE` to a branch specific tag if you need to test a specific branch. diff --git a/test/e2e/cws-tests/requirements.txt b/test/e2e/cws-tests/requirements.txt deleted file mode 100644 index cc9857c383b50..0000000000000 --- a/test/e2e/cws-tests/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -kubernetes==30.1.0 -datadog-api-client==2.27.0 -pyaml==24.7.0 -docker==7.1.0 -retry==0.9.2 -emoji==2.12.1 -requests==2.32.3 -jsonschema==4.23.0 \ No newline at end of file diff --git a/test/e2e/cws-tests/tests/lib/__init__.py b/test/e2e/cws-tests/tests/lib/__init__.py deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/test/e2e/cws-tests/tests/lib/common/app.py b/test/e2e/cws-tests/tests/lib/common/app.py deleted file mode 100644 index 37a8dd8b5829d..0000000000000 --- a/test/e2e/cws-tests/tests/lib/common/app.py +++ /dev/null @@ -1,31 +0,0 @@ -import time - -from datadog_api_client.v1 import ApiClient, Configuration -from datadog_api_client.v1.api.metrics_api import MetricsApi -from retry.api import retry_call - - -class App: - def __init__(self): - self.v1_api_client = ApiClient(Configuration()) - - def query_metric(self, name, **kw): - api_instance = MetricsApi(self.v1_api_client) - - tags = [] - for key, value in kw.items(): - tags.append(f"{key}:{value}") - if len(tags) == 0: - tags.append("*") - - response = api_instance.query_metrics(int(time.time()) - 30, int(time.time()), f"{name}{{{','.join(tags)}}}") - return response - - def wait_for_metric(self, name, tries=30, delay=10, **kw): - def expect_metric(): - metric = self.query_metric(name, **kw) - if len(metric.get("series")) == 0: - raise LookupError(f"no value found in {metric}") - return metric - - return retry_call(expect_metric, tries=tries, delay=delay) diff --git a/test/e2e/cws-tests/tests/lib/config.py b/test/e2e/cws-tests/tests/lib/config.py deleted file mode 100644 index 6051bee608045..0000000000000 --- a/test/e2e/cws-tests/tests/lib/config.py +++ /dev/null @@ -1,45 +0,0 @@ -import tempfile - -import yaml - - -def gen_system_probe_config(npm_enabled=False, rc_enabled=False, log_level="INFO", log_patterns=None): - fp = tempfile.NamedTemporaryFile(prefix="e2e-system-probe-", mode="w", delete=False) - - if not log_patterns: - log_patterns = [] - - data = { - "system_probe_config": {"log_level": log_level}, - "network_config": {"enabled": npm_enabled}, - "runtime_security_config": { - "log_patterns": log_patterns, - "network": {"enabled": True}, - "remote_configuration": {"enabled": rc_enabled, "refresh_interval": "5s"}, - }, - } - - yaml.dump(data, fp) - fp.close() - - return fp.name - - -def gen_datadog_agent_config(hostname="myhost", log_level="INFO", tags=None, rc_enabled=False, rc_key=None): - fp = tempfile.NamedTemporaryFile(prefix="e2e-datadog-agent-", mode="w", delete=False) - - if not tags: - tags = [] - - data = { - "log_level": log_level, - "hostname": hostname, - "tags": tags, - "security_agent.remote_workloadmeta": True, - "remote_configuration": {"enabled": rc_enabled, "refresh_interval": "5s", "key": rc_key}, - } - - yaml.dump(data, fp) - fp.close() - - return fp.name diff --git a/test/e2e/cws-tests/tests/lib/const.py b/test/e2e/cws-tests/tests/lib/const.py deleted file mode 100644 index 7dc3c90a1d31c..0000000000000 --- a/test/e2e/cws-tests/tests/lib/const.py +++ /dev/null @@ -1,3 +0,0 @@ -SECURITY_START_LOG = "Successfully connected to the runtime security module" -SYS_PROBE_START_LOG = "runtime security started" -SEC_AGENT_PATH = "/opt/datadog-agent/embedded/bin/security-agent" diff --git a/test/e2e/cws-tests/tests/lib/cspm/api.py b/test/e2e/cws-tests/tests/lib/cspm/api.py deleted file mode 100644 index a139c99ab9a3b..0000000000000 --- a/test/e2e/cws-tests/tests/lib/cspm/api.py +++ /dev/null @@ -1,56 +0,0 @@ -import os - -import lib.common.app as common -import requests -from retry.api import retry_call - - -def aggregate_logs(query, track): - site = os.environ["DD_SITE"] - api_key = os.environ["DD_API_KEY"] - app_key = os.environ["DD_APP_KEY"] - - url = f"https://api.{site}/api/v2/logs/analytics/aggregate?type={track}" - body = { - "compute": [{"aggregation": "count", "type": "total"}], - "filter": { - "from": "now-3m", - "to": "now", - "query": query, - }, - } - - r = requests.post( - url, - headers={"DD-API-KEY": api_key, "DD-APPLICATION-KEY": app_key}, - json=body, - ) - api_response = r.json() - if not api_response["data"] or not api_response["data"]["buckets"]: - raise LookupError(query) - - count = api_response["data"]["buckets"][0]["computes"]["c0"] - if count == 0: - raise LookupError(query) - - return api_response - - -def fetch_app_findings(query): - return aggregate_logs(query, track="cpfinding") - - -def fetch_app_compliance_event(query): - return aggregate_logs(query, track="compliance") - - -def wait_for_findings(query, tries=30, delay=5): - return retry_call(fetch_app_findings, fargs=[query], tries=tries, delay=delay) - - -def wait_for_compliance_event(query, tries=30, delay=5): - return retry_call(fetch_app_compliance_event, fargs=[query], tries=tries, delay=delay) - - -class App(common.App): - pass diff --git a/test/e2e/cws-tests/tests/lib/cspm/finding.py b/test/e2e/cws-tests/tests/lib/cspm/finding.py deleted file mode 100644 index e3a7839cc3f52..0000000000000 --- a/test/e2e/cws-tests/tests/lib/cspm/finding.py +++ /dev/null @@ -1,27 +0,0 @@ -import json - - -def extract_findings(lines): - if not lines: - return [] - - res_lines = ["["] - for line in lines: - if line == "}": - res_lines.append("},") - else: - res_lines.append(line) - res_lines.pop() - res_lines.extend(["}", "]"]) - return json.loads("".join(res_lines)) - - -def is_subset(subset, superset): - if isinstance(subset, dict): - return all(key in superset and is_subset(val, superset[key]) for key, val in subset.items()) - - if isinstance(subset, list) or isinstance(subset, set): - return all(any(is_subset(subitem, superitem) for superitem in superset) for subitem in subset) - - # assume that subset is a plain value if none of the above match - return subset == superset diff --git a/test/e2e/cws-tests/tests/lib/docker.py b/test/e2e/cws-tests/tests/lib/docker.py deleted file mode 100644 index 40047900f968e..0000000000000 --- a/test/e2e/cws-tests/tests/lib/docker.py +++ /dev/null @@ -1,154 +0,0 @@ -import os -import tarfile -import tempfile - -import docker -from retry.api import retry_call - -from lib.const import SEC_AGENT_PATH -from lib.log import LogGetter - - -def is_container_running(container): - container.reload() - if container.status != "running": - raise Exception - - -class DockerHelper(LogGetter): - def __init__(self): - self.client = docker.from_env() - - self.agent_container = None - - def start_cspm_agent(self, image, datadog_agent_config=None): - volumes = [ - "/var/run/docker.sock:/var/run/docker.sock:ro", - "/proc/:/host/proc/:ro", - "/sys/fs/cgroup/:/host/sys/fs/cgroup:ro", - "/etc/passwd:/etc/passwd:ro", - "/etc/os-release:/host/etc/os-release:ro", - "/:/host/root:ro", - ] - - if datadog_agent_config: - volumes.append(f"{datadog_agent_config}:/etc/datadog-agent/datadog.yaml") - - site = os.environ["DD_SITE"] - api_key = os.environ["DD_API_KEY"] - - self.agent_container = self.client.containers.run( - image, - environment=[ - "DD_COMPLIANCE_CONFIG_ENABLED=true", - "HOST_ROOT=/host/root", - f"DD_SITE={site}", - f"DD_API_KEY={api_key}", - ], - volumes=volumes, - detach=True, - ) - - return self.agent_container - - def start_cws_agent(self, image, datadog_agent_config=None, system_probe_config=None): - volumes = [ - "/var/run/docker.sock:/var/run/docker.sock:ro", - "/proc/:/host/proc/:ro", - "/sys/fs/cgroup/:/host/sys/fs/cgroup:ro", - "/etc/passwd:/etc/passwd:ro", - "/etc/group:/etc/group:ro", - "/:/host/root:ro", - "/sys/kernel/debug:/sys/kernel/debug", - "/etc/os-release:/etc/os-release", - ] - - if datadog_agent_config: - volumes.append(f"{datadog_agent_config}:/etc/datadog-agent/datadog.yaml") - - if system_probe_config: - volumes.append(f"{system_probe_config}:/etc/datadog-agent/system-probe.yaml") - - site = os.environ["DD_SITE"] - api_key = os.environ["DD_API_KEY"] - - self.agent_container = self.client.containers.run( - image, - cap_add=["SYS_ADMIN", "SYS_RESOURCE", "SYS_PTRACE", "NET_ADMIN", "IPC_LOCK"], - security_opt=["apparmor:unconfined"], - environment=[ - "DD_RUNTIME_SECURITY_CONFIG_ENABLED=true", - "DD_SYSTEM_PROBE_ENABLED=true", - "HOST_ROOT=/host/root", - f"DD_SITE={site}", - f"DD_API_KEY={api_key}", - ], - volumes=volumes, - detach=True, - ) - - return self.agent_container - - def download_policies(self): - command = SEC_AGENT_PATH + " runtime policy download" - site = os.environ["DD_SITE"] - api_key = os.environ["DD_API_KEY"] - app_key = os.environ["DD_APP_KEY"] - return self.agent_container.exec_run( - command, - stderr=False, - stdout=True, - stream=False, - environment=[ - f"DD_SITE={site}", - f"DD_API_KEY={api_key}", - f"DD_APP_KEY={app_key}", - ], - ) - - def push_policies(self, policies): - temppolicy = tempfile.NamedTemporaryFile(prefix="e2e-policy-", mode="w", delete=False) - temppolicy.write(policies) - temppolicy.close() - temppolicy_path = temppolicy.name - self.cp_file(temppolicy_path, "/etc/datadog-agent/runtime-security.d/default.policy") - os.remove(temppolicy_path) - - def cp_file(self, src, dst): - tar = tarfile.open(src + '.tar', mode='w') - try: - tar.add(src) - finally: - tar.close() - data = open(src + '.tar', 'rb').read() - self.agent_container.put_archive("/tmp", data) - self.agent_container.exec_run("mv /tmp/" + src + " " + dst) - - def reload_policies(self): - self.agent_container.exec_run(SEC_AGENT_PATH + " runtime policy reload") - - def wait_agent_container(self, tries=10, delay=5): - return retry_call(is_container_running, fargs=[self.agent_container], tries=tries, delay=delay) - - def get_log(self, agent_name): - log_prefix = None - if agent_name == "security-agent": - log_prefix = "SECURITY" - elif agent_name == "system-probe": - log_prefix = "SYS-PROBE" - else: - raise LookupError(agent_name) - - log = self.agent_container.logs(since=1).decode("utf-8") - - result = [line for line in log.splitlines() if log_prefix in line] - if result: - return result - raise LookupError(agent_name) - - def close(self): - if self.agent_container: - self.agent_container.stop() - self.agent_container.remove() - - self.client.close() diff --git a/test/e2e/cws-tests/tests/lib/kubernetes.py b/test/e2e/cws-tests/tests/lib/kubernetes.py deleted file mode 100644 index 6d5e4267150e2..0000000000000 --- a/test/e2e/cws-tests/tests/lib/kubernetes.py +++ /dev/null @@ -1,123 +0,0 @@ -import os -import tarfile -import tempfile - -from kubernetes import client, config -from kubernetes.stream import stream - -from lib.const import SEC_AGENT_PATH -from lib.log import LogGetter - - -class KubernetesHelper(LogGetter): - def __init__(self, namespace, in_cluster=False): - if in_cluster: - config.load_incluster_config() - else: - config.load_kube_config() - - self.api_client = client.CoreV1Api() - - self.namespace = namespace - self.pod_name = None - - def select_pod_name(self, label_selector): - resp = self.api_client.list_namespaced_pod(namespace=self.namespace, label_selector=label_selector) - for i in resp.items: - self.pod_name = i.metadata.name - return - raise LookupError(label_selector) - - def get_log(self, agent_name): - log = self.api_client.read_namespaced_pod_log( - name=self.pod_name, namespace=self.namespace, container=agent_name, follow=False, tail_lines=10000 - ) - - return log.splitlines() - - def exec_command(self, container, command=None): - if not command: - command = [] - - return stream( - self.api_client.connect_post_namespaced_pod_exec, - name=self.pod_name, - namespace=self.namespace, - container=container, - command=command, - stderr=False, - stdin=False, - stdout=True, - tty=False, - ) - - def reload_policies(self): - command = [SEC_AGENT_PATH, 'runtime', 'policy', 'reload'] - self.exec_command("security-agent", command=command) - - def download_policies(self): - site = os.environ["DD_SITE"] - api_key = os.environ["DD_API_KEY"] - app_key = os.environ["DD_APP_KEY"] - command = [ - "/bin/bash", - "-c", - "export DD_SITE=" - + site - + " ; export DD_API_KEY=" - + api_key - + " ; export DD_APP_KEY=" - + app_key - + " ; " - + SEC_AGENT_PATH - + " runtime policy download", - ] - return self.exec_command("security-agent", command=command) - - def push_policies(self, policies): - temppolicy = tempfile.NamedTemporaryFile(prefix="e2e-policy-", mode="w", delete=False) - temppolicy.write(policies) - temppolicy.close() - temppolicy_path = temppolicy.name - self.exec_command("security-agent", command=["mkdir", "-p", "/tmp/runtime-security.d"]) - self.cp_to_agent("security-agent", temppolicy_path, "/tmp/runtime-security.d/downloaded.policy") - os.remove(temppolicy_path) - - def cp_to_agent(self, agent_name, src_file, dst_file): - command = ['tar', 'xvf', '-', '-C', '/tmp'] - resp = stream( - self.api_client.connect_post_namespaced_pod_exec, - name=self.pod_name, - namespace=self.namespace, - container=agent_name, - command=command, - stderr=True, - stdin=True, - stdout=True, - tty=False, - _preload_content=False, - ) - - with tempfile.TemporaryFile() as tar_buffer: - with tarfile.open(fileobj=tar_buffer, mode='w') as tar: - tar.add(src_file) - - tar_buffer.seek(0) - commands = [] - commands.append(tar_buffer.read()) - - while resp.is_open(): - resp.update(timeout=1) - if commands: - c = commands.pop(0) - resp.write_stdin(c) - else: - break - resp.close() - - dirname = os.path.dirname(dst_file) - command = ['mkdir', '-p', dirname] - self.exec_command(agent_name, command=command) - - command = ['mv', f'/tmp/{src_file}', dst_file] - self.exec_command(agent_name, command=command) diff --git a/test/e2e/cws-tests/tests/lib/log.py b/test/e2e/cws-tests/tests/lib/log.py deleted file mode 100644 index 5bbf5c1d3349e..0000000000000 --- a/test/e2e/cws-tests/tests/lib/log.py +++ /dev/null @@ -1,21 +0,0 @@ -from abc import ABC, abstractmethod - -from retry.api import retry_call - - -class LogGetter(ABC): - @abstractmethod - def get_log(self, _agent_name): - raise NotImplementedError() - - -def _wait_agent_log(agent_name, log_getter, pattern): - lines = log_getter.get_log(agent_name) - for line in lines: - if pattern in line: - return - raise LookupError(f"{agent_name} | {pattern}") - - -def wait_agent_log(agent_name, log_getter, pattern, tries=10, delay=5): - return retry_call(_wait_agent_log, fargs=[agent_name, log_getter, pattern], tries=tries, delay=delay) diff --git a/test/e2e/cws-tests/tests/lib/stepper.py b/test/e2e/cws-tests/tests/lib/stepper.py deleted file mode 100644 index fbfec4312c060..0000000000000 --- a/test/e2e/cws-tests/tests/lib/stepper.py +++ /dev/null @@ -1,18 +0,0 @@ -import emoji - - -class Step: - def __init__(self, msg="", emoji=""): - self.msg = msg - self.emoji = emoji - - def __enter__(self): - _emoji = emoji.emojize(self.emoji) - print(f"{_emoji} {self.msg}... ", end="", flush=True) - return self - - def __exit__(self, exc_type, _exc_val, _exc_tb): - if exc_type is None: - print(emoji.emojize(":check_mark:"), flush=True) - else: - print(emoji.emojize(":cross_mark:"), flush=True) diff --git a/test/e2e/cws-tests/tests/test_e2e_cspm.py b/test/e2e/cws-tests/tests/test_e2e_cspm.py deleted file mode 100644 index 57b0ac3f3ae44..0000000000000 --- a/test/e2e/cws-tests/tests/test_e2e_cspm.py +++ /dev/null @@ -1,34 +0,0 @@ -from lib.cspm.finding import is_subset - - -def expect_findings(test_case, findings, expected_findings): - findings_by_rule = {} - for agent_rule_id, rule_findings in findings.items(): - findings_by_rule.setdefault(agent_rule_id, []).extend(rule_findings) - for finding in rule_findings: - print(f"finding {agent_rule_id} {finding}") - - for rule_id, expected_rule_findings in expected_findings.items(): - for expected_rule_finding in expected_rule_findings: - test_case.assertIn(rule_id, findings_by_rule) - found = False - rule_findings = findings_by_rule.get(rule_id, []) - for finding in rule_findings: - if is_subset(expected_rule_finding, finding): - found = True - break - - test_case.assertTrue(found, f"unexpected finding {finding} for rule {rule_id}") - del findings_by_rule[rule_id] - - for rule_id, rule_findings in findings_by_rule.items(): - for finding in rule_findings: - result = finding["result"] - print(f"finding {rule_id} {result}") - - for rule_id, rule_findings in findings_by_rule.items(): - for finding in rule_findings: - result = finding["result"] - test_case.assertNotIn( - result, ("failed", "error"), f"finding for rule {rule_id} not expected to be in failed or error state" - ) diff --git a/test/e2e/cws-tests/tests/test_e2e_cspm_docker.py b/test/e2e/cws-tests/tests/test_e2e_cspm_docker.py deleted file mode 100644 index bbc365807542c..0000000000000 --- a/test/e2e/cws-tests/tests/test_e2e_cspm_docker.py +++ /dev/null @@ -1,150 +0,0 @@ -import json -import os -import socket -import time -import unittest -import uuid -import warnings - -from lib.config import gen_datadog_agent_config -from lib.cspm.api import App -from lib.docker import DockerHelper -from lib.stepper import Step -from test_e2e_cspm import expect_findings - - -class TestE2EDocker(unittest.TestCase): - def setUp(self): - warnings.simplefilter("ignore", category=ResourceWarning) - warnings.simplefilter("ignore", category=UserWarning) - - self.docker_helper = DockerHelper() - self.app = App() - - def tearDown(self): - self.docker_helper.close() - - def test_privileged_container(self): - print("") - - test_id = str(uuid.uuid4())[:4] - with Step(msg="create privileged container", emoji=":construction:"): - pc = self.docker_helper.client.containers.run( - "ubuntu:latest", - command="sleep 7200", - detach=True, - remove=True, - privileged=True, - ) - self.container_id = pc.id - - with Step(msg="check agent start", emoji=":man_running:"): - image = os.getenv("DD_AGENT_IMAGE") - hostname = f"host_{test_id}" - self.datadog_agent_config = gen_datadog_agent_config( - hostname=hostname, log_level="DEBUG", tags=["tag1", "tag2"] - ) - - self.container = self.docker_helper.start_cspm_agent( - image, - datadog_agent_config=self.datadog_agent_config, - ) - self.assertIsNotNone(self.container, msg="unable to start container") - - self.docker_helper.wait_agent_container() - - with Step(msg="check agent events", emoji=":check_mark_button:"): - self.container.exec_run("security-agent compliance check --dump-reports /tmp/reports.json --report") - _, output = self.container.exec_run("cat /tmp/reports.json") - print(output) - findings = json.loads(output) - - expected_findings = { - "cis-docker-1.2.0-5.4": [ - { - "agent_rule_id": "cis-docker-1.2.0-5.4", - "agent_framework_id": "cis-docker", - "result": "failed", - "resource_type": "docker_container", - "data": { - "container.id": self.container_id, - }, - } - ], - "cis-docker-1.2.0-1.2.1": [{"result": "failed"}], - "cis-docker-1.2.0-1.2.3": [{"result": "error"}], - "cis-docker-1.2.0-1.2.4": [{"result": "error"}], - "cis-docker-1.2.0-1.2.5": [{"result": "error"}], - "cis-docker-1.2.0-1.2.6": [{"result": "error"}], - "cis-docker-1.2.0-1.2.7": [{"result": "error"}], - "cis-docker-1.2.0-1.2.8": [{"result": "error"}], - "cis-docker-1.2.0-1.2.9": [{"result": "error"}], - "cis-docker-1.2.0-1.2.10": [{"result": "error"}], - "cis-docker-1.2.0-1.2.11": [{"result": "error"}], - "cis-docker-1.2.0-1.2.12": [{"result": "error"}], - "cis-docker-1.2.0-2.2": [{"result": "failed"}], - "cis-docker-1.2.0-2.3": [{"result": "failed"}], - "cis-docker-1.2.0-2.4": [{"result": "failed"}], - "cis-docker-1.2.0-2.6": [{"result": "failed"}], - "cis-docker-1.2.0-3.10": [{"result": "error"}], - "cis-docker-1.2.0-3.11": [{"result": "error"}], - "cis-docker-1.2.0-3.12": [{"result": "error"}], - "cis-docker-1.2.0-3.13": [{"result": "error"}], - "cis-docker-1.2.0-3.14": [{"result": "error"}], - "cis-docker-1.2.0-3.15": [{"result": "error"}], - "cis-docker-1.2.0-3.16": [{"result": "error"}], - "cis-docker-1.2.0-3.17": [{"result": "error"}], - "cis-docker-1.2.0-3.18": [{"result": "error"}], - "cis-docker-1.2.0-3.19": [{"result": "error"}], - "cis-docker-1.2.0-3.20": [{"result": "error"}], - "cis-docker-1.2.0-3.21": [{"result": "error"}], - "cis-docker-1.2.0-3.22": [{"result": "error"}], - "cis-docker-1.2.0-3.7": [{"result": "error"}], - "cis-docker-1.2.0-3.8": [{"result": "error"}], - "cis-docker-1.2.0-3.9": [{"result": "error"}], - "cis-docker-1.2.0-4.1": [{"result": "failed"}], - "cis-docker-1.2.0-4.6": [{"result": "failed"}], - "cis-docker-1.2.0-5.1": [{"result": "failed"}], - "cis-docker-1.2.0-5.10": [{"result": "failed"}], - "cis-docker-1.2.0-5.11": [{"result": "failed"}], - "cis-docker-1.2.0-5.12": [{"result": "failed"}], - "cis-docker-1.2.0-5.14": [{"result": "failed"}], - "cis-docker-1.2.0-5.2": [{"result": "error"}], - "cis-docker-1.2.0-5.25": [{"result": "failed"}], - "cis-docker-1.2.0-5.26": [{"result": "failed"}], - "cis-docker-1.2.0-5.28": [{"result": "failed"}], - "cis-docker-1.2.0-5.31": [{"result": "failed"}], - "cis-docker-1.2.0-5.7": [{"result": "failed"}], - } - - expect_findings(self, findings, expected_findings) - - with Step(msg="wait for intake (~1m)", emoji=":alarm_clock:"): - time.sleep(1 * 60) - - with Step(msg="wait for datadog.security_agent.compliance.running metric", emoji="\N{BEER MUG}"): # fmt: off - self.app.wait_for_metric("datadog.security_agent.compliance.running", host=socket.gethostname()) - - ## Disabled while no CSPM API is available - # with Step(msg="check app compliance event", emoji=":SOON_arrow:"): - # wait_for_compliance_event(f"resource_id:*{self.container_id}") - - with Step(msg="wait for finding generation (~1m)", emoji=":alarm_clock:"): - time.sleep(1 * 60) - - with Step(msg="wait for datadog.security_agent.compliance.containers_running metric", emoji="\N{BEER MUG}"): # fmt: off - self.app.wait_for_metric( - "datadog.security_agent.compliance.containers_running", container_id=self.container_id - ) - - ## Disabled while no CSPM API is available - # with Step(msg="check app finding", emoji=":chart_increasing_with_yen:"): - # wait_for_findings(f"@resource_type:docker_container @container_id:{self.container_id}") - - -def main(): - unittest.main() - - -if __name__ == "__main__": - main() diff --git a/test/e2e/cws-tests/tests/test_e2e_cspm_kubernetes.py b/test/e2e/cws-tests/tests/test_e2e_cspm_kubernetes.py deleted file mode 100644 index ef0871c049f30..0000000000000 --- a/test/e2e/cws-tests/tests/test_e2e_cspm_kubernetes.py +++ /dev/null @@ -1,224 +0,0 @@ -import argparse -import sys -import time -import unittest -import warnings - -import emoji -from lib.cspm.api import App -from lib.kubernetes import KubernetesHelper -from lib.stepper import Step -from test_e2e_cspm import expect_findings - - -class TestE2EKubernetes(unittest.TestCase): - namespace = "default" - in_cluster = False - expectedFindingsMasterEtcdNode = { - "cis-kubernetes-1.5.1-1.1.12": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.2.16": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.2.19": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.2.21": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.2.22": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.2.23": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.2.24": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.2.25": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.2.26": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.2.33": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.2.6": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.3.2": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.3.3": [ - { - "result": "passed", - } - ], - "cis-kubernetes-1.5.1-1.3.4": [ - { - "result": "passed", - } - ], - "cis-kubernetes-1.5.1-1.3.5": [ - { - "result": "passed", - } - ], - "cis-kubernetes-1.5.1-1.3.6": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-1.3.7": [ - { - "result": "passed", - } - ], - "cis-kubernetes-1.5.1-1.4.1": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-3.2.1": [ - { - "result": "failed", - } - ], - } - expectedFindingsWorkerNode = { - "cis-kubernetes-1.5.1-4.2.1": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-4.2.3": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-4.2.4": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-4.2.5": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-4.2.6": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-4.2.10": [ - { - "result": "failed", - } - ], - "cis-kubernetes-1.5.1-4.2.12": [ - { - "result": "failed", - } - ], - } - hostname = "k8s-e2e-tests-control-plane" - - def setUp(self): - warnings.simplefilter("ignore", category=ResourceWarning) - warnings.simplefilter("ignore", category=UserWarning) - warnings.simplefilter("ignore", category=DeprecationWarning) - - self.kubernetes_helper = KubernetesHelper(namespace=self.namespace, in_cluster=self.in_cluster) - self.resource_id = "k8s-e2e-tests-control-plane_kubernetes_*_node" - self.app = App() - - def test_k8s(self): - print("") - - agent_name = "security-agent" - - with Step(msg="select pod", emoji=":man_running:"): - self.kubernetes_helper.select_pod_name("app.kubernetes.io/component=agent") - - with Step(msg="check agent events", emoji=":check_mark_button:"): - self.kubernetes_helper.exec_command( - agent_name, ["security-agent", "compliance", "check", "--dump-reports", "/tmp/reports", "--report"] - ) - output = self.kubernetes_helper.exec_command(agent_name, ["bash", "-c", "cat /tmp/reports"]) - print(output) - # if the output is JSON, it automatically calls json.loads on it. Yeah, I know... I've felt the same too - findings = eval(output) - expected_findings = dict( - **TestE2EKubernetes.expectedFindingsMasterEtcdNode, **TestE2EKubernetes.expectedFindingsWorkerNode - ) - expect_findings(self, findings, expected_findings) - - with Step(msg="wait for intake (~1m)", emoji=":alarm_clock:"): - time.sleep(1 * 60) - - with Step(msg="wait for datadog.security_agent.compliance.running metric", emoji="\N{beer mug}"): # fmt: off - self.app.wait_for_metric("datadog.security_agent.compliance.running", host=TestE2EKubernetes.hostname) - - ## Disabled while no CSPM API is available - # with Step(msg="check app compliance event", emoji=":SOON_arrow:"): - # wait_for_compliance_event(f"resource_id:{self.resource_id}") - - with Step(msg="wait for finding generation (~1m)", emoji=":alarm_clock:"): - time.sleep(1 * 60) - - with Step(msg="wait for datadog.security_agent.compliance.containers_running metric", emoji="\N{beer mug}"): # fmt: off - self.app.wait_for_metric( - "datadog.security_agent.compliance.containers_running", host=TestE2EKubernetes.hostname - ) - - ## Disabled while no CSPM API is available - # with Step(msg="check app findings", emoji=":chart_increasing_with_yen:"): - # wait_for_findings(f"@resource_type:kubernetes_*_node @resource:{self.resource_id}") - - print(emoji.emojize(":heart_on_fire:"), flush=True) - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument("--namespace", default="default") - parser.add_argument("--in-cluster", action="store_true") - parser.add_argument("unittest_args", nargs="*") - args = parser.parse_args() - - # setup some specific tests - TestE2EKubernetes.namespace = args.namespace - TestE2EKubernetes.in_cluster = args.in_cluster - - unit_argv = [sys.argv[0]] + args.unittest_args - unittest.main(argv=unit_argv) - - -if __name__ == "__main__": - main() diff --git a/test/e2e/docs/run-instance.svg b/test/e2e/docs/run-instance.svg deleted file mode 100644 index 082cdb69d0b99..0000000000000 --- a/test/e2e/docs/run-instance.svg +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
- - - - -
- -
-
-
-
- - - - -
- -
-
-
-
- - - - -
- -
-
-
-
- - - - -
- -
-
-
-
- - - - -
- wait completion -
-
-
-
- - - - -
- -
-
-
-
-
- - - - - - -
Run Instance
-
-
-
-
- - - - - -
kind create cluster
-
-
-
-
- - - - - -
kind cluster ready
-
-
-
-
- - - - - -
argo download
-
-
-
-
- - - - - -
argo setup
-
-
-
-
- - - - - -
argo submit
-
-
-
-
- - - - - -
argo get results
-
-
-
-
- - - - - -
exit with code
-
-
-
-
-
-
-
-
\ No newline at end of file diff --git a/test/e2e/docs/sequence.md b/test/e2e/docs/sequence.md deleted file mode 100644 index 7cbab0d4037e4..0000000000000 --- a/test/e2e/docs/sequence.md +++ /dev/null @@ -1,41 +0,0 @@ -# Generate sequence - -## Update process - -1. Copy paste the content of each sequence in the [online tool](https://github.com/mermaidjs/mermaid-live-editor). -2. Download the image generated -3. move it to replace the old one - -### Online data - -[setup-instance](../scripts/setup-instance): - -```text -graph TD -A{setup-instance} -->B(AWS specification) -B --> C[ignition] -C --> D(sshAuthorizedKeys) -D -->B -B --> E[ec2] -E --> F(request-spot-instances) -F --> G(describe-spot-instance-requests) -G -->|Instance created| H(create-tags) -H -->|instance and spot requests| I(describe-instances) -I -->|Get PrivateIpAddress| J(cancel-spot-instance-requests) -J --> K[ssh] -K --> L(git clone and checkout) -L --> M{run-instance} -``` - - -[run-instance](../scripts/run-instance) -```text -graph TD -A{Run Instance} -->B[kind create cluster] -B --> C[kind cluster ready] -C --> D[argo download] -D --> E[argo setup] -E --> F[argo submit] -F -->|wait completion| G[argo get results] -G --> H{exit with code} -``` diff --git a/test/e2e/docs/setup-instance.svg b/test/e2e/docs/setup-instance.svg deleted file mode 100644 index cc69bf8b9d108..0000000000000 --- a/test/e2e/docs/setup-instance.svg +++ /dev/null @@ -1,350 +0,0 @@ -
Instance created
instance and spot requests
Get PrivateIpAddress
setup-instance
AWS specification
ignition
sshAuthorizedKeys
ec2
request-spot-instances
describe-spot-instance-requests
create-tags
describe-instances
cancel-spot-instance-requests
ssh
git clone and checkout
run-instance
\ No newline at end of file diff --git a/test/e2e/scripts/generate-parameters.sh b/test/e2e/scripts/generate-parameters.sh deleted file mode 100755 index 5dffa47feabbf..0000000000000 --- a/test/e2e/scripts/generate-parameters.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/bash - -##### A script to generate a unique namespace ##### -##### and a parameters file for a workflow ##### - - -##### Exit on error ##### -set -e - -##### Source utility functions ##### -source utils.sh - -##### Functions ##### - -usage() -{ - echo 'Usage: ./generate-parameters.sh [[-w workflow -g workflow_group] | [-h]] -Example: ./generate-parameters.sh -g workflow_group -w workflow -Flags: --w, --workflow workflow name --g, --workflow-group workflow group name --o, --output-file generated yaml file name (default parameters.yaml) --d, --workflows-dir the directory where workflows are defined (default ../argo-workflows)' -} - -validate_input() -{ - # Validate workflow name characters - if ! [[ $WORKFLOW =~ ^[0-9a-zA-Z-]+$ ]]; then - echo "Error: Invalid workflow name format: $WORKFLOW" - exit 1 - fi - - # Validate workflow group name characters - if ! [[ $WORKFLOW_GROUP =~ ^[0-9a-zA-Z._-]+$ ]]; then - echo "Error: Invalid workflow group name format: $WORKFLOW_GROUP" - exit 1 - fi -} - -# Usage: generate_parameters -generate_parameters() -{ - # Merging parameters - echo 'Info: Merging parameters...' - YK_MERGE_COMMAND='yq merge --overwrite --allow-empty' - DEFAULT_GLOBAL_PARAM="$WORKFLOWS_DIR/defaults/parameters.yaml" - DEFAULT_GROUP_PARAM="$WORKFLOWS_DIR/$WORKFLOW_GROUP/defaults/parameters.yaml" - WORKFLOW_PARAM="$WORKFLOWS_DIR/$WORKFLOW_GROUP/$WORKFLOW/parameters.yaml" - TMP_YAML_PATH="$1.tmp.yaml" - $YK_MERGE_COMMAND "$DEFAULT_GLOBAL_PARAM" "$DEFAULT_GROUP_PARAM" "$WORKFLOW_PARAM" > "$TMP_YAML_PATH" - - # Rendering namespace - echo 'Info: Parameters merged, rendering namespace and saving file...' - NAMESPACE_TEMPLATE_VAR="{{ namespace }}" - sed -e "s/$NAMESPACE_TEMPLATE_VAR/$1/g" "$TMP_YAML_PATH" > "$OUTPUT_YAML_FILE" - echo "Info: Generated parameters, yaml file saved: $OUTPUT_YAML_FILE" - - # Cleanup temp file - rm "$TMP_YAML_PATH" -} - - -##### Main ##### - -WORKFLOW="" -WORKFLOW_GROUP="" -NAMESPACE="" -OUTPUT_YAML_FILE="parameters.yaml" -WORKFLOWS_DIR="../argo-workflows" - -if [ "$1" == "" ]; then - usage - exit 1 -fi - -while [ "$1" != "" ]; do - case $1 in - -w | --workflow ) shift - WORKFLOW=$1 - ;; - -g | --workflow-group ) shift - WORKFLOW_GROUP=$1 - ;; - -o | --output-file ) shift - OUTPUT_YAML_FILE=$1 - ;; - -d | --workflows-dir ) shift - WORKFLOWS_DIR=$1 - ;; - -h | --help ) usage - exit - ;; - * ) usage - exit 1 - esac - shift -done - -# Only proceed when `yq` is installed -check_yq_installed - -# Validate the parameters -validate_input - -# Generate namespace -generate_namespace "$WORKFLOW_GROUP" "$WORKFLOW" - -# Generate the parameters file -generate_parameters "$NAMESPACE" diff --git a/test/e2e/scripts/run-instance/.gitignore b/test/e2e/scripts/run-instance/.gitignore deleted file mode 100644 index 9e2dbce48e383..0000000000000 --- a/test/e2e/scripts/run-instance/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -argo -argo.gz diff --git a/test/e2e/scripts/run-instance/10-setup-kind.sh b/test/e2e/scripts/run-instance/10-setup-kind.sh deleted file mode 100755 index bcb879510b035..0000000000000 --- a/test/e2e/scripts/run-instance/10-setup-kind.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -arch="" -case $(uname -m) in - x86_64) arch="amd64" ;; - aarch64) arch="arm64" ;; - *) - echo "Unsupported architecture" - exit 1 - ;; -esac - -download_and_install_kubectl() { - curl --retry 5 --fail --retry-all-errors -LO "https://dl.k8s.io/release/$(curl --retry 5 --fail --retry-all-errors -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/$arch/kubectl" - sudo install kubectl /usr/local/bin/kubectl -} - -printf '=%.0s' {0..79} ; echo - -if [[ $(uname) == "Darwin" ]] -then - echo "Kind setup should not be run on Darwin" - exit 1 -fi - - -# if kubctl is not here, download it -if [[ ! -f ./kubectl ]]; then - download_and_install_kubectl -else - # else, download the SHA256 of the wanted version - curl --retry 5 --fail --retry-all-errors -LO "https://dl.k8s.io/release/$(curl --retry 5 --fail --retry-all-errors -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/$arch/kubectl.sha256" - # And if it differs, force the download again - if ! echo "$(/dev/null 2>&1; then - # skip the usermod step if needless - sudo usermod -a -G docker core -fi - -echo "Kind setup finished" diff --git a/test/e2e/scripts/run-instance/11-setup-kind-cluster.sh b/test/e2e/scripts/run-instance/11-setup-kind-cluster.sh deleted file mode 100755 index 812a37c58943b..0000000000000 --- a/test/e2e/scripts/run-instance/11-setup-kind-cluster.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -printf '=%.0s' {0..79} ; echo - -is_cluster_running=$(kind get clusters|grep k8s-e2e-tests||echo none) -if [ "$is_cluster_running" == "k8s-e2e-tests" ]; then - echo "Cleanup: deleting cluster k8s-e2e-tests" - kind delete cluster --name k8s-e2e-tests -fi - -echo "Setup kind cluster: k8s-e2e-tests" -SCRIPT_DIR=$(dirname "$(readlink -f "$0")") -kind create cluster --name k8s-e2e-tests --wait 10m --config "$SCRIPT_DIR/kind-cluster.yaml" diff --git a/test/e2e/scripts/run-instance/20-argo-download.sh b/test/e2e/scripts/run-instance/20-argo-download.sh deleted file mode 100755 index a29702de2fd27..0000000000000 --- a/test/e2e/scripts/run-instance/20-argo-download.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -set -euo pipefail - -printf '=%.0s' {0..79} ; echo - -cd "$(dirname "$0")" - -set -e - -arch="" -case $(uname -m) in - x86_64) arch="amd64" ;; - aarch64) arch="arm64" ;; - *) - echo "Unsupported architecture" - exit 1 - ;; -esac - -# if argo is not here, or if the SHA doesnt match, (re)download it -if [[ ! -f ./argo.gz ]] || ! sha256sum -c "argo.$arch.sha256sum" ; then - curl -Lf "https://github.com/argoproj/argo-workflows/releases/download/v3.4.3/argo-linux-$arch.gz" -o argo.gz - # before gunziping it, check its SHA - if ! sha256sum -c "argo.$arch.sha256sum"; then - echo "SHA256 of argo.gz differs, exiting." - exit 1 - fi -fi -if [[ ! -f ./argo. ]]; then - gunzip -kf argo.gz -fi -chmod +x ./argo -./argo version diff --git a/test/e2e/scripts/run-instance/21-argo-setup.sh b/test/e2e/scripts/run-instance/21-argo-setup.sh deleted file mode 100755 index 1dae3970954a4..0000000000000 --- a/test/e2e/scripts/run-instance/21-argo-setup.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -set -euo pipefail - -printf '=%.0s' {0..79} ; echo - -cd "$(dirname "$0")" - -for i in {0..60} -do - kubectl get hpa,svc,ep,ds,deploy,job,po --all-namespaces -o wide && break - sleep 5 -done - -set -e - -kubectl create namespace argo -kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v3.4.3/install.yaml - -# TODO use a more restrictive SA -kubectl apply -f - << EOF -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: argo-admin -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cluster-admin -subjects: -- kind: ServiceAccount - name: default - namespace: default -EOF - -set +e - -for i in {0..60} -do - ./argo list && exit 0 - kubectl get hpa,svc,ep,ds,deploy,job,po --all-namespaces -o wide - sleep 5 -done - -exit 1 diff --git a/test/e2e/scripts/run-instance/22-argo-submit.sh b/test/e2e/scripts/run-instance/22-argo-submit.sh deleted file mode 100755 index 9c59119372ee5..0000000000000 --- a/test/e2e/scripts/run-instance/22-argo-submit.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash -set -euo pipefail - -printf '=%.0s' {0..79} ; echo - -# ${DATADOG_AGENT_IMAGE} and ${DATADOG_CLUSTER_AGENT_IMAGE} are provided by the CI -if [[ -z ${DATADOG_AGENT_IMAGE:+x} ]] || [[ -z ${DATADOG_CLUSTER_AGENT_IMAGE:+x} ]]; then - echo "DATADOG_AGENT_IMAGE and DATADOG_CLUSTER_AGENT_IMAGE environment variables need to be set" >&2 - exit 2 -fi - -ARGO_WORKFLOW=${ARGO_WORKFLOW:-''} - -echo "DATADOG_AGENT_IMAGE=${DATADOG_AGENT_IMAGE}" -echo "DATADOG_CLUSTER_AGENT_IMAGE=${DATADOG_CLUSTER_AGENT_IMAGE}" -echo "ARGO_WORKFLOW=${ARGO_WORKFLOW}" - -cd "$(dirname "$0")" - -if [[ -n ${DOCKER_REGISTRY_URL+x} ]] && [[ -n ${DOCKER_REGISTRY_LOGIN+x} ]] && [[ -n ${DOCKER_REGISTRY_PWD+x} ]]; then - oldstate=$(shopt -po xtrace ||:); set +x # Do not log credentials - kubectl create secret docker-registry docker-registry --docker-server="$DOCKER_REGISTRY_URL" --docker-username="$DOCKER_REGISTRY_LOGIN" --docker-password="$DOCKER_REGISTRY_PWD" - eval "$oldstate" -fi - -argo_submit_cws_cspm() { - DATADOG_AGENT_SITE=${DATADOG_AGENT_SITE:-""} - - oldstate=$(shopt -po xtrace ||:); set +x # Do not log credentials - - if [[ -z ${DATADOG_AGENT_API_KEY:+x} ]] || [[ -z ${DATADOG_AGENT_APP_KEY:+x} ]]; then - echo "DATADOG_AGENT_API_KEY, DATADOG_AGENT_APP_KEY environment variables need to be set" >&2 - exit 2 - fi - - kubectl create secret generic dd-keys \ - --from-literal=DD_API_KEY="${DATADOG_AGENT_API_KEY}" \ - --from-literal=DD_APP_KEY="${DATADOG_AGENT_APP_KEY}" \ - --from-literal=DD_DDDEV_API_KEY="${DD_API_KEY}" - - eval "$oldstate" - - ./argo template create ../../argo-workflows/templates/*.yaml - ./argo submit ../../argo-workflows/$1 --wait \ - --parameter datadog-agent-image-repository="${DATADOG_AGENT_IMAGE%:*}" \ - --parameter datadog-agent-image-tag="${DATADOG_AGENT_IMAGE#*:}" \ - --parameter datadog-cluster-agent-image-repository="${DATADOG_CLUSTER_AGENT_IMAGE%:*}" \ - --parameter datadog-cluster-agent-image-tag="${DATADOG_CLUSTER_AGENT_IMAGE#*:}" \ - --parameter datadog-agent-site="${DATADOG_AGENT_SITE#*:}" \ - --parameter ci_commit_short_sha="${CI_COMMIT_SHORT_SHA:-unknown}" \ - --parameter ci_pipeline_id="${CI_PIPELINE_ID:-unknown}" \ - --parameter ci_job_id="${CI_JOB_ID:-unknown}" || : -} - -case "$ARGO_WORKFLOW" in - "cspm") - argo_submit_cws_cspm cspm-workflow.yaml - ;; - *) - kubectl create secret generic dd-keys \ - --from-literal=DD_API_KEY=123er \ - --from-literal=DD_APP_KEY=123er1 \ - --from-literal=DD_DDDEV_API_KEY="${DD_API_KEY}" - - ./argo template create ../../argo-workflows/templates/*.yaml - ./argo submit "../../argo-workflows/${ARGO_WORKFLOW}-workflow.yaml" --wait \ - --parameter datadog-agent-image-repository="${DATADOG_AGENT_IMAGE%:*}" \ - --parameter datadog-agent-image-tag="${DATADOG_AGENT_IMAGE#*:}" \ - --parameter datadog-cluster-agent-image-repository="${DATADOG_CLUSTER_AGENT_IMAGE%:*}" \ - --parameter datadog-cluster-agent-image-tag="${DATADOG_CLUSTER_AGENT_IMAGE#*:}" \ - --parameter ci_commit_short_sha="${CI_COMMIT_SHORT_SHA:-unknown}" \ - --parameter ci_pipeline_id="${CI_PIPELINE_ID:-unknown}" \ - --parameter ci_job_id="${CI_JOB_ID:-unknown}" || : - ;; -esac - -# we are waiting for the end of the workflow but we don't care about its return code -exit 0 diff --git a/test/e2e/scripts/run-instance/23-argo-get.sh b/test/e2e/scripts/run-instance/23-argo-get.sh deleted file mode 100755 index 1c74939c56a94..0000000000000 --- a/test/e2e/scripts/run-instance/23-argo-get.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash -set -euo pipefail - -printf '=%.0s' {0..79} ; echo - -ARGO_WORKFLOW=${ARGO_WORKFLOW:-''} - -cd "$(dirname "$0")" - -# Wait for any Running workflow -until [[ "$(./argo list --running -o name)" == "No workflows found" ]]; do - sleep 10 -done - -if [[ "$(./argo list -o name)" == "No workflows found" ]]; then - echo "No workflow found" - exit 1 -fi - -if ! locale -k LC_CTYPE | grep -qi 'charmap="utf-\+8"'; then - no_utf8_opt='--no-utf8' -fi - -for workflow in $(./argo list --status Succeeded -o name | grep -v 'No workflows found'); do - # CSPM always gets logs - if [ "$ARGO_WORKFLOW" = "cspm" ]; then - ./argo logs "$workflow" - fi - - ./argo get ${no_utf8_opt:-} "$workflow" -done - -EXIT_CODE=0 -for workflow in $(./argo list --status Failed -o name | grep -v 'No workflows found'); do - ./argo logs "$workflow" - ./argo get ${no_utf8_opt:-} "$workflow" - EXIT_CODE=2 -done - -# Make the Argo UI available from the user -kubectl --namespace argo patch service/argo-server --type json --patch $'[{"op": "replace", "path": "/spec/type", "value": "NodePort"}, {"op": "replace", "path": "/spec/ports", "value": [{"port": 2746, "nodePort": 30001, "targetPort": 2746}]}]' - -# In case of failure, let's keep the VM for 1 day instead of 2 hours for investigation -if [[ $EXIT_CODE != 0 ]]; then - sudo sed -i 's/^OnBootSec=.*/OnBootSec=86400/' /etc/systemd/system/terminate.timer - sudo systemctl daemon-reload - sudo systemctl restart terminate.timer -fi - -TIME_LEFT=$(systemctl status terminate.timer | awk '$1 == "Trigger:" {print gensub(/ *Trigger: (.*)/, "\\1", 1)}') -LOCAL_IP=$(curl -s http://169.254.169.254/2020-10-27/meta-data/local-ipv4) -BEGIN_TS=$(./argo list -o json | jq -r '.[] | .metadata.creationTimestamp' | while read -r ts; do date -d "$ts" +%s; done | sort -n | head -n 1) - -printf "\033[1mThe Argo UI will remain available at \033[1;34mhttps://%s\033[0m until \033[1;33m%s\033[0m.\n" "$LOCAL_IP" "$TIME_LEFT" -printf "\033[1mAll the logs of this job can be found at \033[1;34mhttps://dddev.datadoghq.com/logs?query=app%%3Aagent-e2e-tests%%20ci_commit_short_sha%%3A%s%%20ci_pipeline_id%%3A%s%%20ci_job_id%%3A%s&index=dd-agent-ci-e2e&from_ts=%d000&to_ts=%d000&live=false\033[0m.\n" "${CI_COMMIT_SHORT_SHA:-unknown}" "${CI_PIPELINE_ID:-unknown}" "${CI_JOB_ID:-unknown}" "$BEGIN_TS" "$(date +%s)" - -exit ${EXIT_CODE} diff --git a/test/e2e/scripts/run-instance/24-argo-to-ci-setup.sh b/test/e2e/scripts/run-instance/24-argo-to-ci-setup.sh deleted file mode 100755 index a971c9005a4ce..0000000000000 --- a/test/e2e/scripts/run-instance/24-argo-to-ci-setup.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -euo pipefail - -cd "$(dirname "$0")" - -docker build -t argo-to-junit-helper:local ./argo-to-junit \ No newline at end of file diff --git a/test/e2e/scripts/run-instance/25-argo-to-ci.sh b/test/e2e/scripts/run-instance/25-argo-to-ci.sh deleted file mode 100755 index 84512ab6a388a..0000000000000 --- a/test/e2e/scripts/run-instance/25-argo-to-ci.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -euo pipefail - -cd "$(dirname "$0")" - -if ! locale -k LC_CTYPE | grep -qi 'charmap="utf-\+8"'; then - no_utf8_opt='--no-utf8' -fi - -mkdir data - -for workflow in $(./argo list -o name | grep -v 'No workflows found'); do - JSON_CRD_FILE=data/$workflow.json - JUNIT_XML_FILE=data/$workflow-junit.xml - ./argo get ${no_utf8_opt:-} "$workflow" --output json > $JSON_CRD_FILE - docker run -v $PWD/data:/data:z argo-to-junit-helper:local /$JSON_CRD_FILE /$JUNIT_XML_FILE - DATADOG_API_KEY=$DD_API_KEY datadog-ci junit upload --service agent-e2e-tests $JUNIT_XML_FILE -done diff --git a/test/e2e/scripts/run-instance/argo-to-junit/Dockerfile b/test/e2e/scripts/run-instance/argo-to-junit/Dockerfile deleted file mode 100644 index 7f380f2a55eee..0000000000000 --- a/test/e2e/scripts/run-instance/argo-to-junit/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM gcr.io/google-containers/python:3.5.1-alpine - -COPY requirements.txt argo_to_junit.py entrypoint.sh / -RUN pip3 install -r requirements.txt - -ENTRYPOINT ["/entrypoint.sh"] diff --git a/test/e2e/scripts/run-instance/argo-to-junit/argo_to_junit.py b/test/e2e/scripts/run-instance/argo-to-junit/argo_to_junit.py deleted file mode 100755 index 7e1d75c94517b..0000000000000 --- a/test/e2e/scripts/run-instance/argo-to-junit/argo_to_junit.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python3 - -import json -from argparse import ArgumentParser -from datetime import datetime - -from junit_xml import TestCase, TestSuite - - -def _str_to_datetime(date_str): - return datetime.strptime(date_str, '%Y-%m-%dT%H:%M:%SZ') - - -def _generate_test_suites(root_name, argo_nodes): - """ - Groups argo nodes by parents, generate the test cases - and yields the corresponding test suites. - """ - for node_id, node_status in argo_nodes.items(): - if node_status.get("type") in ["StepGroup", "DAG"]: - test_cases = [] - tc = TestCase(node_status.get("displayName", node_id)) - children = node_status.get("children", []) - for child_id in children: - child_status = argo_nodes.get(child_id, None) - if not child_status or child_status.get("type") != "Pod": - continue - children.extend(child_status.get("children", [])) - end = _str_to_datetime(child_status.get("finishedAt")) - start = _str_to_datetime(child_status.get("startedAt")) - job_duration = (end - start).total_seconds() - tc = TestCase(child_status.get("displayName"), elapsed_sec=job_duration) - if child_status.get("phase") == "Failed": - tc.add_failure_info(child_status.get("message")) - test_cases.append(tc) - if len(test_cases) == 0: - continue - parent_name = argo_nodes.get(node_status.get("boundaryID")).get("displayName") - # Some steps are tied directly to the root workflow (i.e the parent is argo-datadog-agent-*) - # Thus, we use a deterministic format to generate the test suite name in that case. - ts_name = parent_name if parent_name != root_name else "root" + "/" + node_status.get("displayName") - yield TestSuite(ts_name, test_cases) - - -def main(): - parser = ArgumentParser() - parser.add_argument("-i", "--input-file", help="File containing the Argo CRD in JSON", required=True) - parser.add_argument("-o", "--output-file", default="junit.xml", help="The junit xml file") - args = parser.parse_args() - - with open(args.input_file) as f: - crd = json.loads(f.read()) - crd_name = crd.get("metadata", {}).get("name") - nodes = crd.get("status", {}).get("nodes") - if not crd_name or not nodes: - print(json.dumps(crd)) - raise Exception("Incompatible CRD") - - test_suites = [] - for ts in _generate_test_suites(crd_name, nodes): - test_suites.append(ts) - with open(args.output_file, "w") as f: - TestSuite.to_file(f, test_suites) - - -if __name__ == "__main__": - main() diff --git a/test/e2e/scripts/run-instance/argo-to-junit/entrypoint.sh b/test/e2e/scripts/run-instance/argo-to-junit/entrypoint.sh deleted file mode 100755 index 72f1650ada344..0000000000000 --- a/test/e2e/scripts/run-instance/argo-to-junit/entrypoint.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -set -e - -if [ "$#" -ne 2 ]; then - /argo_to_junit.py --help - exit 1 -fi - -/argo_to_junit.py --input-file $1 --output-file $2 diff --git a/test/e2e/scripts/run-instance/argo-to-junit/requirements.txt b/test/e2e/scripts/run-instance/argo-to-junit/requirements.txt deleted file mode 100644 index 37ea29569761f..0000000000000 --- a/test/e2e/scripts/run-instance/argo-to-junit/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -junit-xml==1.9 diff --git a/test/e2e/scripts/run-instance/argo.amd64.sha256sum b/test/e2e/scripts/run-instance/argo.amd64.sha256sum deleted file mode 100644 index de69f0053c844..0000000000000 --- a/test/e2e/scripts/run-instance/argo.amd64.sha256sum +++ /dev/null @@ -1 +0,0 @@ -834a1cc0972a8810dfc39469b176d4dead17b0bc29968974da52d89b59357ac2 argo.gz \ No newline at end of file diff --git a/test/e2e/scripts/run-instance/argo.arm64.sha256sum b/test/e2e/scripts/run-instance/argo.arm64.sha256sum deleted file mode 100644 index ed3d0797a7dfd..0000000000000 --- a/test/e2e/scripts/run-instance/argo.arm64.sha256sum +++ /dev/null @@ -1 +0,0 @@ -e54086fd80f2e5de1c4ea9e7b935565b4404233ea4c96264055a7e16e85c376c argo.gz \ No newline at end of file diff --git a/test/e2e/scripts/run-instance/kind-cluster.yaml b/test/e2e/scripts/run-instance/kind-cluster.yaml deleted file mode 100644 index 4a8aed1991464..0000000000000 --- a/test/e2e/scripts/run-instance/kind-cluster.yaml +++ /dev/null @@ -1,18 +0,0 @@ -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -nodes: -- role: control-plane - extraMounts: - - containerPath: /var/lib/kubelet/config.json - hostPath: /root/.docker/config.json - - containerPath: /host/datadog-agent - hostPath: /home/core/datadog-agent - - containerPath: /host/proc - hostPath: /proc - extraPortMappings: - - containerPort: 30001 - hostPort: 443 -containerdConfigPatches: - - |- - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] - endpoint = ["https://mirror.gcr.io", "https://registry-1.docker.io"] diff --git a/test/e2e/scripts/setup-instance/.gitignore b/test/e2e/scripts/setup-instance/.gitignore deleted file mode 100644 index 680a4486820dd..0000000000000 --- a/test/e2e/scripts/setup-instance/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -fcct-* -kind -kubectl -kubectl.sha256 -fedora.gpg -butane-* diff --git a/test/e2e/scripts/setup-instance/00-entrypoint-dev.sh b/test/e2e/scripts/setup-instance/00-entrypoint-dev.sh deleted file mode 100755 index bf1c60c084704..0000000000000 --- a/test/e2e/scripts/setup-instance/00-entrypoint-dev.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -printf '=%.0s' {0..79} ; echo - -BASE64_FLAGS="-w 0" -# OSX with 2 types of base64 binary in PATH ... -if [[ $(uname) == "Darwin" ]] -then - echo "Currently running over Darwin" - # shellcheck disable=SC2086 - echo "osx base64" | base64 ${BASE64_FLAGS} || { - echo "current base64 binary does not support ${BASE64_FLAGS}" - BASE64_FLAGS="" - } -fi - -set -e - -cd "$(dirname "$0")" - -git clean -fdx . - -# Generate ssh-key and ignition files -./01-ignition.sh -# shellcheck disable=SC2086 -IGNITION_BASE64=$(base64 ${BASE64_FLAGS} ignition.json) - -REGION="${REGION:-us-east-1}" -UPDATE_STREAM="${UPDATE_STREAM:-stable}" -AMI="$(curl "https://builds.coreos.fedoraproject.org/streams/${UPDATE_STREAM}.json" | jq -r ".architectures.x86_64.images.aws.regions.\"$REGION\".image")" - -tee specification.json << EOF -{ - "ImageId": "${AMI}", - "InstanceType": "t3.2xlarge", - "Monitoring": { - "Enabled": false - }, - "BlockDeviceMappings": [ - { - "DeviceName": "/dev/xvda", - "Ebs": { - "DeleteOnTermination": true, - "VolumeSize": 50, - "VolumeType": "gp2" - } - } - ], - "UserData": "${IGNITION_BASE64}", - - "SubnetId": "subnet-b89e00e2", - "SecurityGroupIds": ["sg-7fedd80a"] -} -EOF - -export CI_COMMIT_SHORT_SHA=${CI_COMMIT_SHORT_SHA:-$(git describe --tags --always --dirty --match 7.\*)} - -exec ./02-ec2.sh diff --git a/test/e2e/scripts/setup-instance/00-entrypoint-gitlab.sh b/test/e2e/scripts/setup-instance/00-entrypoint-gitlab.sh deleted file mode 100755 index 7279be3fabb27..0000000000000 --- a/test/e2e/scripts/setup-instance/00-entrypoint-gitlab.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -printf '=%.0s' {0..79} ; echo - -cd "$(dirname "$0")" - -git clean -fdx . - -# Generate ssh-key and ignition files -./01-ignition.sh -IGNITION_BASE64=$(base64 -w 0 ignition.json) - -REGION="${REGION:-us-east-1}" -UPDATE_STREAM="${UPDATE_STREAM:-stable}" -if [ -z "${AMI+x}" ]; then - AMI="$(curl "https://builds.coreos.fedoraproject.org/streams/${UPDATE_STREAM}.json" | jq -r ".architectures.x86_64.images.aws.regions.\"$REGION\".image")" -fi -ARGO_WORKFLOW=${ARGO_WORKFLOW:-''} - -# TODO remove the IamInstanceProfile -tee specification.json << EOF -{ - "ImageId": "${AMI}", - "InstanceType": "t3.2xlarge", - "Monitoring": { - "Enabled": false - }, - "BlockDeviceMappings": [ - { - "DeviceName": "/dev/xvda", - "Ebs": { - "DeleteOnTermination": true, - "VolumeSize": 50, - "VolumeType": "gp2" - } - } - ], - "UserData": "${IGNITION_BASE64}", - - "SubnetId": "subnet-05d7c6b1b5cfea811", - "IamInstanceProfile": { - "Name": "ci-datadog-agent-e2e-runner" - }, - "SecurityGroupIds": ["sg-019917348cb0eb7e7"] -} -EOF - -echo "Running inside a gitlab pipeline," -echo "using DATADOG_AGENT_IMAGE=${DATADOG_AGENT_IMAGE}" -echo "using DATADOG_CLUSTER_AGENT_IMAGE=${DATADOG_CLUSTER_AGENT_IMAGE}" -echo "using ARGO_WORKFLOW=${ARGO_WORKFLOW}" - -# Check if the image is hosted on a docker registry and if it's available -echo "${DATADOG_AGENT_IMAGE} is hosted on a docker registry, checking if it's available" -IMAGE_REPOSITORY=${DATADOG_AGENT_IMAGE%:*} -IMAGE_TAG=${DATADOG_AGENT_IMAGE#*:} -if ! curl -Lfs --head "https://hub.docker.com/v2/repositories/${IMAGE_REPOSITORY}/tags/${IMAGE_TAG}" > /dev/null ; then - echo "The DATADOG_AGENT_IMAGE=${DATADOG_AGENT_IMAGE} is not available on DockerHub" - echo "Ensure that the manual jobs in dev_container_deploy has been run/rerun" - echo "*dev_branch* -> k8s-e2e-*-dev" - echo "*dev_master* -> k8s-e2e-*-main" - exit 2 -fi - -echo "${DATADOG_CLUSTER_AGENT_IMAGE} is hosted on a docker registry, checking if it's available" -IMAGE_REPOSITORY=${DATADOG_CLUSTER_AGENT_IMAGE%:*} -IMAGE_TAG=${DATADOG_CLUSTER_AGENT_IMAGE#*:} -if ! curl -Lfs --head "https://hub.docker.com/v2/repositories/${IMAGE_REPOSITORY}/tags/${IMAGE_TAG}" > /dev/null ; then - echo "The DATADOG_CLUSTER_AGENT_IMAGE=${DATADOG_CLUSTER_AGENT_IMAGE} is not available on DockerHub" - echo "Ensure that the manual jobs in dev_container_deploy has been run/rerun" - echo "*dev_branch* -> k8s-e2e-*-dev" - echo "*dev_master* -> k8s-e2e-*-main" - exit 2 -fi - -exec ./02-ec2.sh diff --git a/test/e2e/scripts/setup-instance/00-entrypoint-local.sh b/test/e2e/scripts/setup-instance/00-entrypoint-local.sh deleted file mode 100755 index 6bf51fd15970b..0000000000000 --- a/test/e2e/scripts/setup-instance/00-entrypoint-local.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -printf '=%.0s' {0..79} ; echo -set -e -cd "$(dirname "$0")" - -../run-instance/10-setup-kind.sh -../run-instance/11-setup-kind-cluster.sh -../run-instance/20-argo-download.sh -../run-instance/21-argo-setup.sh -../run-instance/22-argo-submit.sh -../run-instance/23-argo-get.sh diff --git a/test/e2e/scripts/setup-instance/01-ignition.sh b/test/e2e/scripts/setup-instance/01-ignition.sh deleted file mode 100755 index 870d85ddeb4b7..0000000000000 --- a/test/e2e/scripts/setup-instance/01-ignition.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -printf '=%.0s' {0..79} ; echo - -cd "$(dirname "$0")" -ssh-keygen -b 4096 -t rsa -C "datadog" -N "" -f "id_rsa" -SSH_RSA=$(cat id_rsa.pub) - -arch=$(uname -m) -if [ "$arch" = "arm64" ]; -then - arch="aarch64" -fi - -case "$(uname)" in - Linux) butane="butane-$arch-unknown-linux-gnu";; - Darwin) butane="butane-$arch-apple-darwin";; -esac - -curl -O "https://fedoraproject.org/fedora.gpg" -curl -LOC - "https://github.com/coreos/butane/releases/download/v0.20.0/${butane}" -curl -LO "https://github.com/coreos/butane/releases/download/v0.20.0/${butane}.asc" - -gpgv --keyring ./fedora.gpg "${butane}.asc" "$butane" -chmod +x "$butane" - -"./$butane" --pretty --strict < -generate_namespace() -{ - # Generate unique namespace from workflow_group and workflow - # namespace format: --- - echo 'Info: Generating namespace...' - PREFIX=$1-$2 - # `_` and `.` are not allowed in namespace names, replace them with `-` - PREFIX=${PREFIX//[_.]/-} - CHECK_SUM=$(echo -n "$PREFIX" | md5sum | cut -c1-15) - NAMESPACE=$PREFIX-$CHECK_SUM - if ! [[ $NAMESPACE =~ ^[0-9a-zA-Z-]+$ ]]; then - echo "Error: Invalid namespace format: $NAMESPACE" - exit 1 - fi - echo "Info: Generated namespace: $NAMESPACE" -} - -# Usage: check_yq_installed -check_yq_installed() -{ - if ! [ -x "$(command -v yq)" ]; then - echo 'Error: yq is not installed.' - exit 1 - fi -} \ No newline at end of file diff --git a/test/new-e2e/tests/cspm/cspm_test.go b/test/new-e2e/tests/cspm/cspm_test.go new file mode 100644 index 0000000000000..2c7a03f8b67b1 --- /dev/null +++ b/test/new-e2e/tests/cspm/cspm_test.go @@ -0,0 +1,303 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Package cspm contains the e2e tests for cspm +package cspm + +import ( + "context" + _ "embed" + "encoding/json" + "fmt" + "slices" + "testing" + "time" + + "k8s.io/apimachinery/pkg/fields" + + "github.com/DataDog/test-infra-definitions/components/datadog/kubernetesagentparams" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/DataDog/datadog-agent/test/new-e2e/pkg/e2e" + "github.com/DataDog/datadog-agent/test/new-e2e/pkg/environments" + awskubernetes "github.com/DataDog/datadog-agent/test/new-e2e/pkg/environments/aws/kubernetes" +) + +type cspmTestSuite struct { + e2e.BaseSuite[environments.Kubernetes] +} + +type findings = map[string][]map[string]string + +var expectedFindingsMasterEtcdNode = findings{ + "cis-kubernetes-1.5.1-1.1.12": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.2.16": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.2.19": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.2.21": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.2.22": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.2.23": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.2.24": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.2.25": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.2.26": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.2.33": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.2.6": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.3.2": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.3.3": []map[string]string{ + { + "result": "passed", + }, + }, + "cis-kubernetes-1.5.1-1.3.4": []map[string]string{ + { + "result": "passed", + }, + }, + "cis-kubernetes-1.5.1-1.3.5": []map[string]string{ + { + "result": "passed", + }, + }, + "cis-kubernetes-1.5.1-1.3.6": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-1.3.7": []map[string]string{ + { + "result": "passed", + }, + }, + "cis-kubernetes-1.5.1-1.4.1": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-3.2.1": []map[string]string{ + { + "result": "failed", + }, + }, +} +var expectedFindingsWorkerNode = findings{ + "cis-kubernetes-1.5.1-4.2.1": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-4.2.3": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-4.2.4": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-4.2.5": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-4.2.6": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-4.2.10": []map[string]string{ + { + "result": "failed", + }, + }, + "cis-kubernetes-1.5.1-4.2.12": []map[string]string{ + { + "result": "failed", + }, + }, +} + +//go:embed values.yaml +var values string + +func TestCSPM(t *testing.T) { + e2e.Run(t, &cspmTestSuite{}, e2e.WithProvisioner(awskubernetes.KindProvisioner(awskubernetes.WithAgentOptions(kubernetesagentparams.WithHelmValues(values), kubernetesagentparams.WithoutDualShipping())))) +} + +func (s *cspmTestSuite) TestFindings() { + res, err := s.Env().KubernetesCluster.Client().CoreV1().Pods("datadog").List(context.Background(), metav1.ListOptions{ + LabelSelector: fields.OneTermEqualSelector("app", s.Env().Agent.LinuxNodeAgent.LabelSelectors["app"]).String(), + }) + require.NoError(s.T(), err) + require.Len(s.T(), res.Items, 1) + agentPod := res.Items[0] + _, _, err = s.Env().KubernetesCluster.KubernetesClient.PodExec("datadog", agentPod.Name, "security-agent", []string{"security-agent", "compliance", "check", "--dump-reports", "/tmp/reports", "--report"}) + require.NoError(s.T(), err) + dumpContent, _, err := s.Env().KubernetesCluster.KubernetesClient.PodExec("datadog", agentPod.Name, "security-agent", []string{"cat", "/tmp/reports"}) + require.NoError(s.T(), err) + findings, err := parseFindingOutput(dumpContent) + require.NoError(s.T(), err) + s.checkFindings(findings, mergeFindings(expectedFindingsMasterEtcdNode, expectedFindingsWorkerNode)) +} + +func (s *cspmTestSuite) TestMetrics() { + s.T().Log("Waiting for datadog.security_agent.compliance.running metrics") + assert.EventuallyWithT(s.T(), func(c *assert.CollectT) { + + metrics, err := s.Env().FakeIntake.Client().FilterMetrics("datadog.security_agent.compliance.running") + if !assert.NoError(c, err) { + return + } + if assert.NotEmpty(c, metrics) { + s.T().Log("Metrics found: datadog.security_agent.compliance.running") + } + }, 2*time.Minute, 10*time.Second) + + s.T().Log("Waiting for datadog.security_agent.compliance.containers_running metrics") + assert.EventuallyWithT(s.T(), func(c *assert.CollectT) { + metrics, err := s.Env().FakeIntake.Client().FilterMetrics("datadog.security_agent.compliance.containers_running") + if !assert.NoError(c, err) { + return + } + if assert.NotEmpty(c, metrics) { + s.T().Log("Metrics found: datadog.security_agent.compliance.containers_running") + } + }, 2*time.Minute, 10*time.Second) + +} +func (s *cspmTestSuite) checkFindings(findings, expectedFindings findings) { + s.T().Helper() + checkedRule := []string{} + for expectedRule, expectedRuleFindinds := range expectedFindings { + assert.Contains(s.T(), findings, expectedRule) + for _, expectedFinding := range expectedRuleFindinds { + found := false + for _, finding := range findings[expectedRule] { + if isSubset(expectedFinding, finding) { + found = true + break + } + } + assert.Truef(s.T(), found, "unexpected finding %v for rule %s", findings[expectedRule], expectedRule) + checkedRule = append(checkedRule, expectedRule) + } + } + for rule, ruleFindings := range findings { + if slices.Contains(checkedRule, rule) { + continue + } + for _, ruleFinding := range ruleFindings { + fmt.Printf("rule %s finding %v\n", rule, ruleFinding["result"]) + } + } + for rule, ruleFindings := range findings { + if slices.Contains(checkedRule, rule) { + continue + } + for _, ruleFinding := range ruleFindings { + assert.NotContains(s.T(), []string{"failed", "error"}, ruleFinding["result"], fmt.Sprintf("finding for rule %s not expected to be in failed or error state", rule)) + } + } + +} + +func isSubset(a, b map[string]string) bool { + for k, v := range a { + if vb, found := b[k]; !found || vb != v { + return false + } + } + return true +} + +func mergeFindings(a, b findings) findings { + for k, v := range b { + a[k] = v + } + return a +} + +func parseFindingOutput(output string) (findings, error) { + + result := map[string]any{} + parsedResult := findings{} + err := json.Unmarshal([]byte(output), &result) + if err != nil { + return nil, err + } + for rule, ruleFindings := range result { + ruleFindingsCasted, ok := ruleFindings.([]any) + if !ok { + return nil, fmt.Errorf("failed to parse output: %s for rule %s cannot be casted into []any", ruleFindings, rule) + } + parsedRuleFinding := []map[string]string{} + for _, finding := range ruleFindingsCasted { + findingCasted, ok := finding.(map[string]any) + if !ok { + return nil, fmt.Errorf("failed to parse output: %s for rule %s cannot be casted into map[string]any", finding, rule) + } + parsedFinding := map[string]string{} + for k, v := range findingCasted { + if _, ok := v.(string); ok { + parsedFinding[k] = v.(string) + } + } + parsedRuleFinding = append(parsedRuleFinding, parsedFinding) + + } + parsedResult[rule] = parsedRuleFinding + + } + return parsedResult, nil +} diff --git a/test/new-e2e/tests/cspm/values.yaml b/test/new-e2e/tests/cspm/values.yaml new file mode 100644 index 0000000000000..4a9aff86ca347 --- /dev/null +++ b/test/new-e2e/tests/cspm/values.yaml @@ -0,0 +1,4 @@ +datadog: + securityAgent: + compliance: + enabled: true