diff --git a/.custom-gcl.yml b/.custom-gcl.yml new file mode 100644 index 0000000000000..45466d9aef0ce --- /dev/null +++ b/.custom-gcl.yml @@ -0,0 +1,7 @@ +version: v1.59.1 + +name: golangci-lint + +plugins: + - module: 'github.com/DataDog/datadog-agent/pkg/linters/components/pkgconfigusage' + path: ./pkg/linters/components/pkgconfigusage diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5667225e22ed8..15eaf8ff59c07 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -19,7 +19,9 @@ /.go-version @DataDog/agent-shared-components @DataDog/agent-delivery # Go linters and pre-commit config /.golangci.yml @DataDog/agent-devx-loops +/.custom-gcl.yml @DataDog/agent-devx-loops /.pre-commit-config.yaml @DataDog/agent-devx-loops +/.vscode/ @DataDog/agent-devx-loops /CHANGELOG.rst @DataDog/agent-delivery /CHANGELOG-DCA.rst @DataDog/container-integrations @DataDog/container-platform @@ -196,6 +198,7 @@ /cmd/system-probe/modules/traceroute* @DataDog/network-device-monitoring @Datadog/Networks /cmd/system-probe/modules/ping* @DataDog/network-device-monitoring /cmd/system-probe/modules/service_discover* @DataDog/apm-onboarding @DataDog/universal-service-monitoring +/cmd/system-probe/modules/language_detection* @DataDog/processes @DataDog/universal-service-monitoring /cmd/system-probe/runtime/ @DataDog/agent-security /cmd/system-probe/windows/ @DataDog/windows-kernel-integrations /cmd/system-probe/windows_resources/ @DataDog/windows-kernel-integrations @@ -293,12 +296,15 @@ /pkg/cli/ @DataDog/agent-shared-components /pkg/cli/subcommands/clusterchecks @DataDog/container-platform /pkg/dogstatsd/ @DataDog/agent-metrics-logs +/pkg/discovery/ @DataDog/apm-onboarding @DataDog/universal-service-monitoring /pkg/errors/ @DataDog/agent-shared-components /pkg/forwarder/ @DataDog/agent-processing-and-routing /pkg/gohai @DataDog/agent-shared-components /pkg/jmxfetch/ @DataDog/agent-metrics-logs /pkg/metrics/ @DataDog/agent-metrics-logs +/pkg/metrics/metricsource.go @DataDog/agent-metrics-logs @DataDog/agent-integrations /pkg/serializer/ @DataDog/agent-processing-and-routing +/pkg/serializer/internal/metrics/origin_mapping.go @DataDog/agent-processing-and-routing @DataDog/agent-integrations /pkg/serverless/ @DataDog/serverless /pkg/serverless/appsec/ @DataDog/asm-go /pkg/status/ @DataDog/agent-shared-components @@ -356,7 +362,7 @@ /pkg/collector/corechecks/system/winkmem/ @DataDog/windows-agent /pkg/collector/corechecks/system/winproc/ @DataDog/windows-agent /pkg/collector/corechecks/systemd/ @DataDog/agent-integrations -/pkg/collector/corechecks/nvidia/ @DataDog/agent-devx-infra +/pkg/collector/corechecks/nvidia/ @DataDog/platform-integrations /pkg/collector/corechecks/windows_event_log/ @DataDog/windows-agent /pkg/config/ @DataDog/agent-shared-components /pkg/config/config_template.yaml @DataDog/agent-shared-components @DataDog/documentation @@ -398,7 +404,6 @@ /pkg/proto/datadog/workloadmeta @DataDog/container-platform /pkg/remoteconfig/ @DataDog/remote-config /pkg/runtime/ @DataDog/agent-shared-components -/pkg/serializer/ @DataDog/agent-processing-and-routing /pkg/tagset/ @DataDog/agent-shared-components /pkg/util/ @DataDog/agent-shared-components /pkg/util/aggregatingqueue @DataDog/container-integrations @DataDog/container-platform @@ -426,6 +431,8 @@ /pkg/util/testutil/flake @DataDog/agent-devx-loops /pkg/util/trie @DataDog/container-integrations /pkg/languagedetection @DataDog/processes @DataDog/universal-service-monitoring +/pkg/linters/ @DataDog/agent-devx-loops +/pkg/linters/components/ @DataDog/agent-shared-components /pkg/logs/ @DataDog/agent-metrics-logs /pkg/logs/launchers/windowsevent @DataDog/agent-metrics-logs @DataDog/windows-agent /pkg/logs/tailers/windowsevent @DataDog/agent-metrics-logs @DataDog/windows-agent @@ -587,6 +594,7 @@ /test/new-e2e/tests/agent-shared-components @DataDog/agent-shared-components /test/new-e2e/tests/agent-subcommands @DataDog/agent-shared-components /test/new-e2e/tests/containers @DataDog/container-integrations @DataDog/container-platform +/test/new-e2e/tests/discovery @DataDog/apm-onboarding @DataDog/universal-service-monitoring /test/new-e2e/tests/language-detection @DataDog/processes /test/new-e2e/tests/ndm @DataDog/network-device-monitoring /test/new-e2e/tests/npm @DataDog/Networks diff --git a/.github/workflows/buildimages-update.yml b/.github/workflows/buildimages-update.yml index e3fc6d7bc2e15..9a04aceed38e4 100644 --- a/.github/workflows/buildimages-update.yml +++ b/.github/workflows/buildimages-update.yml @@ -58,7 +58,7 @@ jobs: python-version: 3.11 cache: "pip" - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: # use the go version from the input, not from the .go-version file # in case it's a Go update PR diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 5ac98f7c6cd52..4613f73359f16 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -32,12 +32,10 @@ jobs: - name: Setup env variables run: | - echo "CODEQL_PYTHON=$(which python3)" >> $GITHUB_ENV - echo "$GOPATH/bin" >> $GITHUB_PATH echo "CGO_LDFLAGS= -L${GITHUB_WORKSPACE}/rtloader/build/rtloader -ldl " >> $GITHUB_ENV echo "CGO_CFLAGS= -I${GITHUB_WORKSPACE}/rtloader/include -I${GITHUB_WORKSPACE}/rtloader/common " >> $GITHUB_ENV - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version-file: ".go-version" @@ -45,7 +43,12 @@ jobs: uses: github/codeql-action/init@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15 with: languages: ${{ matrix.language }} - setup-python-dependencies: false + config: | + paths-ignore: + - rtloader/build/rtloader/CMakeFiles/datadog-agent-rtloader.dir + - rtloader/build/three/CMakeFiles/datadog-agent-three.dir + - rtloader/build/test/CMakeFiles/run.dir + - rtloader/build/CMakeFiles/clang-format.dir - name: Set Swap Space uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c diff --git a/.github/workflows/create_rc_pr.yml b/.github/workflows/create_rc_pr.yml index 858d0615f9ad3..b6fea6cdab6a3 100644 --- a/.github/workflows/create_rc_pr.yml +++ b/.github/workflows/create_rc_pr.yml @@ -6,14 +6,14 @@ on: - cron: '0 14 * * 1,3,5' # Run on Monday, Wednesday, and Friday at 14:00 UTC - cron: '0 8 * * 1,3,5' # Same as above but at 08:00 UTC, to warn agent-integrations team about releasing - env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} jobs: - create_rc_pr: + find_release_branches: runs-on: ubuntu-latest - + outputs: + branches: ${{ steps.branches.outputs.value }} steps: - name: Checkout repository uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 @@ -33,27 +33,48 @@ jobs: pip install -r tasks/libs/requirements-github.txt pip install -r tasks/requirements_release_tasks.txt - - name: Determine the release active branch + - name: Determine the release active branches + id: branches run: | - echo "RELEASE_BRANCH=$(inv -e release.get-active-release-branch)" >> $GITHUB_ENV + echo "value=$(inv release.get-unreleased-release-branches)" >> $GITHUB_OUTPUT - name: Set the warning option if: github.event.schedule == '0 8 * * 1,3,5' run: echo "WARNING='-w'" >> $GITHUB_ENV + create_rc_pr: + runs-on: ubuntu-latest + needs: find_release_branches + strategy: + matrix: + value: ${{fromJSON(needs.find_release_branches.outputs.branches)}} + steps: - name: Checkout release branch uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: - ref: ${{ env.RELEASE_BRANCH }} + ref: ${{ matrix.value }} fetch-depth: 0 + - name: Install python + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + with: + python-version: 3.11 + cache: "pip" + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install -r tasks/libs/requirements-github.txt + pip install -r tasks/requirements_release_tasks.txt + - name: Check for changes since last RC id: check_for_changes env: ATLASSIAN_USERNAME: ${{ secrets.ATLASSIAN_USERNAME }} ATLASSIAN_PASSWORD: ${{ secrets.ATLASSIAN_PASSWORD }} run: | - echo "CHANGES=$(inv -e release.check-for-changes -r ${{ env.RELEASE_BRANCH }} ${{ env.WARNING }})" >> $GITHUB_OUTPUT + echo "CHANGES=$(inv -e release.check-for-changes -r ${{ matrix.value }} ${{ env.WARNING }})" >> $GITHUB_OUTPUT - name: Create RC PR if: ${{ steps.check_for_changes.outputs.CHANGES == 'true'}} diff --git a/.github/workflows/cws-btfhub-sync.yml b/.github/workflows/cws-btfhub-sync.yml index 8003a7d2ca0f0..970a0fef308f8 100644 --- a/.github/workflows/cws-btfhub-sync.yml +++ b/.github/workflows/cws-btfhub-sync.yml @@ -69,7 +69,7 @@ jobs: - run: pip install -r requirements.txt - name: Install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version-file: '.go-version' @@ -83,7 +83,7 @@ jobs: inv -e security-agent.generate-btfhub-constants --archive-path=./dev/dist/archive --output-path=./${{ steps.artifact-name.outputs.ARTIFACT_NAME }}.json ${{ inputs.force_refresh && '--force-refresh' || '' }} - name: Upload artifact - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: name: ${{ steps.artifact-name.outputs.ARTIFACT_NAME }} path: ./${{ steps.artifact-name.outputs.ARTIFACT_NAME }}.json @@ -105,7 +105,7 @@ jobs: - run: pip install -r requirements.txt - name: Install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version-file: '.go-version' diff --git a/.github/workflows/docs-dev.yml b/.github/workflows/docs-dev.yml index 51c74c4898463..7dba335ed58b7 100644 --- a/.github/workflows/docs-dev.yml +++ b/.github/workflows/docs-dev.yml @@ -47,7 +47,7 @@ jobs: - name: Build documentation run: invoke docs.build - - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: name: documentation path: site diff --git a/.github/workflows/go_mod_tidy.yml b/.github/workflows/go_mod_tidy.yml index 002a454c08ad0..d90caf056fb82 100644 --- a/.github/workflows/go_mod_tidy.yml +++ b/.github/workflows/go_mod_tidy.yml @@ -26,7 +26,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version-file: ".go-version" - name: Install python diff --git a/.github/workflows/gohai.yml b/.github/workflows/gohai.yml index 19da9e4695b7e..bb20f0e0104df 100644 --- a/.github/workflows/gohai.yml +++ b/.github/workflows/gohai.yml @@ -31,7 +31,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version-file: ${{ matrix.go-file }} - name: Test diff --git a/.github/workflows/serverless-benchmarks.yml b/.github/workflows/serverless-benchmarks.yml index 1b1388da42007..37742948b0d36 100644 --- a/.github/workflows/serverless-benchmarks.yml +++ b/.github/workflows/serverless-benchmarks.yml @@ -27,7 +27,7 @@ jobs: ref: ${{ github.base_ref }} - name: Install Go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: stable @@ -43,7 +43,7 @@ jobs: ./pkg/serverless/... | tee ${{runner.temp}}/benchmark.log - name: Upload result artifact - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: name: baseline.log path: ${{runner.temp}}/benchmark.log @@ -63,7 +63,7 @@ jobs: ref: ${{ github.sha }} - name: Install Go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: stable @@ -79,7 +79,7 @@ jobs: ./pkg/serverless/... | tee ${{runner.temp}}/benchmark.log - name: Upload result artifact - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: name: current.log path: ${{runner.temp}}/benchmark.log @@ -89,10 +89,12 @@ jobs: name: Summary runs-on: ubuntu-latest needs: [baseline, current] + permissions: + pull-requests: write steps: - name: Install Go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version: stable cache: false diff --git a/.github/workflows/serverless-binary-size.yml b/.github/workflows/serverless-binary-size.yml index 7e23a355320e3..56818495bd7cb 100644 --- a/.github/workflows/serverless-binary-size.yml +++ b/.github/workflows/serverless-binary-size.yml @@ -82,14 +82,19 @@ jobs: id: should run: | cd go/src/github.com/DataDog/datadog-agent + git fetch origin $GITHUB_BASE_REF + git fetch origin $GITHUB_HEAD_REF if test $( - git diff $GITHUB_BASE_REF..$GITHUB_SHA --name-only | grep dependencies_linux_amd64.txt + git diff origin/$GITHUB_BASE_REF...origin/$GITHUB_HEAD_REF --name-only | grep dependencies_linux_amd64.txt ); then echo "should_run=true" >> $GITHUB_OUTPUT + echo "dependencies list changed" elif [[ ${{ steps.compare.outputs.diff }} > env.SIZE_ALLOWANCE ]]; then echo "should_run=true" >> $GITHUB_OUTPUT + echo "binary size changed" else echo "should_run=false" >> $GITHUB_OUTPUT + echo "nothing changed" fi ### Steps below run if size diff > SIZE_ALLOWANCE or file dependencies_linux_amd64.txt changed ### @@ -127,7 +132,7 @@ jobs: done - name: Archive dependency graphs - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 if: steps.should.outputs.should_run == 'true' with: name: dependency-graphs diff --git a/.github/workflows/serverless-integration.yml b/.github/workflows/serverless-integration.yml index e4eab97b643b7..8bd8459b6c52f 100644 --- a/.github/workflows/serverless-integration.yml +++ b/.github/workflows/serverless-integration.yml @@ -74,7 +74,7 @@ jobs: - name: Archive raw logs if: always() - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: name: rawlogs-${{ matrix.suite }}-${{ matrix.architecture }} path: ${{ steps.rawlogs.outputs.dir }} diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f62f2756f3c43..d315c194dad2e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -206,6 +206,10 @@ variables: E2E_TESTS_API_KEY_SSM_NAME: ci.datadog-agent.e2e_tests_api_key # agent-devx-loops E2E_TESTS_APP_KEY_SSM_NAME: ci.datadog-agent.e2e_tests_app_key # agent-devx-loops E2E_TESTS_RC_KEY_SSM_NAME: ci.datadog-agent.e2e_tests_rc_key # agent-devx-loops + E2E_TESTS_AZURE_CLIENT_ID: ci.datadog-agent.e2e_tests_azure_client_id # agent-devx-loops + E2E_TESTS_AZURE_CLIENT_SECRET: ci.datadog-agent.e2e_tests_azure_client_secret # agent-devx-loops + E2E_TESTS_AZURE_TENANT_ID: ci.datadog-agent.e2e_tests_azure_tenant_id # agent-devx-loops + E2E_TESTS_AZURE_SUBSCRIPTION_ID: ci.datadog-agent.e2e_tests_azure_subscription_id # agent-devx-loops KITCHEN_EC2_SSH_KEY_SSM_NAME: ci.datadog-agent.aws_ec2_kitchen_ssh_key # agent-devx-loops KITCHEN_AZURE_CLIENT_ID_SSM_NAME: ci.datadog-agent.azure_kitchen_client_id # agent-devx-loops KITCHEN_AZURE_CLIENT_SECRET_SSM_NAME: ci.datadog-agent.azure_kitchen_client_secret # agent-devx-loops @@ -384,6 +388,7 @@ workflow: GO_TEST_SKIP_FLAKE: "false" - <<: *if_release_branch - <<: *if_deploy + - <<: *if_deploy_installer - if: $CI_COMMIT_TAG == null # @@ -590,7 +595,6 @@ workflow: .except_deploy: - <<: *if_deploy when: never - - when: on_success .except_no_tests_no_deploy: - if: $DEPLOY_AGENT == "false" && $DDR_WORKFLOW_ID == null && $RUN_E2E_TESTS == "off" @@ -720,16 +724,6 @@ workflow: - tasks/msi.py compare_to: main # TODO: use a variable, when this is supported https://gitlab.com/gitlab-org/gitlab/-/issues/369916 -.on_windows_installer_changes_or_manual: - - <<: *if_disable_e2e_tests - when: never - - <<: *if_main_branch - - !reference [.except_mergequeue] - - <<: *if_windows_installer_changes - when: on_success - - when: manual - allow_failure: true - .except_windows_installer_changes: - <<: *if_windows_installer_changes when: never @@ -796,6 +790,11 @@ workflow: - test/new-e2e/go.mod compare_to: main # TODO: use a variable, when this is supported https://gitlab.com/gitlab-org/gitlab/-/issues/369916 +.on_e2e_or_windows_installer_changes: + - !reference [.on_e2e_main_release_or_rc] + - <<: *if_windows_installer_changes + when: on_success + .on_e2e_or_fakeintake_changes_or_manual: - !reference [.on_e2e_main_release_or_rc] - changes: @@ -884,6 +883,14 @@ workflow: - test/new-e2e/tests/npm/**/* compare_to: main # TODO: use a variable, when this is supported https://gitlab.com/gitlab-org/gitlab/-/issues/369916 +.on_discovery_or_e2e_changes: + - !reference [.on_e2e_main_release_or_rc] + - changes: + paths: + - test/new-e2e/tests/discovery/**/* + - pkg/collector/corechecks/servicediscovery/**/* + compare_to: main # TODO: use a variable, when this is supported https://gitlab.com/gitlab-org/gitlab/-/issues/369916 + .on_aml_or_e2e_changes: - !reference [.on_e2e_main_release_or_rc] - changes: diff --git a/.gitlab/JOBOWNERS b/.gitlab/JOBOWNERS index 8a7d447774c5c..230727b1baa6d 100644 --- a/.gitlab/JOBOWNERS +++ b/.gitlab/JOBOWNERS @@ -158,6 +158,7 @@ upload_minimized_btfs* @DataDog/ebpf-platform kmt_* @DataDog/ebpf-platform upload_secagent_tests* @DataDog/ebpf-platform upload_sysprobe_tests* @DataDog/ebpf-platform +notify_ebpf_complexity_changes @DataDog/ebpf-platform pull_test_dockers* @DataDog/universal-service-monitoring # Single machine performance diff --git a/.gitlab/common/container_publish_job_templates.yml b/.gitlab/common/container_publish_job_templates.yml index 495b67ac9f26b..ed119645aa883 100644 --- a/.gitlab/common/container_publish_job_templates.yml +++ b/.gitlab/common/container_publish_job_templates.yml @@ -1,9 +1,9 @@ --- .docker_variables: &docker_variables - SRC_AGENT: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent - SRC_DSD: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/dogstatsd - SRC_DCA: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/cluster-agent - SRC_CWS_INSTRUMENTATION: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/cws-instrumentation + SRC_AGENT: registry.ddbuild.io/ci/datadog-agent/agent + SRC_DSD: registry.ddbuild.io/ci/datadog-agent/dogstatsd + SRC_DCA: registry.ddbuild.io/ci/datadog-agent/cluster-agent + SRC_CWS_INSTRUMENTATION: registry.ddbuild.io/ci/datadog-agent/cws-instrumentation .docker_publish_job_definition: image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent-buildimages/deb_x64$DATADOG_AGENT_BUILDIMAGES_SUFFIX:$DATADOG_AGENT_BUILDIMAGES diff --git a/.gitlab/common/test_infra_version.yml b/.gitlab/common/test_infra_version.yml index fa31a5ecb408a..178e85344cbc9 100644 --- a/.gitlab/common/test_infra_version.yml +++ b/.gitlab/common/test_infra_version.yml @@ -4,4 +4,4 @@ variables: # and check the job creating the image to make sure you have the right SHA prefix TEST_INFRA_DEFINITIONS_BUILDIMAGES_SUFFIX: "" # Make sure to update test-infra-definitions version in go.mod as well - TEST_INFRA_DEFINITIONS_BUILDIMAGES: 94712f9a273b + TEST_INFRA_DEFINITIONS_BUILDIMAGES: 0f82f8cbf8ea diff --git a/.gitlab/container_build/docker_linux.yml b/.gitlab/container_build/docker_linux.yml index 4383141d7f3a0..d12b6894b57de 100644 --- a/.gitlab/container_build/docker_linux.yml +++ b/.gitlab/container_build/docker_linux.yml @@ -15,8 +15,8 @@ # DockerHub login for build to limit rate limit when pulling base images - DOCKER_REGISTRY_LOGIN=$($CI_PROJECT_DIR/tools/ci/aws_ssm_get_wrapper.sh $DOCKER_REGISTRY_LOGIN_SSM_KEY) - $CI_PROJECT_DIR/tools/ci/aws_ssm_get_wrapper.sh $DOCKER_REGISTRY_PWD_SSM_KEY | docker login --username "$DOCKER_REGISTRY_LOGIN" --password-stdin "$DOCKER_REGISTRY_URL" - # Build image - - docker buildx build --no-cache --push --pull --platform linux/$ARCH --build-arg CIBUILD=true --build-arg GENERAL_ARTIFACTS_CACHE_BUCKET_URL=${GENERAL_ARTIFACTS_CACHE_BUCKET_URL} $BUILD_ARG --build-arg DD_GIT_REPOSITORY_URL=https://github.com/DataDog/datadog-agent --build-arg DD_GIT_COMMIT_SHA=${CI_COMMIT_SHA} --file $BUILD_CONTEXT/Dockerfile --tag ${TARGET_TAG} --label "org.opencontainers.image.created=$(date --rfc-3339=seconds)" --label "org.opencontainers.image.authors=Datadog " --label "org.opencontainers.image.source=https://github.com/DataDog/datadog-agent" --label "org.opencontainers.image.version=$(inv agent.version)" --label "org.opencontainers.image.revision=${CI_COMMIT_SHA}" --label "org.opencontainers.image.vendor=Datadog, Inc." $BUILD_CONTEXT + # Build image, use target none label to avoid replication + - docker buildx build --no-cache --push --pull --platform linux/$ARCH --build-arg CIBUILD=true --build-arg GENERAL_ARTIFACTS_CACHE_BUCKET_URL=${GENERAL_ARTIFACTS_CACHE_BUCKET_URL} $BUILD_ARG --build-arg DD_GIT_REPOSITORY_URL=https://github.com/DataDog/datadog-agent --build-arg DD_GIT_COMMIT_SHA=${CI_COMMIT_SHA} --file $BUILD_CONTEXT/Dockerfile --tag ${TARGET_TAG} --label "org.opencontainers.image.created=$(date --rfc-3339=seconds)" --label "org.opencontainers.image.authors=Datadog " --label "org.opencontainers.image.source=https://github.com/DataDog/datadog-agent" --label "org.opencontainers.image.version=$(inv agent.version)" --label "org.opencontainers.image.revision=${CI_COMMIT_SHA}" --label "org.opencontainers.image.vendor=Datadog, Inc." --label "target=none" $BUILD_CONTEXT # Squash image - crane flatten -t ${TARGET_TAG} ${TARGET_TAG} # Workaround for temporary network failures @@ -47,7 +47,7 @@ docker_build_agent6: - job: agent_deb-x64-a6 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -6 BUILD_ARG: --target test --build-arg PYTHON_VERSION=2 --build-arg DD_AGENT_ARTIFACT=datadog-agent_6*_amd64.deb @@ -59,7 +59,7 @@ docker_build_agent6_arm64: - job: agent_deb-arm64-a6 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -6 BUILD_ARG: --target test --build-arg PYTHON_VERSION=2 --build-arg DD_AGENT_ARTIFACT=datadog-agent_6*arm64.deb @@ -74,7 +74,7 @@ docker_build_agent6_jmx: - job: agent_deb-x64-a6 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent BUILD_ARTIFACT_GLOB: datadog-agent_6*_amd64.deb TAG_SUFFIX: -6-jmx @@ -88,7 +88,7 @@ docker_build_agent6_jmx_arm64: - job: agent_deb-arm64-a6 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent BUILD_ARTIFACT_GLOB: datadog-agent_6*arm64.deb TAG_SUFFIX: -6-jmx @@ -105,7 +105,7 @@ docker_build_agent6_py2py3_jmx: - job: agent_deb-x64-a6 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -6-py2py3-jmx BUILD_ARG: --target test --build-arg WITH_JMX=true --build-arg DD_AGENT_ARTIFACT=datadog-agent_6*_amd64.deb @@ -120,7 +120,7 @@ docker_build_agent7: - job: agent_deb-x64-a7 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -7 BUILD_ARG: --target test --build-arg PYTHON_VERSION=3 --build-arg DD_AGENT_ARTIFACT=datadog-agent_7*_amd64.deb @@ -147,7 +147,7 @@ docker_build_agent7_arm64: - job: agent_deb-arm64-a7 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -7 BUILD_ARG: --target test --build-arg PYTHON_VERSION=3 --build-arg DD_AGENT_ARTIFACT=datadog-agent_7*_arm64.deb @@ -162,7 +162,7 @@ docker_build_agent7_jmx: - job: agent_deb-x64-a7 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -7-jmx BUILD_ARG: --target test --build-arg WITH_JMX=true --build-arg PYTHON_VERSION=3 --build-arg DD_AGENT_ARTIFACT=datadog-agent_7*_amd64.deb @@ -176,7 +176,7 @@ docker_build_agent7_jmx_arm64: - job: agent_deb-arm64-a7 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -7-jmx BUILD_ARG: --target test --build-arg WITH_JMX=true --build-arg PYTHON_VERSION=3 --build-arg DD_AGENT_ARTIFACT=datadog-agent_7*_arm64.deb @@ -191,7 +191,7 @@ docker_build_ot_agent7: - job: ot_agent_deb-x64-a7 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -7-ot-beta BUILD_ARG: --target test --build-arg PYTHON_VERSION=3 --build-arg DD_AGENT_ARTIFACT=datadog-ot-agent_7*_amd64.deb @@ -205,7 +205,7 @@ docker_build_ot_agent7_arm64: - job: ot_agent_deb-arm64-a7 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -7-ot-beta BUILD_ARG: --target test --build-arg PYTHON_VERSION=3 --build-arg DD_AGENT_ARTIFACT=datadog-ot-agent_7*_arm64.deb @@ -220,7 +220,7 @@ docker_build_ot_agent7_jmx: - job: ot_agent_deb-x64-a7 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -7-ot-beta-jmx BUILD_ARG: --target test --build-arg WITH_JMX=true --build-arg PYTHON_VERSION=3 --build-arg DD_AGENT_ARTIFACT=datadog-ot-agent_7*_amd64.deb @@ -234,7 +234,7 @@ docker_build_ot_agent7_jmx_arm64: - job: ot_agent_deb-arm64-a7 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent TAG_SUFFIX: -7-ot-beta-jmx BUILD_ARG: --target test --build-arg WITH_JMX=true --build-arg PYTHON_VERSION=3 --build-arg DD_AGENT_ARTIFACT=datadog-ot-agent_7*_arm64.deb @@ -251,7 +251,7 @@ docker_build_cluster_agent_amd64: - job: cws_instrumentation-build_arm64 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/cluster-agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/cluster-agent BUILD_CONTEXT: Dockerfiles/cluster-agent before_script: - cp -Rvf Dockerfiles/agent/nosys-seccomp Dockerfiles/cluster-agent/ @@ -267,7 +267,7 @@ docker_build_cluster_agent_arm64: - job: cws_instrumentation-build_arm64 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/cluster-agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/cluster-agent BUILD_CONTEXT: Dockerfiles/cluster-agent before_script: - cp -Rvf Dockerfiles/agent/nosys-seccomp Dockerfiles/cluster-agent/ @@ -280,7 +280,7 @@ docker_build_cws_instrumentation_amd64: - job: cws_instrumentation-build_amd64 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/cws-instrumentation + IMAGE: registry.ddbuild.io/ci/datadog-agent/cws-instrumentation BUILD_CONTEXT: Dockerfiles/cws-instrumentation docker_build_cws_instrumentation_arm64: @@ -290,7 +290,7 @@ docker_build_cws_instrumentation_arm64: - job: cws_instrumentation-build_arm64 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/cws-instrumentation + IMAGE: registry.ddbuild.io/ci/datadog-agent/cws-instrumentation BUILD_CONTEXT: Dockerfiles/cws-instrumentation # build the dogstatsd image @@ -303,7 +303,7 @@ docker_build_dogstatsd_amd64: - job: build_dogstatsd_static-binary_x64 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/dogstatsd + IMAGE: registry.ddbuild.io/ci/datadog-agent/dogstatsd BUILD_CONTEXT: Dockerfiles/dogstatsd/alpine timeout: 20m @@ -317,6 +317,6 @@ docker_build_dogstatsd_arm64: - job: build_dogstatsd_static-binary_arm64 artifacts: false variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/dogstatsd + IMAGE: registry.ddbuild.io/ci/datadog-agent/dogstatsd BUILD_CONTEXT: Dockerfiles/dogstatsd/alpine timeout: 20m diff --git a/.gitlab/container_build/docker_windows.yml b/.gitlab/container_build/docker_windows.yml index 568b3e3f6798d..6d7a365b22ee4 100644 --- a/.gitlab/container_build/docker_windows.yml +++ b/.gitlab/container_build/docker_windows.yml @@ -2,7 +2,7 @@ .docker_build_agent_windows_common: stage: container_build variables: - IMAGE: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/agent + IMAGE: registry.ddbuild.io/ci/datadog-agent/agent BUILD_CONTEXT: Dockerfiles/agent script: - $ECR_RELEASE_SUFFIX="$(If ($BUCKET_BRANCH -eq `"nightly`") { `"-nightly`" } elseif ($CI_COMMIT_TAG) { `"-release`" } else { `"`" })" diff --git a/.gitlab/container_build/fakeintake.yml b/.gitlab/container_build/fakeintake.yml index b5a725f23dba9..334d6e73e78ca 100644 --- a/.gitlab/container_build/fakeintake.yml +++ b/.gitlab/container_build/fakeintake.yml @@ -9,7 +9,7 @@ docker_build_fakeintake: image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/docker:20.10-py3 tags: ["arch:amd64"] variables: - TARGET: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/fakeintake:v${CI_PIPELINE_ID}-${CI_COMMIT_SHORT_SHA} + TARGET: registry.ddbuild.io/ci/datadog-agent/fakeintake:v${CI_PIPELINE_ID}-${CI_COMMIT_SHORT_SHA} DOCKERFILE: test/fakeintake/Dockerfile PLATFORMS: linux/amd64,linux/arm64 BUILD_CONTEXT: . diff --git a/.gitlab/dev_container_deploy/fakeintake.yml b/.gitlab/dev_container_deploy/fakeintake.yml index 326def46873f9..d7119602ce3c7 100644 --- a/.gitlab/dev_container_deploy/fakeintake.yml +++ b/.gitlab/dev_container_deploy/fakeintake.yml @@ -9,7 +9,7 @@ publish_fakeintake: - job: docker_build_fakeintake optional: false variables: - IMG_SOURCES: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/fakeintake:v${CI_PIPELINE_ID}-${CI_COMMIT_SHORT_SHA} + IMG_SOURCES: registry.ddbuild.io/ci/datadog-agent/fakeintake:v${CI_PIPELINE_ID}-${CI_COMMIT_SHORT_SHA} IMG_DESTINATIONS: fakeintake:v${CI_COMMIT_SHORT_SHA} IMG_REGISTRIES: public IMG_SIGNING: "false" @@ -24,7 +24,7 @@ publish_fakeintake_latest: - job: docker_build_fakeintake optional: false variables: - IMG_SOURCES: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent/fakeintake:v${CI_PIPELINE_ID}-${CI_COMMIT_SHORT_SHA} + IMG_SOURCES: registry.ddbuild.io/ci/datadog-agent/fakeintake:v${CI_PIPELINE_ID}-${CI_COMMIT_SHORT_SHA} IMG_DESTINATIONS: fakeintake:latest IMG_REGISTRIES: public IMG_SIGNING: "false" diff --git a/.gitlab/e2e/e2e.yml b/.gitlab/e2e/e2e.yml index f337ec283ff1a..c6da596e93f7a 100644 --- a/.gitlab/e2e/e2e.yml +++ b/.gitlab/e2e/e2e.yml @@ -97,6 +97,12 @@ k8s-e2e-otlp-main: - touch $E2E_PRIVATE_KEY_PATH && chmod 600 $E2E_PRIVATE_KEY_PATH && $CI_PROJECT_DIR/tools/ci/aws_ssm_get_wrapper.sh $SSH_KEY_RSA_SSM_NAME > $E2E_PRIVATE_KEY_PATH # Use S3 backend - pulumi login "s3://dd-pulumi-state?region=us-east-1&awssdk=v2&profile=$AWS_PROFILE" + # Setup Azure credentials. https://www.pulumi.com/registry/packages/azure-native/installation-configuration/#set-configuration-using-pulumi-config + # The app is called `agent-e2e-tests` + - export ARM_CLIENT_ID=$($CI_PROJECT_DIR/tools/ci/aws_ssm_get_wrapper.sh $E2E_TESTS_AZURE_CLIENT_ID) + - export ARM_CLIENT_SECRET=$($CI_PROJECT_DIR/tools/ci/aws_ssm_get_wrapper.sh $E2E_TESTS_AZURE_CLIENT_SECRET) + - export ARM_TENANT_ID=$($CI_PROJECT_DIR/tools/ci/aws_ssm_get_wrapper.sh $E2E_TESTS_AZURE_TENANT_ID) + - export ARM_SUBSCRIPTION_ID=$($CI_PROJECT_DIR/tools/ci/aws_ssm_get_wrapper.sh $E2E_TESTS_AZURE_SUBSCRIPTION_ID) # Generate external links to CI VISIBILITY, used by artifacts:reports:annotations - inv -e gitlab.generate-ci-visibility-links --output=$EXTERNAL_LINKS_PATH variables: @@ -167,7 +173,7 @@ new-e2e-containers: matrix: # Temporarily disable old version of Kubernetes # On this version, the reported kubernetes CPU usage appears to be significantly off - # - EXTRA_PARAMS: "--run TestKindSuite -c ddinfra:kubernetesVersion=1.19" + - EXTRA_PARAMS: "--run TestKindSuite -c ddinfra:kubernetesVersion=1.19" - EXTRA_PARAMS: "--run TestKindSuite -c ddinfra:kubernetesVersion=1.22" - EXTRA_PARAMS: "--run TestKindSuite -c ddinfra:kubernetesVersion=1.27" - EXTRA_PARAMS: "--run TestKindSuite -c ddinfra:kubernetesVersion=1.29" @@ -308,6 +314,18 @@ new-e2e-cws: # Temporary, remove once we made sure the recent changes have no impact on the stability of these tests allow_failure: true +new-e2e-discovery: + extends: .new_e2e_template + needs: + - !reference [.needs_new_e2e_template] + - deploy_deb_testing-a7_x64 + rules: + - !reference [.on_discovery_or_e2e_changes] + - !reference [.manual] + variables: + TARGETS: ./tests/discovery + TEAM: universal-service-monitoring + new-e2e-process: extends: .new_e2e_template needs: @@ -380,6 +398,29 @@ new-e2e-installer: variables: TARGETS: ./tests/installer TEAM: fleet + FLEET_INSTALL_METHOD: "install_script" + +new-e2e-installer-ansible: + extends: .new_e2e_template + rules: + - !reference [.on_installer_or_e2e_changes] + - !reference [.manual] + needs: + - !reference [.needs_new_e2e_template] + - new-e2e-installer + before_script: + # CURRENT_AGENT_VERSION is used to verify the installed agent version + # Must run before new_e2e_template changes the aws profile + # Note: this is similar to the WINDOWS_AGENT_VERSION in new-e2e_windows_msi but this job is running cross platforms + # Note 2: new_e2e_template does not define AGENT_MAJOR_VERSION, so define it as 7 below. + - export CURRENT_AGENT_VERSION=$(invoke agent.version --major-version 7) + - export STABLE_AGENT_VERSION_PACKAGE=$(curl -sS https://hub.docker.com/v2/namespaces/datadog/repositories/agent-package/tags | jq -r '.results[] | .name' | sort | tail -n 2 | head -n 1) + - export STABLE_INSTALLER_VERSION_PACKAGE=$(curl -sS https://hub.docker.com/v2/namespaces/datadog/repositories/installer-package/tags | jq -r '.results[] | .name' | sort | tail -n 2 | head -n 1) + - !reference [.new_e2e_template, before_script] + variables: + TARGETS: ./tests/installer + TEAM: fleet + FLEET_INSTALL_METHOD: "ansible" new-e2e-ndm-netflow: extends: .new_e2e_template diff --git a/.gitlab/functional_test/include.yml b/.gitlab/functional_test/include.yml index 106204c447c69..b5a2e851ac2c6 100644 --- a/.gitlab/functional_test/include.yml +++ b/.gitlab/functional_test/include.yml @@ -11,3 +11,4 @@ include: - .gitlab/kernel_matrix_testing/common.yml - .gitlab/kernel_matrix_testing/system_probe.yml - .gitlab/kernel_matrix_testing/security_agent.yml + - .gitlab/functional_test/oracle.yml diff --git a/.gitlab/functional_test/oracle.yml b/.gitlab/functional_test/oracle.yml new file mode 100644 index 0000000000000..324f757bc9481 --- /dev/null +++ b/.gitlab/functional_test/oracle.yml @@ -0,0 +1,20 @@ +oracle: + image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent-buildimages/deb_x64$DATADOG_AGENT_BUILDIMAGES_SUFFIX:$DATADOG_AGENT_BUILDIMAGES + tags: ["runner:docker"] + stage: functional_test + needs: ["go_deps"] + services: + - alias: "oracle" + name: "registry.ddbuild.io/images/mirror/oracle:${DBMS_VERSION}" + variables: + ORACLE_PWD: "datad0g" + variables: + CI_DEBUG_SERVICES: "true" + parallel: + matrix: + - DBMS_VERSION: "21.3.0-xe" + before_script: + - source /root/.bashrc + - !reference [.retrieve_linux_go_deps] + script: + - inv oracle.test \ No newline at end of file diff --git a/.gitlab/functional_test/regression_detector.yml b/.gitlab/functional_test/regression_detector.yml index 0f9f06e20c7ec..3819ff4626d4d 100644 --- a/.gitlab/functional_test/regression_detector.yml +++ b/.gitlab/functional_test/regression_detector.yml @@ -17,7 +17,7 @@ single-machine-performance-regression_detector: - outputs/report.html # for debugging, also on S3 when: always variables: - SMP_VERSION: 0.15.1 + SMP_VERSION: 0.16.0 # At present we require two artifacts to exist for the 'baseline' and the # 'comparison'. We are guaranteed by the structure of the pipeline that # 'comparison' exists, not so much with 'baseline' as it has to come from main diff --git a/.gitlab/internal_image_deploy/internal_image_deploy.yml b/.gitlab/internal_image_deploy/internal_image_deploy.yml index 4c5d5af08f1d4..f4cb34de1588a 100644 --- a/.gitlab/internal_image_deploy/internal_image_deploy.yml +++ b/.gitlab/internal_image_deploy/internal_image_deploy.yml @@ -14,7 +14,7 @@ docker_trigger_internal: tags: ["arch:amd64"] variables: DYNAMIC_BUILD_RENDER_RULES: agent-build-only # fake rule to not trigger the ones in the images repo - IMAGE_VERSION: tmpl-v9 + IMAGE_VERSION: tmpl-v10 IMAGE_NAME: datadog-agent RELEASE_TAG: ${CI_COMMIT_REF_SLUG}-jmx BUILD_TAG: ${CI_COMMIT_REF_SLUG}-jmx @@ -60,7 +60,7 @@ docker_trigger_internal-ot: tags: ["arch:amd64"] variables: DYNAMIC_BUILD_RENDER_RULES: agent-build-only # fake rule to not trigger the ones in the images repo - IMAGE_VERSION: tmpl-v9 + IMAGE_VERSION: tmpl-v10 IMAGE_NAME: datadog-agent RELEASE_TAG: ${CI_COMMIT_REF_SLUG}-ot-beta-jmx BUILD_TAG: ${CI_COMMIT_REF_SLUG}-ot-beta-jmx @@ -106,7 +106,7 @@ docker_trigger_cluster_agent_internal: tags: ["arch:amd64"] variables: DYNAMIC_BUILD_RENDER_RULES: agent-build-only # fake rule to not trigger the ones in the images repo - IMAGE_VERSION: tmpl-v4 + IMAGE_VERSION: tmpl-v5 IMAGE_NAME: datadog-cluster-agent RELEASE_TAG: ${CI_COMMIT_REF_SLUG} BUILD_TAG: ${CI_COMMIT_REF_SLUG} @@ -153,7 +153,7 @@ docker_trigger_cws_instrumentation_internal: tags: ["arch:amd64"] variables: DYNAMIC_BUILD_RENDER_RULES: agent-build-only # fake rule to not trigger the ones in the images repo - IMAGE_VERSION: tmpl-v1 + IMAGE_VERSION: tmpl-v2 IMAGE_NAME: datadog-cws-instrumentation RELEASE_TAG: ${CI_COMMIT_REF_SLUG} BUILD_TAG: ${CI_COMMIT_REF_SLUG} diff --git a/.gitlab/kernel_matrix_testing/common.yml b/.gitlab/kernel_matrix_testing/common.yml index 5dad208ec8007..a75a9b9b8b04e 100644 --- a/.gitlab/kernel_matrix_testing/common.yml +++ b/.gitlab/kernel_matrix_testing/common.yml @@ -271,14 +271,15 @@ notify_ebpf_complexity_changes: stage: notify - image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/test-infra-definitions/runner$TEST_INFRA_DEFINITIONS_BUILDIMAGES_SUFFIX:$TEST_INFRA_DEFINITIONS_BUILDIMAGES + image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/datadog-agent-buildimages/deb_x64$DATADOG_AGENT_BUILDIMAGES_SUFFIX:$DATADOG_AGENT_BUILDIMAGES tags: ["arch:amd64"] rules: - - !reference [.on_system_probe_or_e2e_changes_or_manual] - - !reference [.on_security_agent_changes_or_manual] - !reference [.except_mergequeue] - !reference [.except_main_or_release_branch] - !reference [.except_no_tests_no_deploy] + - !reference [.except_deploy] + - !reference [.on_system_probe_or_e2e_changes_or_manual] + - !reference [.on_security_agent_changes_or_manual] needs: # We need to specify the jobs that generate complexity explicitly, else we hit the limit of "needs" # Important: the list of platforms should match the one in .define_if_collect_complexity @@ -310,7 +311,8 @@ notify_ebpf_complexity_changes: TEST_SET: no_usm allow_failure: true before_script: - - python3 -m pip install tabulate # Required for printing the tables + - source /root/.bashrc + - python3 -m pip install tabulate # Required for printing the tables - python3 -m pip install -r tasks/libs/requirements-github.txt - | export GITHUB_KEY_B64=$($CI_PROJECT_DIR/tools/ci/aws_ssm_get_wrapper.sh $GITHUB_PR_COMMENTER_APP_KEY_SSM_NAME | base64) diff --git a/.gitlab/kitchen_deploy/kitchen_deploy.yml b/.gitlab/kitchen_deploy/kitchen_deploy.yml index c341e71bb6a14..4184c08c53f8b 100644 --- a/.gitlab/kitchen_deploy/kitchen_deploy.yml +++ b/.gitlab/kitchen_deploy/kitchen_deploy.yml @@ -281,7 +281,8 @@ deploy_suse_rpm_testing_arm64-a7: deploy_windows_testing-a6: rules: - !reference [.on_kitchen_tests] - - !reference [.on_windows_installer_changes_or_manual] + - !reference [.on_e2e_or_windows_installer_changes] + - !reference [.manual] stage: kitchen_deploy 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"] diff --git a/.gitlab/kitchen_testing/new-e2e_testing/docker.yml b/.gitlab/kitchen_testing/new-e2e_testing/docker.yml new file mode 100644 index 0000000000000..c7ef9c9303847 --- /dev/null +++ b/.gitlab/kitchen_testing/new-e2e_testing/docker.yml @@ -0,0 +1,15 @@ +new-e2e-agent-platform-install-script-docker: + stage: kitchen_testing + extends: + - .new_e2e_template + - .new_e2e_template_needs_deb_x64 + - .new-e2e_agent_a7 + - .new-e2e_install_script + rules: !reference [.on_default_new_e2e_tests] + variables: + E2E_ARCH: x86_64 + E2E_PLATFORM: "docker" + E2E_OSVERS: "none" + E2E_BRANCH_OSVERS: none + E2E_CWS_SUPPORTED_OSVERS: "none" + FLAVOR: "datadog-agent" diff --git a/.gitlab/kitchen_testing/new-e2e_testing/include.yml b/.gitlab/kitchen_testing/new-e2e_testing/include.yml index 30ab8be78521c..78c043739d7ee 100644 --- a/.gitlab/kitchen_testing/new-e2e_testing/include.yml +++ b/.gitlab/kitchen_testing/new-e2e_testing/include.yml @@ -9,3 +9,4 @@ include: - .gitlab/kitchen_testing/new-e2e_testing/centos.yml - .gitlab/kitchen_testing/new-e2e_testing/suse.yml - .gitlab/kitchen_testing/new-e2e_testing/windows.yml + - .gitlab/kitchen_testing/new-e2e_testing/docker.yml diff --git a/.gitlab/kitchen_testing/new-e2e_testing/windows.yml b/.gitlab/kitchen_testing/new-e2e_testing/windows.yml index 2b0dcbc1b6a58..a32253711ac08 100644 --- a/.gitlab/kitchen_testing/new-e2e_testing/windows.yml +++ b/.gitlab/kitchen_testing/new-e2e_testing/windows.yml @@ -114,7 +114,8 @@ new-e2e-windows-agent-msi-windows-server-a6-x86_64: - .new-e2e_windows_installer_v6_tests rules: - !reference [.on_deploy] - - !reference [.on_windows_installer_changes_or_manual] + - !reference [.on_e2e_or_windows_installer_changes] + - !reference [.manual] # Agent 7 .new-e2e_windows_a7_x86_64: @@ -135,7 +136,8 @@ new-e2e-windows-agent-msi-windows-server-a7-x86_64: - .new-e2e_windows_installer_v7_tests rules: - !reference [.on_deploy] - - !reference [.on_windows_installer_changes_or_manual] + - !reference [.on_e2e_or_windows_installer_changes] + - !reference [.manual] timeout: 1h15m new-e2e-windows-agent-domain-tests-a7-x86_64: @@ -151,7 +153,8 @@ new-e2e-windows-agent-domain-tests-a7-x86_64: - deploy_windows_testing-a7 rules: - !reference [.on_deploy] - - !reference [.on_windows_installer_changes_or_manual] + - !reference [.on_e2e_or_windows_installer_changes] + - !reference [.manual] timeout: 1h15 ## single test for PRs @@ -165,7 +168,6 @@ new-e2e-windows-agent-msi-upgrade-windows-server-a7-x86_64: - !reference [.except_main_or_release_branch] - !reference [.except_windows_installer_changes] - !reference [.on_default_new_e2e_tests] - # must be last since it ends with when: on_success - !reference [.except_deploy] variables: E2E_MSI_TEST: TestUpgrade diff --git a/.gitlab/source_test/golang_deps_diff.yml b/.gitlab/source_test/golang_deps_diff.yml index f0acd1b8b9076..5a01ac2d74a13 100644 --- a/.gitlab/source_test/golang_deps_diff.yml +++ b/.gitlab/source_test/golang_deps_diff.yml @@ -28,7 +28,8 @@ golang_deps_commenter: image: 486234852809.dkr.ecr.us-east-1.amazonaws.com/pr-commenter:2 tags: ["arch:amd64"] rules: # this should only run on dev branches - - !reference [ .except_main_or_release_branch ] + - !reference [.except_main_or_release_branch] + - !reference [.except_deploy] - when: on_success needs: ["golang_deps_diff"] script: # ignore error message about no PR, because it happens for dev branches without PRs diff --git a/.gitlab/source_test/macos.yml b/.gitlab/source_test/macos.yml index 84fea058c18b2..76adde53972bf 100644 --- a/.gitlab/source_test/macos.yml +++ b/.gitlab/source_test/macos.yml @@ -55,20 +55,12 @@ lint_macos: PYTHON_RUNTIMES: "3" # The Gitlab macOS runners are currently long runners, so we need to clean them beforehand. before_script: - # Remove the Go cache and env if the Go version changed + # Selecting the current Go version - | - GO_REPO_VERSION=$(cat .go-version) - GO_VERSION=$(go version | awk '{print $3}' | sed 's/go//') - if [ "$GO_REPO_VERSION" != "$GO_VERSION" ]; then - echo "Go version $GO_VERSION is different from $GO_REPO_VERSION in .go-version. Cleaning the environment." - go clean -cache -modcache -testcache - rm -rf $HOME/go/bin - echo "Installing Go $GO_REPO_VERSION..." - echo "$(gimme $(cat .go-version))" - eval $(gimme $(cat .go-version)) - else - echo "Go current version $GO_VERSION is the same as .go-version. Keeping the cache." - fi + eval $(gimme $(cat .go-version)) + export GOPATH=$GOROOT + echo "Don't forget to regularly delete unused versions. Here are the installed versions and their memory usage on the runner:" + du -sh $HOME/.gimme/versions/* # Remove the Python cache and env if the Python version changed - | PYTHON_REPO_VERSION=$(cat .python-version) diff --git a/.golangci.yml b/.golangci.yml index b74881792e806..a5860decf1f76 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -59,7 +59,512 @@ issues: # We are using it and it's not clear how to replace it. - text: "Temporary has been deprecated since Go 1.18" linters: [staticcheck] - + # Treat this list as a TODO for fixing issues with pkgconfigusage custom linter + # DO NOT ADD NEW ENTRIES + - path: comp/api/api/apiimpl/internal/config/endpoint.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/component.go + linters: + - pkgconfigusage + - path: comp/process/forwarders/forwardersimpl/forwarders.go + linters: + - pkgconfigusage + - path: comp/process/profiler/profilerimpl/profiler.go + linters: + - pkgconfigusage + - path: comp/logs/agent/agentimpl/agent.go + linters: + - pkgconfigusage + - path: comp/logs/agent/agentimpl/agent_core_init.go + linters: + - pkgconfigusage + - path: comp/logs/agent/agentimpl/serverless.go + linters: + - pkgconfigusage + - path: comp/logs/agent/agentimpl/agent_test.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/cloudfoundry/vm/cf_vm.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/kubemetadata/kubemetadata.go + linters: + - pkgconfigusage + - path: comp/trace/config/component.go + linters: + - pkgconfigusage + - path: comp/trace/config/config.go + linters: + - pkgconfigusage + - path: comp/trace/config/config_mock.go + linters: + - pkgconfigusage + - path: comp/trace/config/hostname.go + linters: + - pkgconfigusage + - path: comp/trace/config/remote.go + linters: + - pkgconfigusage + - path: comp/trace/config/setup.go + linters: + - pkgconfigusage + - path: comp/trace/config/config_test.go + linters: + - pkgconfigusage + - path: comp/remote-config/rcclient/rcclientimpl/rcclient.go + linters: + - pkgconfigusage + - path: comp/remote-config/rcclient/rcclientimpl/rcclient_test.go + linters: + - pkgconfigusage + - path: comp/agent/cloudfoundrycontainer/cloudfoundrycontainerimpl/cloudfoundrycontainer.go + linters: + - pkgconfigusage + - path: comp/metadata/internal/util/inventory_enabled.go + linters: + - pkgconfigusage + - path: comp/process/expvars/expvarsimpl/expvars.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/cloudfoundry/container/cf_container.go + linters: + - pkgconfigusage + - path: comp/api/api/apiimpl/listener.go + linters: + - pkgconfigusage + - path: comp/api/api/apiimpl/server.go + linters: + - pkgconfigusage + - path: comp/api/api/apiimpl/server_cmd.go + linters: + - pkgconfigusage + - path: comp/api/api/apiimpl/server_ipc.go + linters: + - pkgconfigusage + - path: comp/metadata/host/hostimpl/utils/common.go + linters: + - pkgconfigusage + - path: comp/metadata/host/hostimpl/utils/host.go + linters: + - pkgconfigusage + - path: comp/metadata/host/hostimpl/utils/meta.go + linters: + - pkgconfigusage + - path: comp/metadata/host/hostimpl/utils/host_test.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/remote/processcollector/process_collector.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/remote/processcollector/process_collector_test.go + linters: + - pkgconfigusage + - path: comp/aggregator/demultiplexer/demultiplexerimpl/test_agent_demultiplexer.go + linters: + - pkgconfigusage + - path: comp/metadata/host/hostimpl/host.go + linters: + - pkgconfigusage + - path: comp/metadata/host/hostimpl/payload.go + linters: + - pkgconfigusage + - path: comp/core/tagger/taggerimpl/collectors/ecs_common.go + linters: + - pkgconfigusage + - path: comp/core/tagger/taggerimpl/collectors/workloadmeta_extract.go + linters: + - pkgconfigusage + - path: comp/core/tagger/taggerimpl/collectors/workloadmeta_main.go + linters: + - pkgconfigusage + - path: comp/core/tagger/taggerimpl/collectors/ecs_common_test.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/kubelet/kubelet.go + linters: + - pkgconfigusage + - path: comp/metadata/inventoryotel/inventoryotelimpl/inventoryotel_test.go + linters: + - pkgconfigusage + - path: comp/metadata/host/hostimpl/hosttags/tags.go + linters: + - pkgconfigusage + - path: comp/metadata/host/hostimpl/hosttags/tags_test.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/listeners/ratelimit/mem_based_rate_limiter.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/cloudfoundry.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/clusterchecks.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/config_reader.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/consul.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/container.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/endpointschecks.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/etcd.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_endpoints.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_endpoints_file.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_services.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_services_file.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/prometheus_common.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/prometheus_pods.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/prometheus_services.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/providers.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/remote_config.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/utils.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/zookeeper.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/file_test.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_endpoints_test.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_services_test.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/prometheus_common_test.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/prometheus_services_test.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/utils_test.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/listeners/named_pipe_nowindows.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/listeners/udp.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/listeners/uds_common.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/listeners/uds_datagram.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/listeners/uds_stream.go + linters: + - pkgconfigusage + - path: comp/metadata/inventoryagent/inventoryagentimpl/inventoryagent_test.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/common/utils/container_collect_all.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/common/utils/prometheus.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/common/utils/prometheus_apiserver_test.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/common/utils/prometheus_kubelet_test.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/serverDebug/serverdebugimpl/debug.go + linters: + - pkgconfigusage + - path: comp/otelcol/otlp/collector_test.go + linters: + - pkgconfigusage + - path: comp/core/hostname/remotehostnameimpl/hostname.go + linters: + - pkgconfigusage + - path: comp/trace/agent/impl/agent.go + linters: + - pkgconfigusage + - path: comp/trace/agent/impl/run.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/server/batch.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/server/float64_list_pool.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/server/parse.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/server/server.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/server/serverless.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/server/server_bench_test.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/server/server_test.go + linters: + - pkgconfigusage + - path: comp/process/agent/agentimpl/agent.go + linters: + - pkgconfigusage + - path: comp/process/apiserver/apiserver.go + linters: + - pkgconfigusage + - path: comp/remote-config/rcservice/rcserviceimpl/rcservice.go + linters: + - pkgconfigusage + - path: comp/netflow/config/config_test.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/listeners/common.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/listeners/container.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/listeners/environment.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/listeners/kubelet.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/listeners/service.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/listeners/staticconfig.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/listeners/snmp_test.go + linters: + - pkgconfigusage + - path: comp/core/tagger/params.go + linters: + - pkgconfigusage + - path: comp/remote-config/rcservicemrf/rcservicemrfimpl/rcservicemrf.go + linters: + - pkgconfigusage + - path: comp/process/status/statusimpl/status.go + linters: + - pkgconfigusage + - path: comp/agent/jmxlogger/jmxloggerimpl/jmxlogger.go + linters: + - pkgconfigusage + - path: comp/core/tagger/taggerimpl/remote/tagger.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/mapper/mapper.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/mapper/mapper_test.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/remote/workloadmeta/workloadmeta.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/remote/workloadmeta/workloadmeta_test.go + linters: + - pkgconfigusage + - path: comp/forwarder/eventplatform/eventplatformimpl/epforwarder.go + linters: + - pkgconfigusage + - path: comp/core/gui/guiimpl/checks.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/replay/impl/capture.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/autodiscoveryimpl/autoconfig.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/autodiscoveryimpl/secrets.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/autodiscoveryimpl/autoconfig_test.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/packets/pool.go + linters: + - pkgconfigusage + - path: comp/process/agent/status.go + linters: + - pkgconfigusage + - path: comp/core/sysprobeconfig/component.go + linters: + - pkgconfigusage + - path: comp/core/tagger/taglist/taglist.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/remote/generic.go + linters: + - pkgconfigusage + - path: comp/core/hostname/hostnameimpl/service_test.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/status/status.go + linters: + - pkgconfigusage + - path: comp/core/sysprobeconfig/sysprobeconfigimpl/config.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/docker/docker.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/docker/image_sbom_trivy.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/containerd/containerd.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/containerd/image_sbom_trivy.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/containerd/network_linux.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/ecs/ecs.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/ecsfargate/ecsfargate.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/podman/podman.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/internal/process/process_collector.go + linters: + - pkgconfigusage + - path: comp/core/workloadmeta/collectors/util/process_util_linux.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/listeners/ratelimit/cgroup_memory_usage_linux.g + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/cloudfoundry_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/consul_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/endpointschecks_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/etcd_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_endpoints_file_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_endpoints_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_services_file_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_services_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/prometheus_pods_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/prometheus_services_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/zookeeper_nop.go + linters: + - pkgconfigusage + - path: comp/otelcol/otlp/no_otlp.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/cloudfoundry_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/consul_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/etcd_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_endpoints_file_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_endpoints_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_services_file_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_services_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/prometheus_services_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/zookeeper_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/cloudfoundry_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/endpointschecks_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_endpoints_file_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_endpoints_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_services_file_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/kube_services_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/prometheus_pods_nop.go + linters: + - pkgconfigusage + - path: comp/core/autodiscovery/providers/prometheus_services_nop.go + linters: + - pkgconfigusage + - path: comp/systray/systray/systrayimpl/doflare.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/listeners/named_pipe_windows.go + linters: + - pkgconfigusage + - path: comp/dogstatsd/packets/packet_manager_windows.go + linters: + - pkgconfigusage linters: disable-all: true enable: @@ -76,6 +581,7 @@ linters: - bodyclose # checks whether HTTP response body is closed successfully - gosimple # Linter for Go source code that specializes in simplifying code. - gocheckcompilerdirectives # Checks Go compiler directives syntax + - pkgconfigusage # Linter for checking usage of pkgconfig inside components folder linters-settings: depguard: @@ -98,9 +604,58 @@ linters-settings: desc: "Not really forbidden to use, but it is usually imported by mistake instead of github.com/stretchr/testify/assert, and confusing since it actually has the behavior of github.com/stretchr/testify/require" errcheck: - # Disable warnings for `fmt`, `log` and `seelog` packages. Also ignore `Write` functions from `net/http` package. - # Disable warnings for select Windows functions - ignore: fmt:.*,github.com/DataDog/datadog-agent/pkg/util/log:.*,github.com/DataDog/datadog-agent/comp/core/log/def:.*,github.com/DataDog/datadog-agent/comp/core/log/mock:.*,github.com/cihub/seelog:.*,net/http:Write,github.com/DataDog/datadog-agent/pkg/trace/metrics:.*,github.com/DataDog/datadog-agent/pkg/collector/corechecks:Warnf?,golang.org/x/sys/windows:(CloseHandle|FreeLibrary|FreeSid|RegCloseKey|SetEvent|LocalFree),syscall:CloseHandle,golang.org/x/sys/windows/svc/mgr:Disconnect,golang.org/x/sys/windows/svc/debug:(Close|Error|Info|Warning),github.com/lxn/walk:Dispose,github.com/DataDog/datadog-agent/comp/core/flare/types:(AddFile.*|CopyDir.*|CopyFile.*),github.com/DataDog/datadog-agent/comp/core/flare/builder:(AddFile.*|CopyDir.*|CopyFile.*),golang.org/x/sys/windows/registry:Close + exclude-functions: + - (*github.com/DataDog/datadog-agent/pkg/collector/corechecks.CheckBase).Warn + - (*github.com/DataDog/datadog-agent/pkg/collector/corechecks.CheckBase).Warnf + - (*github.com/lxn/walk.NotifyIcon).Dispose + - (*golang.org/x/sys/windows/svc/mgr.Mgr).Disconnect + - (github.com/DataDog/datadog-agent/comp/core/flare/builder.FlareBuilder).AddFile + - (github.com/DataDog/datadog-agent/comp/core/flare/builder.FlareBuilder).AddFileFromFunc + - (github.com/DataDog/datadog-agent/comp/core/flare/builder.FlareBuilder).AddFileWithoutScrubbing + - (github.com/DataDog/datadog-agent/comp/core/flare/builder.FlareBuilder).CopyDir + - (github.com/DataDog/datadog-agent/comp/core/flare/builder.FlareBuilder).CopyDirTo + - (github.com/DataDog/datadog-agent/comp/core/flare/builder.FlareBuilder).CopyDirToWithoutScrubbing + - (github.com/DataDog/datadog-agent/comp/core/flare/builder.FlareBuilder).CopyFile + - (github.com/DataDog/datadog-agent/comp/core/flare/builder.FlareBuilder).CopyFileTo + - (github.com/DataDog/datadog-agent/comp/core/log/def.Component).ChangeLogLevel + - (github.com/DataDog/datadog-agent/comp/core/log/def.Component).Critical + - (github.com/DataDog/datadog-agent/comp/core/log/def.Component).Criticalf + - (github.com/DataDog/datadog-agent/comp/core/log/def.Component).Error + - (github.com/DataDog/datadog-agent/comp/core/log/def.Component).Errorf + - (github.com/DataDog/datadog-agent/comp/core/log/def.Component).Warn + - (github.com/DataDog/datadog-agent/comp/core/log/def.Component).Warnf + - (net/http.ResponseWriter).Write + - fmt.Sscanf + - github.com/cihub/seelog.Warnf + - github.com/DataDog/datadog-agent/pkg/util/log.ChangeLogLevel + - github.com/DataDog/datadog-agent/pkg/util/log.Critical + - github.com/DataDog/datadog-agent/pkg/util/log.Criticalc + - github.com/DataDog/datadog-agent/pkg/util/log.Criticalf + - github.com/DataDog/datadog-agent/pkg/util/log.CriticalStackDepth + - github.com/DataDog/datadog-agent/pkg/util/log.Error + - github.com/DataDog/datadog-agent/pkg/util/log.Errorc + - github.com/DataDog/datadog-agent/pkg/util/log.Errorf + - github.com/DataDog/datadog-agent/pkg/util/log.ErrorStackDepth + - github.com/DataDog/datadog-agent/pkg/util/log.JMXError + - github.com/DataDog/datadog-agent/pkg/util/log.logContextWithError + - github.com/DataDog/datadog-agent/pkg/util/log.logFormatWithError + - github.com/DataDog/datadog-agent/pkg/util/log.Warn + - github.com/DataDog/datadog-agent/pkg/util/log.Warnc + - github.com/DataDog/datadog-agent/pkg/util/log.Warnf + - github.com/DataDog/datadog-agent/pkg/util/log.WarnStackDepth + - golang.org/x/sys/windows.CloseHandle + - golang.org/x/sys/windows.FreeLibrary + - golang.org/x/sys/windows.FreeSid + - golang.org/x/sys/windows.LocalFree + - golang.org/x/sys/windows.RegCloseKey + - golang.org/x/sys/windows.SetEvent + - golang.org/x/sys/windows/registry.Close + - golang.org/x/sys/windows/svc/debug.Close + - golang.org/x/sys/windows/svc/debug.Error + - golang.org/x/sys/windows/svc/debug.Info + - golang.org/x/sys/windows/svc/debug.Warning + - pkg/util/log.JMXError + - syscall.CloseHandle staticcheck: checks: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022", # These ones are disabled by default on staticcheck @@ -156,3 +711,7 @@ linters-settings: - name: var-naming # non-default rules: - name: duplicated-imports + custom: + pkgconfigusage: + type: "module" + description: "Check usage of pkgconfig in components folder" diff --git a/.vscode/settings.json.template b/.vscode/settings.json.template index 795843112176d..297be4f2f0200 100644 --- a/.vscode/settings.json.template +++ b/.vscode/settings.json.template @@ -3,9 +3,7 @@ "go.lintTool": "golangci-lint", "go.lintFlags": [ "--build-tags", - "{build_tags}", - "--config", - "{workspace_folder}/.golangci.yml" + "{build_tags}" ], "[go]": {{ "editor.formatOnSave": true, diff --git a/.wwhrd.yml b/.wwhrd.yml index b293d0db0a899..84cd078577d5b 100644 --- a/.wwhrd.yml +++ b/.wwhrd.yml @@ -45,5 +45,4 @@ exceptions: additional: # list here paths to additional licenses - golang/go: "raw.githubusercontent.com/golang/go/master/LICENSE" - \ No newline at end of file + golang/go: "raw.githubusercontent.com/golang/go/go1.22.6/LICENSE" diff --git a/CHANGELOG-DCA.rst b/CHANGELOG-DCA.rst index 5db2a8f04d80d..6c4acb405c730 100644 --- a/CHANGELOG-DCA.rst +++ b/CHANGELOG-DCA.rst @@ -2,6 +2,64 @@ Release Notes ============= +.. _Release Notes_7.56.0: + +7.56.0 +====== + +.. _Release Notes_7.56.0_Prelude: + +Prelude +------- + +Released on: 2024-08-16 +Pinned to datadog-agent v7.56.0: `CHANGELOG `_. + +.. _Release Notes_7.56.0_Upgrade Notes: + +Upgrade Notes +------------- + +- Disables default injection of the .NET profiler dependency for Kubernetes auto_instrumentation. + + +.. _Release Notes_7.56.0_Enhancement Notes: + +Enhancement Notes +----------------- + +- Mark the NetworkPolicy collector as stable in the Cluster Agent + +- Enabled language detection automatically in the injected agent sidecar on EKS Fargate when APM SSI is enabled. + This is only available for users using the admission controller to automatically inject the agent sidecar. + +- The orchestrator check can now scrub sensitive data from probes in pods specifications. + + +.. _Release Notes_7.56.0_Bug Fixes: + +Bug Fixes +--------- + +- Fixes issue where the external metrics server would sometimes return metrics which had not + been updated for longer than the configured `external_metrics_provider.max_age` as valid. + In connection with this fix, a new config (`external_metrics_provider.query_validity_period`) + has been added to account for the delay between when metrics are resolved and when they + are queried by the various autoscaling controllers. It is set to 30 seconds by default. + +.. _Release Notes_7.55.3: + +7.55.3 +================ + +.. _Release Notes_7.55.3_Prelude: + +Prelude +------- + +Released on: 2024-08-01 +Pinned to datadog-agent v7.55.3: `CHANGELOG `_. + .. _Release Notes_7.55.2: 7.55.2 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f1b7112a74497..075bf271c7b79 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,225 @@ Release Notes ============= +.. _Release Notes_7.56.0: + +7.56.0 +====== + +.. _Release Notes_7.56.0_Prelude: + +Prelude +------- + +Release on: 2024-08-16 + +- Please refer to the `7.56.0 tag on integrations-core `_ for the list of changes on the Core Checks + + +.. _Release Notes_7.56.0_Upgrade Notes: + +Upgrade Notes +------------- + +- Change default bind address in OTLP ingest from `0.0.0.0` to `localhost`. Please refer to the following blog post: https://opentelemetry.io/blog/2024/hardening-the-collector-one for additional information around this change. + +- Update cURL to 8.7.1. + + +.. _Release Notes_7.56.0_New Features: + +New Features +------------ + +- The core Agent now supports multiple configuration files in addition to the main ``datadog.yaml`` file. + The -E flag can be used to specify additional configuration files to be loaded sequentially after the main ``datadog.yaml``. + +- When ``DD_SERVERLESS_STREAM_LOGS`` is enabled, DD_EXTENSION + prints collected logs like ``agent stream-logs``. + +- Add full support of CIS Amazon Linux 2 Benchmark in CSPM. + +- Add full support of CIS Amazon Linux 2023 Benchmark in CSPM. + +- NPM - Adds the capability to track and report failed TCP connections to the Datadog backend. This feature is disabled by default. + + +.. _Release Notes_7.56.0_Enhancement Notes: + +Enhancement Notes +----------------- + +- Add the `use_apiserver_cache` option to the `kubernetes_state_metrics` check + to reduce the pressure on the underlying storage engine `etcd`. Requires Kubernetes 1.19+. + +- APM: Add obfuscation support for OpenSearch statements within span metadata. This feature works in the same way as the existing Elasticsearch one, and is enabled by default. It is configured by binding ``apm_config.obfuscation.opensearch.*`` parameters to new obfuscation environment variables. In particular, bind: + ``apm_config.obfuscation.opensearch.enabled`` to ``DD_APM_OBFUSCATION_OPENSEARCH_ENABLED``: + It accepts a boolean value with default value true. + + ``apm_config.obfuscation.opensearch.keep_values`` to ``DD_APM_OBFUSCATION_OPENSEARCH_KEEP_VALUES`` + It accepts a list of strings of the form ``["id1", "id2"]``. + + ``apm_config.obfuscation.opensearch.obfuscate_sql_values`` to ``DD_APM_OBFUSCATION_OPENSEARCH_OBFUSCATE_SQL_VALUES`` + It accepts a list of strings of the form ``["key1", "key2"]``. + +- Agents are now built with Go ``1.22.4``. + +- Agents are now built with Go ``1.22.5``. + +- Bump dependency `msodbcsql18` to version 18.3.3.1. + +- Adds config ``kubernetes_events_source_detection.enabled`` which is + false by default. When set to true, this sets the source of kubernetes + events to specific integrations based on the name of the controller + that emitted it. All kubernetes events will have the tag + ``orchestrator:kubernetes``. For controller names that do not match + any of the known integrations, the source will still be set to + ``kubernetes`` by default. + +- Introduces a ``bundle_unspecifed_events`` config to the ``docker`` integration. + When ``bundle_unspecifed_events`` and ``unbundle_events`` are true, + Docker events are unbundled according to ``collected_event_types`` and + the remaining events are bundled after excluding the ``filtered_event_types`` and ``collected_event_types``. + +- The Agent will now ignore empty configuration files in ``conf.d``. Users can + use this functionality to avoid creating broken integrations when deploying + agents with provisioning systems that do not allow skipping files entirely. + +- Introduces an ``bundle_unspecified_events`` config to the ``kubernetes_apiserver`` + integration. When ``bundle_unspecified_events`` and ``unbundle_events`` are true, + Kubernetes events are unbundled according to ``collected_event_types`` and + the remaining events are bundled. + +- Improve utility functions that start or stop a service to better manage the SERVICE_START_PENDING and SERVICE_STOP_PENDING states by waiting for the service transition to complete. This will improve handling of concurrent execution of `agent.exe start` and `agent.exe restart` commands for the Windows Agent. + +- Make the `oom_kill` check capture the OOM score and the OOM score adjustment of the process being killed. + +- Oracle integration will now auto-adjust the size of the SQL substring requested by the activity sampler + to better support users with multi-byte character sets, for example, Korean, Arabic, etc. This should + alleviate crashes caused by long queries using these characters. + +- The OTLP ingestion endpoint now supports the same settings and protocol as + the OpenTelemetry Collector OTLP receiver v0.103.0. + +- APM: Probabilistic Sampler now only looks at the lower 64 bits of a trace ID by default to improve compatibility in distributed systems where some apps may truncate the trace ID. To maintain the previous behavior use the feature flag `probabilistic_sampler_full_trace_id`. + +- Adds the source of the payload for Processes-owned messages. + +- Add tags to `CollectorManifest` + +- Add image and imageID fields to pods ContainerStatuses. + +- The orchestrator check can now scrub sensitive data from probes in pods specifications. + +- The Agent now populates the `git.repository_url` and `git.commit.sha` tags from the values of the `DD_GIT_REPOSITORY_URL` and `DD_GIT_COMMIT_SHA` container environment variables. + +- Implement the kubernetes_persistent_volume_claims_as_tags configuration that allows + users to disable PersistentVolumeClaim for Kubernetes resources. + +- Upgrade the NTP check client library 'beevik/ntp' from v0.3.0 to v1.3.4 + +- Use cloud-provided hostname as default when running the Agent + in AKS. + +- APM: Enabled zstd compression by default on trace payloads. + + +.. _Release Notes_7.56.0_Deprecation Notes: + +Deprecation Notes +----------------- + +- APM: DD_APM_MAX_TPS config setting is deprecated in favor of the more + accurate DD_APM_TARGET_TPS. Accordingly, when configured through YAML, + max_traces_per_second is deprecated in favor of target_traces_per_second. + The setting behavior remains the same, only the name is changed to more + accurately reflect the existing logic. + + +.. _Release Notes_7.56.0_Security Notes: + +Security Notes +-------------- + +- Updating OpenSSL to 3.0.14 to address CVE-2024-4741. + + +.. _Release Notes_7.56.0_Bug Fixes: + +Bug Fixes +--------- + +- Upgrades the pro-bing library to fix a Windows-only bug with too-long ICMP packets being received + +- Fix ExtraTags mapping for CollectorManifest. + +- Fix a bug in the Agent where it could potentially fetch logs of short-lived Kubernetes jobs twice if the CRI is Docker. + +- Re-enable printing of checks metadata in the ``datadog-agent status`` collector section. + +- Fix OTLP status output not being displayed in the GUI. + +- Fix issue where init config for ping took priority over instance config. + +- Fix ``diagnose`` command for logs endpoints and related warnings about unknown config keys. + +- Fixes `oracle.tablespace.offline` metric not emitting 1 when tablespace is offline. + +- APM: Show probabilistic sampling configuration in Agent status when enabled. + +- Add a field to differentiate between empty and undefined podSelector or namespaceSelector for network policies. + +- Fixed a bug where the file tailing position is always set to the beginning, this fix allows + users to explicitly set a starting position. + +- All datadog public endpoints have the maximum requirements to close idle + connections after 60s being idle. If a given client keeps it for longer, + the server will close it, and the client will likely see the issue during + the next write, leading to a connection reset error. The idle timeout + should be therefore set under a minute. + This PR is reducing the timeout from 90 to 30s. + +- Windows: Added driver rollback properties to ensure that all services and drivers are uninstalled or rolled back after an installation or upgrade failure. + + +.. _Release Notes_7.56.0_Other Notes: + +Other Notes +----------- + +- Add metric origins for community Python integrations. + +.. _Release Notes_7.55.3: + +7.55.3 +================ + +.. _Release Notes_7.55.3_Prelude: + +Prelude +------- + +Release on: 2024-08-01 + +- Please refer to the `7.55.3 tag on integrations-core `_ for the list of changes on the Core Checks + + +.. _Release Notes_7.55.3_Enhancement Notes: + +Enhancement Notes +----------------- + +- Agents are now built with Go ``1.21.12``. + + +.. _Release Notes_7.55.3_Security Notes: + +Security Notes +-------------- + +- Fix CVE-2024-41110. + + .. _Release Notes_7.55.2: 7.55.2 diff --git a/Dockerfiles/agent-ot/Dockerfile.byoc b/Dockerfiles/agent-ot/Dockerfile.agent-otel similarity index 96% rename from Dockerfiles/agent-ot/Dockerfile.byoc rename to Dockerfiles/agent-ot/Dockerfile.agent-otel index 04132bd129dfd..cb0fb6109e780 100644 --- a/Dockerfiles/agent-ot/Dockerfile.byoc +++ b/Dockerfiles/agent-ot/Dockerfile.agent-otel @@ -24,7 +24,7 @@ RUN apt-get update && \ && rm -rf /var/lib/apt/lists/* # TEMP: Use github source code -RUN git clone https://github.com/DataDog/datadog-agent.git datadog-agent-${AGENT_VERSION} +RUN git clone --depth 1 https://github.com/DataDog/datadog-agent.git datadog-agent-${AGENT_VERSION} # Once we have stable releases, we can use the following code to download the source code # TODO: use released agent version once we have an agent release with the otel binary diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 986ba0d282973..c84c5c02d527c 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -768,7 +768,6 @@ core,github.com/containerd/containerd/contrib/seccomp/kernelversion,Apache-2.0," core,github.com/containerd/containerd/defaults,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/containerd/diff,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/containerd/diff/proxy,Apache-2.0,"Copyright 2012-2015 Docker, Inc." -core,github.com/containerd/containerd/errdefs,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/containerd/events,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/containerd/events/exchange,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/containerd/filters,Apache-2.0,"Copyright 2012-2015 Docker, Inc." @@ -797,7 +796,6 @@ core,github.com/containerd/containerd/pkg/userns,Apache-2.0,"Copyright 2012-2015 core,github.com/containerd/containerd/platforms,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/containerd/plugin,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/containerd/protobuf,Apache-2.0,"Copyright 2012-2015 Docker, Inc." -core,github.com/containerd/containerd/protobuf/plugin,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/containerd/protobuf/proto,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/containerd/protobuf/types,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/containerd/reference,Apache-2.0,"Copyright 2012-2015 Docker, Inc." @@ -824,6 +822,7 @@ core,github.com/containerd/continuity/sysx,Apache-2.0,"Copyright 2012-2015 Docke core,github.com/containerd/errdefs,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/fifo,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/log,Apache-2.0,"Copyright 2012-2015 Docker, Inc." +core,github.com/containerd/platforms,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/stargz-snapshotter/estargz,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/stargz-snapshotter/estargz/errorutil,Apache-2.0,"Copyright 2012-2015 Docker, Inc." core,github.com/containerd/ttrpc,Apache-2.0,"Copyright 2012-2015 Docker, Inc." @@ -1611,6 +1610,7 @@ core,github.com/open-policy-agent/opa/topdown/print,Apache-2.0,Copyright 2016 Th core,github.com/open-policy-agent/opa/tracing,Apache-2.0,Copyright 2016 The OPA Authors. All rights reserved. core,github.com/open-policy-agent/opa/types,Apache-2.0,Copyright 2016 The OPA Authors. All rights reserved. core,github.com/open-policy-agent/opa/util,Apache-2.0,Copyright 2016 The OPA Authors. All rights reserved. +core,github.com/open-policy-agent/opa/util/decoding,Apache-2.0,Copyright 2016 The OPA Authors. All rights reserved. core,github.com/open-policy-agent/opa/version,Apache-2.0,Copyright 2016 The OPA Authors. All rights reserved. core,github.com/open-telemetry/opentelemetry-collector-contrib/connector/datadogconnector,Apache-2.0,Copyright The OpenTelemetry Authors core,github.com/open-telemetry/opentelemetry-collector-contrib/connector/datadogconnector/internal/metadata,Apache-2.0,Copyright The OpenTelemetry Authors @@ -2509,8 +2509,8 @@ core,go.opentelemetry.io/otel/metric/noop,Apache-2.0,Copyright The OpenTelemetry core,go.opentelemetry.io/otel/propagation,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/sdk,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/sdk/instrumentation,Apache-2.0,Copyright The OpenTelemetry Authors -core,go.opentelemetry.io/otel/sdk/internal,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/sdk/internal/env,Apache-2.0,Copyright The OpenTelemetry Authors +core,go.opentelemetry.io/otel/sdk/internal/x,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/sdk/metric,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/sdk/metric/internal,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/sdk/metric/internal/aggregate,Apache-2.0,Copyright The OpenTelemetry Authors @@ -2527,7 +2527,9 @@ core,go.opentelemetry.io/otel/semconv/v1.17.0,Apache-2.0,Copyright The OpenTelem core,go.opentelemetry.io/otel/semconv/v1.17.0/httpconv,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/semconv/v1.20.0,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/semconv/v1.21.0,Apache-2.0,Copyright The OpenTelemetry Authors +core,go.opentelemetry.io/otel/semconv/v1.24.0,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/semconv/v1.25.0,Apache-2.0,Copyright The OpenTelemetry Authors +core,go.opentelemetry.io/otel/semconv/v1.26.0,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/trace,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/trace/embedded,Apache-2.0,Copyright The OpenTelemetry Authors core,go.opentelemetry.io/otel/trace/noop,Apache-2.0,Copyright The OpenTelemetry Authors @@ -2542,6 +2544,7 @@ core,go.uber.org/automaxprocs/internal/cgroups,MIT,"Copyright (c) 2017 Uber Tech core,go.uber.org/automaxprocs/internal/runtime,MIT,"Copyright (c) 2017 Uber Technologies, Inc" core,go.uber.org/automaxprocs/maxprocs,MIT,"Copyright (c) 2017 Uber Technologies, Inc" core,go.uber.org/dig,MIT,"Copyright (c) 2017-2018 Uber Technologies, Inc" +core,go.uber.org/dig/internal/digclock,MIT,"Copyright (c) 2017-2018 Uber Technologies, Inc" core,go.uber.org/dig/internal/digerror,MIT,"Copyright (c) 2017-2018 Uber Technologies, Inc" core,go.uber.org/dig/internal/digreflect,MIT,"Copyright (c) 2017-2018 Uber Technologies, Inc" core,go.uber.org/dig/internal/dot,MIT,"Copyright (c) 2017-2018 Uber Technologies, Inc" @@ -2571,37 +2574,37 @@ core,go4.org/netipx,BSD-3-Clause,Alex Willmer | Copyright core,go4.org/unsafe/assume-no-moving-gc,BSD-3-Clause,"Copyright (c) 2020, Brad Fitzpatrick" core,golang.org/x/arch/arm64/arm64asm,BSD-3-Clause,Copyright 2015 The Go Authors core,golang.org/x/arch/x86/x86asm,BSD-3-Clause,Copyright 2015 The Go Authors -core,golang.org/x/crypto/argon2,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/bcrypt,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/blake2b,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/blowfish,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/cast5,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/chacha20,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved +core,golang.org/x/crypto/argon2,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/bcrypt,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/blake2b,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/blowfish,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/cast5,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/chacha20,BSD-3-Clause,Copyright 2009 The Go Authors core,golang.org/x/crypto/chacha20poly1305,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/cryptobyte,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/cryptobyte/asn1,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/curve25519,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/hkdf,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/internal/alias,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/internal/poly1305,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/nacl/secretbox,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/ocsp,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/openpgp,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/openpgp/armor,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/openpgp/elgamal,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/openpgp/errors,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/openpgp/packet,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/openpgp/s2k,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/pbkdf2,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/pkcs12,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/pkcs12/internal/rc2,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/salsa20/salsa,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/scrypt,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/sha3,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/ssh,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/ssh/agent,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/ssh/internal/bcrypt_pbkdf,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/crypto/ssh/knownhosts,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved +core,golang.org/x/crypto/cryptobyte,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/cryptobyte/asn1,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/curve25519,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/hkdf,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/internal/alias,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/internal/poly1305,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/nacl/secretbox,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/ocsp,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/openpgp,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/openpgp/armor,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/openpgp/elgamal,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/openpgp/errors,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/openpgp/packet,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/openpgp/s2k,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/pbkdf2,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/pkcs12,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/pkcs12/internal/rc2,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/salsa20/salsa,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/scrypt,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/sha3,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/ssh,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/ssh/agent,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/ssh/internal/bcrypt_pbkdf,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/crypto/ssh/knownhosts,BSD-3-Clause,Copyright 2009 The Go Authors core,golang.org/x/exp/constraints,BSD-3-Clause,Copyright 2009 The Go Authors core,golang.org/x/exp/maps,BSD-3-Clause,Copyright 2009 The Go Authors core,golang.org/x/exp/mmap,BSD-3-Clause,Copyright 2009 The Go Authors @@ -2612,29 +2615,29 @@ core,golang.org/x/exp/slog/internal/buffer,BSD-3-Clause,Copyright 2009 The Go Au core,golang.org/x/exp/typeparams,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved | Copyright 2009 The Go Authors core,golang.org/x/lint,BSD-3-Clause,Copyright (c) 2013 The Go Authors. All rights reserved core,golang.org/x/lint/golint,BSD-3-Clause,Copyright (c) 2013 The Go Authors. All rights reserved -core,golang.org/x/net/bpf,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/context,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/html,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/html/atom,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/html/charset,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/http/httpguts,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/http/httpproxy,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/http2,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/http2/h2c,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/http2/hpack,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/icmp,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/idna,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/internal/iana,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/internal/socket,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/internal/socks,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/internal/timeseries,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/ipv4,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/ipv6,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/netutil,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/proxy,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/publicsuffix,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/trace,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/net/websocket,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved +core,golang.org/x/net/bpf,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/context,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/html,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/html/atom,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/html/charset,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/http/httpguts,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/http/httpproxy,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/http2,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/http2/h2c,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/http2/hpack,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/icmp,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/idna,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/internal/iana,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/internal/socket,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/internal/socks,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/internal/timeseries,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/ipv4,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/ipv6,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/netutil,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/proxy,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/publicsuffix,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/trace,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/net/websocket,BSD-3-Clause,Copyright 2009 The Go Authors core,golang.org/x/oauth2,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved core,golang.org/x/oauth2/authhandler,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved core,golang.org/x/oauth2/clientcredentials,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved @@ -2658,41 +2661,41 @@ core,golang.org/x/sys/windows/registry,BSD-3-Clause,Copyright 2009 The Go Author core,golang.org/x/sys/windows/svc,BSD-3-Clause,Copyright 2009 The Go Authors core,golang.org/x/sys/windows/svc/eventlog,BSD-3-Clause,Copyright 2009 The Go Authors core,golang.org/x/sys/windows/svc/mgr,BSD-3-Clause,Copyright 2009 The Go Authors -core,golang.org/x/term,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/cases,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding/charmap,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding/htmlindex,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding/ianaindex,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding/internal,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding/internal/identifier,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding/japanese,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding/korean,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding/simplifiedchinese,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding/traditionalchinese,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/encoding/unicode,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/feature/plural,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/internal,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/internal/catmsg,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/internal/format,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/internal/language,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/internal/language/compact,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/internal/number,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/internal/stringset,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/internal/tag,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/internal/utf8internal,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/language,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/message,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/message/catalog,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/runes,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/secure/bidirule,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/secure/precis,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/transform,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/unicode/bidi,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/unicode/norm,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved -core,golang.org/x/text/width,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved +core,golang.org/x/term,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/cases,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding/charmap,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding/htmlindex,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding/ianaindex,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding/internal,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding/internal/identifier,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding/japanese,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding/korean,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding/simplifiedchinese,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding/traditionalchinese,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/encoding/unicode,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/feature/plural,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/internal,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/internal/catmsg,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/internal/format,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/internal/language,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/internal/language/compact,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/internal/number,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/internal/stringset,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/internal/tag,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/internal/utf8internal,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/language,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/message,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/message/catalog,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/runes,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/secure/bidirule,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/secure/precis,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/transform,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/unicode/bidi,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/unicode/norm,BSD-3-Clause,Copyright 2009 The Go Authors +core,golang.org/x/text/width,BSD-3-Clause,Copyright 2009 The Go Authors core,golang.org/x/time/rate,BSD-3-Clause,Copyright 2009 The Go Authors -core,golang/go,BSD-Source-Code,Copyright (c) 2009 The Go Authors. All rights reserved. +core,golang/go,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved. core,gomodules.xyz/jsonpatch/v2,Apache-2.0,Copyright (c) 2015 The Authors core,gonum.org/v1/gonum/blas,BSD-3-Clause,Alexander Egurnov | Andrei Blinnikov | Andrew Brampton | Bailey Lissington | Bill Gray | Bill Noon | Brendan Tracey | Brent Pedersen | Bulat Khasanov | Chad Kunde | Chan Kwan Yin | Chih-Wei Chang | Chong-Yeol Nah | Chris Tessum | Christophe Meessen | Christopher Waldon | Clayton Northey | Copyright ©2013 The Gonum Authors. All rights reserved | Dan Kortschak | Dan Lorenc | Daniel Fireman | Dario Heinisch | David Kleiven | David Samborski | Davor Kapsa | DeepMind Technologies | Delaney Gillilan | Dezmond Goff | Dong-hee Na | Dustin Spicuzza | Egon Elbre | Ekaterina Efimova | Eng Zer Jun | Ethan Burns | Ethan Reesor | Evert Lammerts | Evgeny Savinov | Fabian Wickborn | Facundo Gaich | Fazlul Shahriar | Francesc Campoy | Google Inc | Gustaf Johansson | Hossein Zolfi | Iakov Davydov | Igor Mikushkin | Iskander Sharipov | Jalem Raj Rohit | James Bell | James Bowman | James Holmes <32bitkid@gmail.com> | Janne Snabb | Jeremy Atkinson | Jes Cok | Jinesi Yelizati | Jon Richards | Jonas Kahler | Jonas Schulze | Jonathan Bluett-Duncan | Jonathan J Lawlor | Jonathan Reiter | Jonathan Schroeder | Joost van Amersfoort | Jordan Stoker | Joseph Watson | Josh Wilson | Julien Roland | Kai Trukenmüller | Kent English | Kevin C. Zimmerman | Kirill Motkov | Konstantin Shaposhnikov | Leonid Kneller | Lyron Winderbaum | Marco Leogrande | Mark Canning | Mark Skilbeck | Martin Diz | Matthew Connelly | Matthieu Di Mercurio | Max Halford | Maxim Sergeev | Microsoft Corporation | MinJae Kwon | Nathan Edwards | Nick Potts | Nils Wogatzky | Olivier Wulveryck | Or Rikon | Patricio Whittingslow | Patrick DeVivo | Pontus Melke | Renee French | Rishi Desai | Robin Eklind | Roger Welin | Roman Werpachowski | Rondall Jones | Sam Zaydel | Samuel Kelemen | Saran Ahluwalia | Scott Holden | Scott Kiesel | Sebastien Binet | Shawn Smith | Sintela Ltd | Spencer Lyon | Steve McCoy | Taesu Pyo | Takeshi Yoneda | Tamir Hyman | The University of Adelaide | The University of Minnesota | The University of Washington | Thomas Berg | Tobin Harding | Valentin Deleplace | Vincent Thiery | Vladimír Chalupecký | Will Tekulve | Yasuhiro Matsumoto | Yevgeniy Vahlis | Yucheng Zhu | Yunomi | Zoe Juozapaitis | antichris | source{d} core,gonum.org/v1/gonum/blas/blas64,BSD-3-Clause,Alexander Egurnov | Andrei Blinnikov | Andrew Brampton | Bailey Lissington | Bill Gray | Bill Noon | Brendan Tracey | Brent Pedersen | Bulat Khasanov | Chad Kunde | Chan Kwan Yin | Chih-Wei Chang | Chong-Yeol Nah | Chris Tessum | Christophe Meessen | Christopher Waldon | Clayton Northey | Copyright ©2013 The Gonum Authors. All rights reserved | Dan Kortschak | Dan Lorenc | Daniel Fireman | Dario Heinisch | David Kleiven | David Samborski | Davor Kapsa | DeepMind Technologies | Delaney Gillilan | Dezmond Goff | Dong-hee Na | Dustin Spicuzza | Egon Elbre | Ekaterina Efimova | Eng Zer Jun | Ethan Burns | Ethan Reesor | Evert Lammerts | Evgeny Savinov | Fabian Wickborn | Facundo Gaich | Fazlul Shahriar | Francesc Campoy | Google Inc | Gustaf Johansson | Hossein Zolfi | Iakov Davydov | Igor Mikushkin | Iskander Sharipov | Jalem Raj Rohit | James Bell | James Bowman | James Holmes <32bitkid@gmail.com> | Janne Snabb | Jeremy Atkinson | Jes Cok | Jinesi Yelizati | Jon Richards | Jonas Kahler | Jonas Schulze | Jonathan Bluett-Duncan | Jonathan J Lawlor | Jonathan Reiter | Jonathan Schroeder | Joost van Amersfoort | Jordan Stoker | Joseph Watson | Josh Wilson | Julien Roland | Kai Trukenmüller | Kent English | Kevin C. Zimmerman | Kirill Motkov | Konstantin Shaposhnikov | Leonid Kneller | Lyron Winderbaum | Marco Leogrande | Mark Canning | Mark Skilbeck | Martin Diz | Matthew Connelly | Matthieu Di Mercurio | Max Halford | Maxim Sergeev | Microsoft Corporation | MinJae Kwon | Nathan Edwards | Nick Potts | Nils Wogatzky | Olivier Wulveryck | Or Rikon | Patricio Whittingslow | Patrick DeVivo | Pontus Melke | Renee French | Rishi Desai | Robin Eklind | Roger Welin | Roman Werpachowski | Rondall Jones | Sam Zaydel | Samuel Kelemen | Saran Ahluwalia | Scott Holden | Scott Kiesel | Sebastien Binet | Shawn Smith | Sintela Ltd | Spencer Lyon | Steve McCoy | Taesu Pyo | Takeshi Yoneda | Tamir Hyman | The University of Adelaide | The University of Minnesota | The University of Washington | Thomas Berg | Tobin Harding | Valentin Deleplace | Vincent Thiery | Vladimír Chalupecký | Will Tekulve | Yasuhiro Matsumoto | Yevgeniy Vahlis | Yucheng Zhu | Yunomi | Zoe Juozapaitis | antichris | source{d} @@ -2894,12 +2897,17 @@ core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/config,Apache-2.0,"Copyrigh core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec/types,Apache-2.0,"Copyright 2016-Present Datadog, Inc." +core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/ossec,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/sharedsec,Apache-2.0,"Copyright 2016-Present Datadog, Inc." +core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/sqlsec/types,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/httpsec,Apache-2.0,"Copyright 2016-Present Datadog, Inc." +core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/ossec,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/sharedsec,Apache-2.0,"Copyright 2016-Present Datadog, Inc." +core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/sqlsec,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/trace,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/trace/httptrace,Apache-2.0,"Copyright 2016-Present Datadog, Inc." +core,gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/hostname,Apache-2.0,"Copyright 2016-Present Datadog, Inc." @@ -2913,6 +2921,7 @@ core,gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/validate,Apache-2.0,"Copy core,gopkg.in/DataDog/dd-trace-go.v1/internal/log,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/normalizer,Apache-2.0,"Copyright 2016-Present Datadog, Inc." +core,gopkg.in/DataDog/dd-trace-go.v1/internal/orchestrion,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/remoteconfig,Apache-2.0,"Copyright 2016-Present Datadog, Inc." core,gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames,Apache-2.0,"Copyright 2016-Present Datadog, Inc." diff --git a/README.md b/README.md index 9c06f45c19e29..7f40e410c1b4f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![GoDoc](https://godoc.org/github.com/DataDog/datadog-agent?status.svg)](https://godoc.org/github.com/DataDog/datadog-agent) [![Go Report Card](https://goreportcard.com/badge/github.com/DataDog/datadog-agent)](https://goreportcard.com/report/github.com/DataDog/datadog-agent) -The present repository contains the source code of the Datadog Agent version 7 and version 6. Please refer to the [Agent user documentation](docs/agent) for information about differences between Agent v5, Agent v6 and Agent v7. Additionally, we provide a list of prepackaged binaries for an easy install process [here](https://app.datadoghq.com/account/settings/agent/latest?platform=overview) +The present repository contains the source code of the Datadog Agent version 7 and version 6. Please refer to the [Agent user documentation](https://docs.datadoghq.com/agent/) for information about differences between Agent v5, Agent v6 and Agent v7. Additionally, we provide a list of prepackaged binaries for an easy install process [here](https://app.datadoghq.com/account/settings/agent/latest?platform=overview) **Note:** the source code of Datadog Agent v5 is located in the [dd-agent](https://github.com/DataDog/dd-agent) repository. @@ -73,7 +73,7 @@ To start working on the Agent, you can build the `main` branch: If you built an older version of the agent, you may have the error `make: *** No targets specified and no makefile found. Stop.`. To solve the issue, you should remove `CMakeCache.txt` from `rtloader` folder with `rm rtloader/CMakeCache.txt`. - Please note that the [trace agent](./docs/trace-agent/README.md) needs to be built and run separately. + Please note that the [trace agent](https://docs.datadoghq.com/tracing/trace_collection/) needs to be built and run separately. diff --git a/cmd/agent/common/import_test.go b/cmd/agent/common/import_test.go index b6472c40875b1..2be52bf7fcd46 100644 --- a/cmd/agent/common/import_test.go +++ b/cmd/agent/common/import_test.go @@ -17,6 +17,7 @@ import ( "gopkg.in/yaml.v2" "github.com/DataDog/datadog-agent/pkg/config/legacy" + "github.com/DataDog/datadog-agent/pkg/config/mock" ) func TestBasicMinCollectionIntervalRelocation(t *testing.T) { @@ -73,6 +74,7 @@ func TestImport(t *testing.T) { } func RunImport(t *testing.T, integrations []string) { + mock.New(t) a6ConfDir := t.TempDir() a5ConfDir := path.Join(".", "tests", "a5_conf") a6RefConfDir := path.Join(".", "tests", "a6_conf") diff --git a/cmd/agent/common/misconfig/mounts.go b/cmd/agent/common/misconfig/mounts.go index 313de5f6423dc..4fe51cf3ea17f 100644 --- a/cmd/agent/common/misconfig/mounts.go +++ b/cmd/agent/common/misconfig/mounts.go @@ -19,6 +19,7 @@ import ( "github.com/syndtr/gocapability/capability" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/log" ) @@ -68,7 +69,7 @@ func procMount() error { groups = append(groups, egid) } path := config.Datadog().GetString("container_proc_root") - if config.IsContainerized() && path != "/proc" { + if env.IsContainerized() && path != "/proc" { path = filepath.Join(path, "1/mounts") } else { path = filepath.Join(path, "mounts") diff --git a/cmd/agent/common/path/go.mod b/cmd/agent/common/path/go.mod index cbc72e9e1cfbc..34395125a6eb4 100644 --- a/cmd/agent/common/path/go.mod +++ b/cmd/agent/common/path/go.mod @@ -13,13 +13,12 @@ require ( github.com/DataDog/datadog-agent/pkg/util/executable v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/util/log v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/util/winutil v0.56.0-rc.3 - golang.org/x/sys v0.23.0 + golang.org/x/sys v0.24.0 ) require ( github.com/DataDog/datadog-agent/pkg/util/scrubber v0.56.0-rc.3 // indirect github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect go.uber.org/atomic v1.11.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/cmd/agent/common/path/go.sum b/cmd/agent/common/path/go.sum index e34b1d17f405f..fce5903d8ae50 100644 --- a/cmd/agent/common/path/go.sum +++ b/cmd/agent/common/path/go.sum @@ -2,8 +2,6 @@ github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1 github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo= 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/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -12,8 +10,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/cmd/agent/dist/conf.d/oracle.d/conf.yaml.example b/cmd/agent/dist/conf.d/oracle.d/conf.yaml.example index bda2888e09b13..b60bf263ed8b0 100644 --- a/cmd/agent/dist/conf.d/oracle.d/conf.yaml.example +++ b/cmd/agent/dist/conf.d/oracle.d/conf.yaml.example @@ -134,6 +134,12 @@ instances: # # enabled: true + ## @param active_session_history - boolean - optional - default: false + ## Collect activity samples from `v$active_session_history` instead of the Agent performing sampling. + ## WARNING: Querying `v$active_session_history` requires optional Oracle licences and may result in additional costs if enabled. + # + # active_session_history: false + ## Configure collection of query metrics # # query_metrics: diff --git a/cmd/agent/install_script.sh b/cmd/agent/install_script.sh index 27b1b3fb58ee0..04a89fdb615cb 100755 --- a/cmd/agent/install_script.sh +++ b/cmd/agent/install_script.sh @@ -9,9 +9,9 @@ set -e echo -e "\033[33m install_script.sh is deprecated. Please use one of - - * https://s3.amazonaws.com/dd-agent/scripts/install_script_agent6.sh to install Agent 6 - * https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh to install Agent 7 + + * https://install.datadoghq.com/scripts/install_script_agent6.sh to install Agent 6 + * https://install.datadoghq.com/scripts/install_script_agent7.sh to install Agent 7 \033[0m" install_script_version=1.13.0.deprecated diff --git a/cmd/agent/subcommands/diagnose/command.go b/cmd/agent/subcommands/diagnose/command.go index b5ab789ca094e..9710f8298329f 100644 --- a/cmd/agent/subcommands/diagnose/command.go +++ b/cmd/agent/subcommands/diagnose/command.go @@ -95,15 +95,12 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { core.Bundle(), // workloadmeta setup wmcatalog.GetCatalog(), - fx.Provide(func() workloadmeta.Params { - return workloadmeta.Params{ - AgentType: workloadmeta.NodeAgent, - InitHelper: common.GetWorkloadmetaInit(), - NoInstance: !cliParams.runLocal, - } + workloadmetafx.Module(workloadmeta.Params{ + AgentType: workloadmeta.NodeAgent, + InitHelper: common.GetWorkloadmetaInit(), + NoInstance: !cliParams.runLocal, }), fx.Supply(optional.NewNoneOption[collector.Component]()), - workloadmetafx.Module(), taggerimpl.Module(), fx.Provide(func(config config.Component) tagger.Params { return tagger.NewTaggerParamsForCoreAgent(config) }), autodiscoveryimpl.Module(), diff --git a/cmd/agent/subcommands/dogstatsdstats/command.go b/cmd/agent/subcommands/dogstatsdstats/command.go index 5b5cfdbbd43ff..c8c12ce29f9da 100644 --- a/cmd/agent/subcommands/dogstatsdstats/command.go +++ b/cmd/agent/subcommands/dogstatsdstats/command.go @@ -9,6 +9,7 @@ package dogstatsdstats import ( "bytes" "encoding/json" + "errors" "fmt" "os" @@ -88,7 +89,7 @@ func requestDogstatsdStats(_ log.Component, config config.Component, cliParams * json.Unmarshal(r, &errMap) //nolint:errcheck // If the error has been marshalled into a json object, check it and return it properly if err, found := errMap["error"]; found { - e = fmt.Errorf(err) + e = errors.New(err) } if len(errMap["error_type"]) > 0 { diff --git a/cmd/agent/subcommands/flare/command.go b/cmd/agent/subcommands/flare/command.go index 04fb9572349ee..d990b2aabe11c 100644 --- a/cmd/agent/subcommands/flare/command.go +++ b/cmd/agent/subcommands/flare/command.go @@ -108,7 +108,7 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { SysprobeConfigParams: sysprobeconfigimpl.NewParams(sysprobeconfigimpl.WithSysProbeConfFilePath(globalParams.SysProbeConfFilePath), sysprobeconfigimpl.WithFleetPoliciesDirPath(globalParams.FleetPoliciesDirPath)), LogParams: log.ForOneShot(command.LoggerName, "off", false), }), - fx.Supply(flare.NewLocalParams( + flare.Module(flare.NewLocalParams( commonpath.GetDistPath(), commonpath.PyChecksPath, commonpath.DefaultLogFile, @@ -118,17 +118,13 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { )), // workloadmeta setup wmcatalog.GetCatalog(), - fx.Provide(func() workloadmeta.Params { - return workloadmeta.Params{ - AgentType: workloadmeta.NodeAgent, - InitHelper: common.GetWorkloadmetaInit(), - NoInstance: !cliParams.forceLocal, //if forceLocal is true, we want to run workloadmeta - } + workloadmetafx.Module(workloadmeta.Params{ + AgentType: workloadmeta.NodeAgent, + InitHelper: common.GetWorkloadmetaInit(), + NoInstance: !cliParams.forceLocal, //if forceLocal is true, we want to run workloadmeta }), - workloadmetafx.Module(), taggerimpl.OptionalModule(), autodiscoveryimpl.OptionalModule(), // if forceLocal is true, we will start autodiscovery (loadComponents) later - flare.Module(), fx.Supply(optional.NewNoneOption[collector.Component]()), compressionimpl.Module(), diagnosesendermanagerimpl.Module(), diff --git a/cmd/agent/subcommands/flare/command_test.go b/cmd/agent/subcommands/flare/command_test.go index 83a7d595de005..5dbeeb2c68376 100644 --- a/cmd/agent/subcommands/flare/command_test.go +++ b/cmd/agent/subcommands/flare/command_test.go @@ -22,7 +22,6 @@ import ( "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/core/flare" "github.com/DataDog/datadog-agent/comp/core/secrets" - "github.com/DataDog/datadog-agent/pkg/config" configmock "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) @@ -99,7 +98,7 @@ func (c *commandTestSuite) TestReadProfileData() { mockConfig.SetWithoutSource("process_config.expvar_port", port) mockConfig.SetWithoutSource("security_agent.expvar_port", port) - mockSysProbeConfig := config.MockSystemProbe(t) + mockSysProbeConfig := configmock.NewSystemProbe(t) mockSysProbeConfig.SetWithoutSource("system_probe_config.enabled", true) if runtime.GOOS == "windows" { mockSysProbeConfig.SetWithoutSource("system_probe_config.sysprobe_socket", u.Host) @@ -167,7 +166,7 @@ func (c *commandTestSuite) TestReadProfileDataNoTraceAgent() { mockConfig.SetWithoutSource("process_config.expvar_port", port) mockConfig.SetWithoutSource("security_agent.expvar_port", port) - mockSysProbeConfig := config.MockSystemProbe(t) + mockSysProbeConfig := configmock.NewSystemProbe(t) mockSysProbeConfig.SetWithoutSource("system_probe_config.enabled", true) if runtime.GOOS == "windows" { mockSysProbeConfig.SetWithoutSource("system_probe_config.sysprobe_socket", u.Host) diff --git a/cmd/agent/subcommands/integrations/command.go b/cmd/agent/subcommands/integrations/command.go index 9bcf4b7dc63a1..867f85bfa945b 100644 --- a/cmd/agent/subcommands/integrations/command.go +++ b/cmd/agent/subcommands/integrations/command.go @@ -860,7 +860,7 @@ func moveConfigurationFiles(srcFolder string, dstFolder string) error { ))) } if errorMsg != "" { - return fmt.Errorf(errorMsg) + return errors.New(errorMsg) } return nil } diff --git a/cmd/agent/subcommands/jmx/command.go b/cmd/agent/subcommands/jmx/command.go index 9c8f4425f4df2..6ae802311346f 100644 --- a/cmd/agent/subcommands/jmx/command.go +++ b/cmd/agent/subcommands/jmx/command.go @@ -48,6 +48,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/tagger/taggerimpl" wmcatalog "github.com/DataDog/datadog-agent/comp/core/workloadmeta/collectors/catalog" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + "github.com/DataDog/datadog-agent/comp/core/workloadmeta/defaults" workloadmetafx "github.com/DataDog/datadog-agent/comp/core/workloadmeta/fx" "github.com/DataDog/datadog-agent/comp/dogstatsd/pidmap" replay "github.com/DataDog/datadog-agent/comp/dogstatsd/replay/def" @@ -57,7 +58,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/aggregator/sender" "github.com/DataDog/datadog-agent/pkg/cli/standalone" pkgcollector "github.com/DataDog/datadog-agent/pkg/collector" - pkgconfig "github.com/DataDog/datadog-agent/pkg/config" "github.com/DataDog/datadog-agent/pkg/config/model" "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/DataDog/datadog-agent/pkg/util/optional" @@ -134,10 +134,7 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { }), // workloadmeta setup wmcatalog.GetCatalog(), - fx.Supply(workloadmeta.Params{ - InitHelper: common.GetWorkloadmetaInit(), - }), - workloadmetafx.Module(), + workloadmetafx.Module(defaults.DefaultParams()), apiimpl.Module(), authtokenimpl.Module(), // The jmx command do not have settings that change are runtime @@ -304,7 +301,7 @@ func runJmxCommandConsole(config config.Component, // This prevents log-spam from "comp/core/workloadmeta/collectors/internal/remote/process_collector/process_collector.go" // It appears that this collector creates some contention in AD. // Disabling it is both more efficient and gets rid of this log spam - pkgconfig.Datadog().Set("language_detection.enabled", "false", model.SourceAgentRuntime) + config.Set("language_detection.enabled", "false", model.SourceAgentRuntime) senderManager, err := diagnoseSendermanager.LazyGetSenderManager() if err != nil { diff --git a/cmd/agent/subcommands/launchgui/command.go b/cmd/agent/subcommands/launchgui/command.go index c88c53f5a98a0..d50475a0c7e5c 100644 --- a/cmd/agent/subcommands/launchgui/command.go +++ b/cmd/agent/subcommands/launchgui/command.go @@ -8,6 +8,7 @@ package launchgui import ( "fmt" + "net" "github.com/spf13/cobra" "go.uber.org/fx" @@ -18,6 +19,7 @@ import ( log "github.com/DataDog/datadog-agent/comp/core/log/def" apiutil "github.com/DataDog/datadog-agent/pkg/api/util" "github.com/DataDog/datadog-agent/pkg/util/fxutil" + "github.com/DataDog/datadog-agent/pkg/util/system" ) // cliParams are the command-line arguments for this subcommand @@ -53,6 +55,14 @@ func launchGui(config config.Component, _ *cliParams, _ log.Component) error { return fmt.Errorf("GUI not enabled: to enable, please set an appropriate port in your datadog.yaml file") } + // 'http://localhost' is preferred over 'http://127.0.0.1' due to Internet Explorer behavior. + // Internet Explorer High Security Level does not support setting cookies via HTTP Header response. + // By default, 'http://localhost' is categorized as an "intranet" website, which is considered safer and allowed to use cookies. This is not the case for 'http://127.0.0.1'. + guiHost, err := system.IsLocalAddress(config.GetString("GUI_host")) + if err != nil { + return fmt.Errorf("GUI server host is not a local address: %s", err) + } + endpoint, err := apiutil.NewIPCEndpoint(config, "/agent/gui/intent") if err != nil { return err @@ -63,12 +73,14 @@ func launchGui(config config.Component, _ *cliParams, _ log.Component) error { return err } + guiAddress := net.JoinHostPort(guiHost, guiPort) + // Open the GUI in a browser, passing the authorization tokens as parameters - err = open("http://127.0.0.1:" + guiPort + "/auth?intent=" + string(intentToken)) + err = open("http://" + guiAddress + "/auth?intent=" + string(intentToken)) if err != nil { - return fmt.Errorf("error opening GUI: " + err.Error()) + return fmt.Errorf("error opening GUI: %s", err.Error()) } - fmt.Printf("GUI opened at 127.0.0.1:" + guiPort + "\n") + fmt.Printf("GUI opened at %s\n", guiAddress) return nil } diff --git a/cmd/agent/subcommands/run/command.go b/cmd/agent/subcommands/run/command.go index a9c3abf98056c..37a197d47fcc9 100644 --- a/cmd/agent/subcommands/run/command.go +++ b/cmd/agent/subcommands/run/command.go @@ -66,6 +66,7 @@ import ( "github.com/DataDog/datadog-agent/comp/agent/cloudfoundrycontainer" healthprobe "github.com/DataDog/datadog-agent/comp/core/healthprobe/def" healthprobefx "github.com/DataDog/datadog-agent/comp/core/healthprobe/fx" + lsof "github.com/DataDog/datadog-agent/comp/core/lsof/fx" "github.com/DataDog/datadog-agent/comp/core/secrets" "github.com/DataDog/datadog-agent/comp/core/settings" "github.com/DataDog/datadog-agent/comp/core/settings/settingsimpl" @@ -327,7 +328,7 @@ func run(log log.Component, func getSharedFxOption() fx.Option { return fx.Options( - fx.Supply(flare.NewParams( + flare.Module(flare.NewParams( path.GetDistPath(), path.PyChecksPath, path.DefaultLogFile, @@ -335,13 +336,12 @@ func getSharedFxOption() fx.Option { path.DefaultDogstatsDLogFile, path.DefaultStreamlogsLogFile, )), - flare.Module(), core.Bundle(), + lsof.Module(), fx.Supply(dogstatsdServer.Params{ Serverless: false, }), - forwarder.Bundle(), - fx.Provide(func(config config.Component, log log.Component) defaultforwarder.Params { + forwarder.BundleWithProvider(func(config config.Component, log log.Component) defaultforwarder.Params { params := defaultforwarder.NewParams(config, log) // Enable core agent specific features like persistence-to-disk params.Options.EnabledFeatures = defaultforwarder.SetFeature(params.Options.EnabledFeatures, defaultforwarder.CoreFeatures) @@ -350,8 +350,7 @@ func getSharedFxOption() fx.Option { // workloadmeta setup wmcatalog.GetCatalog(), - fx.Provide(defaults.DefaultParams), - workloadmetafx.Module(), + workloadmetafx.Module(defaults.DefaultParams()), fx.Supply( status.Params{ PythonVersionGetFunc: python.GetPythonVersion, @@ -434,8 +433,7 @@ func getSharedFxOption() fx.Option { }), orchestratorForwarderImpl.Module(), fx.Supply(orchestratorForwarderImpl.NewDefaultParams()), - eventplatformimpl.Module(), - fx.Supply(eventplatformimpl.NewDefaultParams()), + eventplatformimpl.Module(eventplatformimpl.NewDefaultParams()), eventplatformreceiverimpl.Module(), // injecting the shared Serializer to FX until we migrate it to a proper component. This allows other @@ -446,9 +444,6 @@ func getSharedFxOption() fx.Option { fx.Provide(func(ms serializer.MetricSerializer) optional.Option[serializer.MetricSerializer] { return optional.NewOption[serializer.MetricSerializer](ms) }), - fx.Provide(func(logReceiver integrations.Component) optional.Option[integrations.Component] { - return optional.NewOption[integrations.Component](logReceiver) - }), ndmtmp.Bundle(), netflow.Bundle(), rdnsquerierfx.Module(), diff --git a/cmd/agent/subcommands/run/internal/settings/runtime_settings_test.go b/cmd/agent/subcommands/run/internal/settings/runtime_settings_test.go index d3cedca0e6afe..a710a4b259306 100644 --- a/cmd/agent/subcommands/run/internal/settings/runtime_settings_test.go +++ b/cmd/agent/subcommands/run/internal/settings/runtime_settings_test.go @@ -47,8 +47,7 @@ func TestDogstatsdMetricsStats(t *testing.T) { demultiplexerimpl.MockModule(), dogstatsd.Bundle(), defaultforwarder.MockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) s := DsdStatsRuntimeSetting{ diff --git a/cmd/agent/subcommands/snmp/command.go b/cmd/agent/subcommands/snmp/command.go index 4459a7d3a7263..53848d363e43a 100644 --- a/cmd/agent/subcommands/snmp/command.go +++ b/cmd/agent/subcommands/snmp/command.go @@ -190,14 +190,12 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { LogParams: log.ForOneShot(command.LoggerName, "off", true)}), core.Bundle(), aggregator.Bundle(), - forwarder.Bundle(), - eventplatformimpl.Module(), + forwarder.BundleWithProvider(defaultforwarder.NewParams), + eventplatformimpl.Module(eventplatformimpl.NewDefaultParams()), eventplatformreceiverimpl.Module(), orchestratorimpl.Module(), fx.Provide( - defaultforwarder.NewParams, orchestratorimpl.NewDefaultParams, - eventplatformimpl.NewDefaultParams, demultiplexerimpl.NewDefaultParams, ), ) diff --git a/cmd/cluster-agent-cloudfoundry/subcommands/run/command.go b/cmd/cluster-agent-cloudfoundry/subcommands/run/command.go index 2a9b94afa8c40..9b8494e8781f7 100644 --- a/cmd/cluster-agent-cloudfoundry/subcommands/run/command.go +++ b/cmd/cluster-agent-cloudfoundry/subcommands/run/command.go @@ -83,22 +83,19 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { LogParams: log.ForDaemon(command.LoggerName, "log_file", path.DefaultDCALogFile), }), core.Bundle(), - forwarder.Bundle(), - fx.Provide(defaultforwarder.NewParamsWithResolvers), + forwarder.BundleWithProvider(defaultforwarder.NewParamsWithResolvers), compressionimpl.Module(), demultiplexerimpl.Module(), orchestratorForwarderImpl.Module(), fx.Supply(orchestratorForwarderImpl.NewDisabledParams()), - eventplatformimpl.Module(), - fx.Supply(eventplatformimpl.NewDisabledParams()), + eventplatformimpl.Module(eventplatformimpl.NewDisabledParams()), eventplatformreceiverimpl.Module(), fx.Supply(demultiplexerimpl.NewDefaultParams()), // setup workloadmeta wmcatalog.GetCatalog(), - fx.Supply(workloadmeta.Params{ + workloadmetafx.Module(workloadmeta.Params{ InitHelper: common.GetWorkloadmetaInit(), }), // TODO(components): check what this must be for cluster-agent-cloudfoundry - workloadmetafx.Module(), fx.Provide(tagger.NewTaggerParams), taggerimpl.Module(), collectorimpl.Module(), diff --git a/cmd/cluster-agent/api/v1/languagedetection/util_test.go b/cmd/cluster-agent/api/v1/languagedetection/util_test.go index e6c48c98629e1..65685b3578494 100644 --- a/cmd/cluster-agent/api/v1/languagedetection/util_test.go +++ b/cmd/cluster-agent/api/v1/languagedetection/util_test.go @@ -300,8 +300,7 @@ func TestOwnersLanguagesFlush(t *testing.T) { mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) err := ownersLanguages.flush(mockStore) @@ -401,8 +400,7 @@ func TestOwnersLanguagesMergeAndFlush(t *testing.T) { mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) err := ownersLanguages.flush(mockStore) @@ -483,8 +481,7 @@ func TestCleanExpiredLanguages(t *testing.T) { mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) mockStore.Push(workloadmeta.SourceLanguageDetectionServer, workloadmeta.Event{ @@ -578,8 +575,7 @@ func TestHandleKubeAPIServerUnsetEvents(t *testing.T) { mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) ownersLanguages := OwnersLanguages{ diff --git a/cmd/cluster-agent/subcommands/start/command.go b/cmd/cluster-agent/subcommands/start/command.go index 896e4ff9a2618..8d35057f9aa31 100644 --- a/cmd/cluster-agent/subcommands/start/command.go +++ b/cmd/cluster-agent/subcommands/start/command.go @@ -134,8 +134,7 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { LogParams: log.ForDaemon(command.LoggerName, "log_file", path.DefaultDCALogFile), }), core.Bundle(), - forwarder.Bundle(), - fx.Provide(func(config config.Component, log log.Component) defaultforwarder.Params { + forwarder.BundleWithProvider(func(config config.Component, log log.Component) defaultforwarder.Params { params := defaultforwarder.NewParamsWithResolvers(config, log) params.Options.DisableAPIKeyChecking = true return params @@ -144,18 +143,16 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { demultiplexerimpl.Module(), orchestratorForwarderImpl.Module(), fx.Supply(orchestratorForwarderImpl.NewDefaultParams()), - eventplatformimpl.Module(), - fx.Supply(eventplatformimpl.NewDisabledParams()), + eventplatformimpl.Module(eventplatformimpl.NewDisabledParams()), eventplatformreceiverimpl.Module(), fx.Supply(demultiplexerimpl.NewDefaultParams()), // setup workloadmeta wmcatalog.GetCatalog(), - fx.Supply(workloadmeta.Params{ + workloadmetafx.Module(workloadmeta.Params{ InitHelper: common.GetWorkloadmetaInit(), AgentType: workloadmeta.ClusterAgent, }), // TODO(components): check what this must be for cluster-agent-cloudfoundry fx.Supply(context.Background()), - workloadmetafx.Module(), fx.Provide(tagger.NewTaggerParams), taggerimpl.Module(), fx.Supply( diff --git a/cmd/cluster-agent/subcommands/status/command.go b/cmd/cluster-agent/subcommands/status/command.go index 5d547bec4c6fd..7f4e3084cb6f8 100644 --- a/cmd/cluster-agent/subcommands/status/command.go +++ b/cmd/cluster-agent/subcommands/status/command.go @@ -11,6 +11,7 @@ package status import ( "bytes" "encoding/json" + "errors" "fmt" "net/url" "os" @@ -96,7 +97,7 @@ func run(log log.Component, config config.Component, cliParams *cliParams) error json.Unmarshal(r, &errMap) //nolint:errcheck // If the error has been marshalled into a json object, check it and return it properly if err, found := errMap["error"]; found { - e = fmt.Errorf(err) + e = errors.New(err) } fmt.Printf(` diff --git a/cmd/dogstatsd/subcommands/start/command.go b/cmd/dogstatsd/subcommands/start/command.go index 5110d9c4244b8..42898c1f47236 100644 --- a/cmd/dogstatsd/subcommands/start/command.go +++ b/cmd/dogstatsd/subcommands/start/command.go @@ -65,7 +65,8 @@ import ( ) type CLIParams struct { - confPath string + confPath string + socketPath string } type DogstatsdComponents struct { @@ -93,10 +94,7 @@ func MakeCommand(defaultLogFile string) *cobra.Command { // local flags startCmd.PersistentFlags().StringVarP(&cliParams.confPath, "cfgpath", "c", "", "path to directory containing datadog.yaml") - - var socketPath string - startCmd.Flags().StringVarP(&socketPath, "socket", "s", "", "listen to this socket instead of UDP") - pkgconfig.Datadog().BindPFlag("dogstatsd_socket", startCmd.Flags().Lookup("socket")) //nolint:errcheck + startCmd.PersistentFlags().StringVarP(&cliParams.socketPath, "socket", "s", "", "listen to this socket instead of UDP") return startCmd } @@ -109,15 +107,23 @@ func RunDogstatsdFct(cliParams *CLIParams, defaultConfPath string, defaultLogFil params := &Params{ DefaultLogFile: defaultLogFile, } + + configOptions := []func(*config.Params){ + config.WithConfFilePath(cliParams.confPath), + config.WithConfigMissingOK(true), + config.WithConfigName("dogstatsd"), + } + if cliParams.socketPath != "" { + configOptions = append(configOptions, config.WithCLIOverride("dogstatsd_socket", cliParams.socketPath)) + } + return fxutil.OneShot(fct, fx.Supply(cliParams), fx.Supply(params), fx.Supply(config.NewParams( defaultConfPath, - config.WithConfFilePath(cliParams.confPath), - config.WithConfigMissingOK(true), - config.WithConfigName("dogstatsd")), - ), + configOptions..., + )), fx.Provide(func(comp secrets.Component) optional.Option[secrets.Component] { return optional.NewOption[secrets.Component](comp) }), @@ -130,11 +136,10 @@ func RunDogstatsdFct(cliParams *CLIParams, defaultConfPath string, defaultLogFil Serverless: false, }), dogstatsd.Bundle(), - forwarder.Bundle(), - fx.Provide(defaultforwarder.NewParams), + forwarder.BundleWithProvider(defaultforwarder.NewParams), // workloadmeta setup wmcatalog.GetCatalog(), - fx.Provide(func(config config.Component) workloadmeta.Params { + workloadmetafx.ModuleWithProvider(func(config config.Component) workloadmeta.Params { catalog := workloadmeta.NodeAgent instantiate := config.GetBool("dogstatsd_origin_detection") @@ -144,16 +149,15 @@ func RunDogstatsdFct(cliParams *CLIParams, defaultConfPath string, defaultLogFil NoInstance: !instantiate, } }), - workloadmetafx.Module(), + compressionimpl.Module(), demultiplexerimpl.Module(), secretsimpl.Module(), orchestratorForwarderImpl.Module(), fx.Supply(orchestratorForwarderImpl.NewDisabledParams()), - eventplatformimpl.Module(), + eventplatformimpl.Module(eventplatformimpl.NewDisabledParams()), eventplatformreceiverimpl.Module(), hostnameimpl.Module(), - fx.Supply(eventplatformimpl.NewDisabledParams()), taggerimpl.OptionalModule(), // injecting the shared Serializer to FX until we migrate it to a prpoper component. This allows other // already migrated components to request it. diff --git a/cmd/otel-agent/subcommands/run/command.go b/cmd/otel-agent/subcommands/run/command.go index 598df7de5d71f..f6071025dcd89 100644 --- a/cmd/otel-agent/subcommands/run/command.go +++ b/cmd/otel-agent/subcommands/run/command.go @@ -93,10 +93,9 @@ func (o *orchestratorinterfaceimpl) Reset() { func runOTelAgentCommand(ctx context.Context, params *subcommands.GlobalParams, opts ...fx.Option) error { err := fxutil.Run( - forwarder.Bundle(), + forwarder.BundleWithProvider(newForwarderParams), logtracefx.Module(), inventoryagentimpl.Module(), - workloadmetafx.Module(), fx.Supply(metricsclient.NewStatsdClientWrapper(&ddgostatsd.NoOpClient{})), fx.Provide(func(client *metricsclient.StatsdClientWrapper) statsd.Component { return statsd.NewOTelStatsd(client) @@ -118,9 +117,7 @@ func runOTelAgentCommand(ctx context.Context, params *subcommands.GlobalParams, pkgconfigenv.DetectFeatures(c) return c, nil }), - fx.Provide(func() workloadmeta.Params { - return workloadmeta.NewParams() - }), + workloadmetafx.Module(workloadmeta.NewParams()), fx.Provide(func() []string { return append(params.ConfPaths, params.Sets...) }), @@ -154,7 +151,6 @@ func runOTelAgentCommand(ctx context.Context, params *subcommands.GlobalParams, return hn, nil }), - fx.Provide(newForwarderParams), fx.Provide(func(c defaultforwarder.Component) (defaultforwarder.Forwarder, error) { return defaultforwarder.Forwarder(c), nil }), diff --git a/cmd/process-agent/command/command.go b/cmd/process-agent/command/command.go index dd31c658ac54f..649a1c21cf614 100644 --- a/cmd/process-agent/command/command.go +++ b/cmd/process-agent/command/command.go @@ -19,6 +19,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/secrets" "github.com/DataDog/datadog-agent/comp/core/sysprobeconfig/sysprobeconfigimpl" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/filesystem" ) @@ -130,7 +131,7 @@ func SetHostMountEnv(logger log.Component) { // Set default values for proc/sys paths if unset. // Generally only applicable for container-only cases like Fargate. // This is primarily used by gopsutil to correlate cpu metrics with host processes - if !config.IsContainerized() || !filesystem.FileExists("/host") { + if !env.IsContainerized() || !filesystem.FileExists("/host") { return } diff --git a/cmd/process-agent/command/main_common.go b/cmd/process-agent/command/main_common.go index 8b567e6d4dfc7..45c1c6abc4e23 100644 --- a/cmd/process-agent/command/main_common.go +++ b/cmd/process-agent/command/main_common.go @@ -137,12 +137,8 @@ func runApp(ctx context.Context, globalParams *GlobalParams) error { // Provide process agent bundle so fx knows where to find components process.Bundle(), - // Provide ep forwarder bundle so fx knows where to find components - fx.Provide(func() eventplatformimpl.Params { - return eventplatformimpl.NewDefaultParams() - }), eventplatformreceiverimpl.Module(), - eventplatformimpl.Module(), + eventplatformimpl.Module(eventplatformimpl.NewDefaultParams()), // Provide network path bundle networkpath.Bundle(), @@ -150,9 +146,6 @@ func runApp(ctx context.Context, globalParams *GlobalParams) error { // Provide remote config client bundle remoteconfig.Bundle(), - // Provide workloadmeta module - workloadmetafx.Module(), - // Provide tagger module taggerimpl.Module(), @@ -174,7 +167,9 @@ func runApp(ctx context.Context, globalParams *GlobalParams) error { // Provide the corresponding workloadmeta Params to configure the catalog wmcatalog.GetCatalog(), - fx.Provide(func(c config.Component) workloadmeta.Params { + + // Provide workloadmeta module + workloadmetafx.ModuleWithProvider(func(c config.Component) workloadmeta.Params { var catalog workloadmeta.AgentType if c.GetBool("process_config.remote_workloadmeta") { diff --git a/cmd/process-agent/subcommands/check/check.go b/cmd/process-agent/subcommands/check/check.go index 811ee4c49d444..d91447f346d19 100644 --- a/cmd/process-agent/subcommands/check/check.go +++ b/cmd/process-agent/subcommands/check/check.go @@ -120,15 +120,14 @@ func MakeCommand(globalParamsGetter func() *command.GlobalParams, name string, a fx.Supply(cliParams, bundleParams), core.Bundle(), // Provide workloadmeta module - workloadmetafx.Module(), + // Provide eventplatformimpl module eventplatformreceiverimpl.Module(), - eventplatformimpl.Module(), - fx.Supply(eventplatformimpl.NewDefaultParams()), + eventplatformimpl.Module(eventplatformimpl.NewDefaultParams()), npcollectorimpl.Module(), // Provide the corresponding workloadmeta Params to configure the catalog wmcatalog.GetCatalog(), - fx.Provide(func(config config.Component) workloadmeta.Params { + workloadmetafx.ModuleWithProvider(func(config config.Component) workloadmeta.Params { var catalog workloadmeta.AgentType if config.GetBool("process_config.remote_workloadmeta") { diff --git a/cmd/security-agent/main_windows.go b/cmd/security-agent/main_windows.go index 2beb6a6683538..2a1563f34f160 100644 --- a/cmd/security-agent/main_windows.go +++ b/cmd/security-agent/main_windows.go @@ -115,8 +115,7 @@ func (s *service) Run(svcctx context.Context) error { // workloadmeta setup wmcatalog.GetCatalog(), - workloadmetafx.Module(), - fx.Provide(func(config config.Component) workloadmeta.Params { + workloadmetafx.ModuleWithProvider(func(config config.Component) workloadmeta.Params { catalog := workloadmeta.NodeAgent diff --git a/cmd/security-agent/subcommands/runtime/activity_dump.go b/cmd/security-agent/subcommands/runtime/activity_dump.go index 158a42648cf6b..46465a0986dd2 100644 --- a/cmd/security-agent/subcommands/runtime/activity_dump.go +++ b/cmd/security-agent/subcommands/runtime/activity_dump.go @@ -134,7 +134,7 @@ func generateDumpCommands(globalParams *command.GlobalParams) []*cobra.Command { activityDumpGenerateDumpCmd := &cobra.Command{ Use: "dump", Short: "generate an activity dump", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, _ []string) error { return fxutil.OneShot(generateActivityDump, fx.Supply(cliParams), fx.Supply(core.BundleParams{ diff --git a/cmd/security-agent/subcommands/start/command.go b/cmd/security-agent/subcommands/start/command.go index 0dc49ef83a48d..c4cf04e4a0dc0 100644 --- a/cmd/security-agent/subcommands/start/command.go +++ b/cmd/security-agent/subcommands/start/command.go @@ -103,8 +103,7 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { dogstatsd.ClientBundle, // workloadmeta setup wmcatalog.GetCatalog(), - workloadmetafx.Module(), - fx.Provide(func(config config.Component) workloadmeta.Params { + workloadmetafx.ModuleWithProvider(func(config config.Component) workloadmeta.Params { catalog := workloadmeta.NodeAgent if config.GetBool("security_agent.remote_workloadmeta") { catalog = workloadmeta.Remote diff --git a/cmd/security-agent/subcommands/status/command.go b/cmd/security-agent/subcommands/status/command.go index d64a016f6b0af..5b03ffac1913d 100644 --- a/cmd/security-agent/subcommands/status/command.go +++ b/cmd/security-agent/subcommands/status/command.go @@ -9,6 +9,7 @@ package status import ( "bytes" "encoding/json" + "errors" "fmt" "net/url" "os" @@ -94,7 +95,7 @@ func runStatus(_ log.Component, config config.Component, _ secrets.Component, pa json.Unmarshal(r, &errMap) //nolint:errcheck // If the error has been marshalled into a json object, check it and return it properly if err, found := errMap["error"]; found { - e = fmt.Errorf(err) + e = errors.New(err) } fmt.Printf(` diff --git a/cmd/security-agent/subcommands/workloadlist/command_test.go b/cmd/security-agent/subcommands/workloadlist/command_test.go index 4843c181a5f60..31b30b76d1d06 100644 --- a/cmd/security-agent/subcommands/workloadlist/command_test.go +++ b/cmd/security-agent/subcommands/workloadlist/command_test.go @@ -25,10 +25,7 @@ func TestWorkloadListCommand(t *testing.T) { } func TestWorkloadURL(t *testing.T) { - cfg := fxutil.Test[config.Component](t, fx.Options( - config.MockModule(), - // fx.Replace(config.MockParams{Overrides: overrides}), - )) + cfg := config.NewMock(t) expected := "https://localhost:5010/agent/workload-list?verbose=true" got, err := workloadURL(cfg, true) diff --git a/cmd/serverless-init/main.go b/cmd/serverless-init/main.go index b1d28cad4611f..00516dcef3466 100644 --- a/cmd/serverless-init/main.go +++ b/cmd/serverless-init/main.go @@ -67,7 +67,6 @@ func main() { err := fxutil.OneShot( run, autodiscoveryimpl.Module(), - workloadmetafx.Module(), fx.Provide(func(config coreconfig.Component) healthprobeDef.Options { return healthprobeDef.Options{ Port: config.GetInt("health_port"), @@ -76,7 +75,7 @@ func main() { }), taggerimpl.Module(), healthprobeFx.Module(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafx.Module(workloadmeta.NewParams()), fx.Supply(tagger.NewTaggerParams()), fx.Supply(coreconfig.NewParams("", coreconfig.WithConfigMissingOK(true))), coreconfig.Module(), diff --git a/cmd/serverless/dependencies_linux_amd64.txt b/cmd/serverless/dependencies_linux_amd64.txt index 16be4684f5886..f98339f3fd574 100644 --- a/cmd/serverless/dependencies_linux_amd64.txt +++ b/cmd/serverless/dependencies_linux_amd64.txt @@ -110,6 +110,7 @@ github.com/DataDog/datadog-agent/comp/logs/agent/agentimpl github.com/DataDog/datadog-agent/comp/logs/agent/config github.com/DataDog/datadog-agent/comp/logs/agent/flare github.com/DataDog/datadog-agent/comp/logs/integrations/def +github.com/DataDog/datadog-agent/comp/logs/integrations/impl github.com/DataDog/datadog-agent/comp/metadata/host/hostimpl/hosttags github.com/DataDog/datadog-agent/comp/metadata/inventoryagent github.com/DataDog/datadog-agent/comp/otelcol/otlp @@ -156,6 +157,7 @@ github.com/DataDog/datadog-agent/pkg/logs/client/tcp github.com/DataDog/datadog-agent/pkg/logs/diagnostic github.com/DataDog/datadog-agent/pkg/logs/internal/decoder github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection +github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens github.com/DataDog/datadog-agent/pkg/logs/internal/framer github.com/DataDog/datadog-agent/pkg/logs/internal/parsers github.com/DataDog/datadog-agent/pkg/logs/internal/parsers/dockerfile @@ -707,8 +709,8 @@ go.opentelemetry.io/otel/metric/noop go.opentelemetry.io/otel/propagation go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/sdk/instrumentation -go.opentelemetry.io/otel/sdk/internal go.opentelemetry.io/otel/sdk/internal/env +go.opentelemetry.io/otel/sdk/internal/x go.opentelemetry.io/otel/sdk/metric go.opentelemetry.io/otel/sdk/metric/internal go.opentelemetry.io/otel/sdk/metric/internal/aggregate @@ -720,7 +722,9 @@ go.opentelemetry.io/otel/sdk/trace go.opentelemetry.io/otel/sdk/trace/tracetest go.opentelemetry.io/otel/semconv/v1.17.0 go.opentelemetry.io/otel/semconv/v1.20.0 +go.opentelemetry.io/otel/semconv/v1.24.0 go.opentelemetry.io/otel/semconv/v1.25.0 +go.opentelemetry.io/otel/semconv/v1.26.0 go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded go.opentelemetry.io/otel/trace/noop @@ -735,6 +739,7 @@ go.uber.org/automaxprocs/internal/cgroups go.uber.org/automaxprocs/internal/runtime go.uber.org/automaxprocs/maxprocs go.uber.org/dig +go.uber.org/dig/internal/digclock go.uber.org/dig/internal/digerror go.uber.org/dig/internal/digreflect go.uber.org/dig/internal/dot @@ -760,6 +765,7 @@ go/token golang.org/x/exp/constraints golang.org/x/exp/maps golang.org/x/exp/slices +golang.org/x/mod/semver golang.org/x/net/http/httpguts golang.org/x/net/http/httpproxy golang.org/x/net/http2 @@ -924,6 +930,7 @@ gopkg.in/DataDog/dd-trace-go.v1/internal gopkg.in/DataDog/dd-trace-go.v1/internal/appsec gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/config gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo +gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig gopkg.in/DataDog/dd-trace-go.v1/internal/hostname @@ -937,6 +944,7 @@ gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/validate gopkg.in/DataDog/dd-trace-go.v1/internal/log gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema gopkg.in/DataDog/dd-trace-go.v1/internal/normalizer +gopkg.in/DataDog/dd-trace-go.v1/internal/orchestrion gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo gopkg.in/DataDog/dd-trace-go.v1/internal/remoteconfig gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames @@ -962,6 +970,7 @@ log/internal log/slog log/slog/internal log/slog/internal/buffer +maps math math/big math/bits diff --git a/cmd/serverless/dependencies_linux_arm64.txt b/cmd/serverless/dependencies_linux_arm64.txt index 4493cef9488ae..9a3c5a03c120d 100644 --- a/cmd/serverless/dependencies_linux_arm64.txt +++ b/cmd/serverless/dependencies_linux_arm64.txt @@ -110,6 +110,7 @@ github.com/DataDog/datadog-agent/comp/logs/agent/agentimpl github.com/DataDog/datadog-agent/comp/logs/agent/config github.com/DataDog/datadog-agent/comp/logs/agent/flare github.com/DataDog/datadog-agent/comp/logs/integrations/def +github.com/DataDog/datadog-agent/comp/logs/integrations/impl github.com/DataDog/datadog-agent/comp/metadata/host/hostimpl/hosttags github.com/DataDog/datadog-agent/comp/metadata/inventoryagent github.com/DataDog/datadog-agent/comp/otelcol/otlp @@ -156,6 +157,7 @@ github.com/DataDog/datadog-agent/pkg/logs/client/tcp github.com/DataDog/datadog-agent/pkg/logs/diagnostic github.com/DataDog/datadog-agent/pkg/logs/internal/decoder github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection +github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens github.com/DataDog/datadog-agent/pkg/logs/internal/framer github.com/DataDog/datadog-agent/pkg/logs/internal/parsers github.com/DataDog/datadog-agent/pkg/logs/internal/parsers/dockerfile @@ -706,8 +708,8 @@ go.opentelemetry.io/otel/metric/noop go.opentelemetry.io/otel/propagation go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/sdk/instrumentation -go.opentelemetry.io/otel/sdk/internal go.opentelemetry.io/otel/sdk/internal/env +go.opentelemetry.io/otel/sdk/internal/x go.opentelemetry.io/otel/sdk/metric go.opentelemetry.io/otel/sdk/metric/internal go.opentelemetry.io/otel/sdk/metric/internal/aggregate @@ -719,7 +721,9 @@ go.opentelemetry.io/otel/sdk/trace go.opentelemetry.io/otel/sdk/trace/tracetest go.opentelemetry.io/otel/semconv/v1.17.0 go.opentelemetry.io/otel/semconv/v1.20.0 +go.opentelemetry.io/otel/semconv/v1.24.0 go.opentelemetry.io/otel/semconv/v1.25.0 +go.opentelemetry.io/otel/semconv/v1.26.0 go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded go.opentelemetry.io/otel/trace/noop @@ -734,6 +738,7 @@ go.uber.org/automaxprocs/internal/cgroups go.uber.org/automaxprocs/internal/runtime go.uber.org/automaxprocs/maxprocs go.uber.org/dig +go.uber.org/dig/internal/digclock go.uber.org/dig/internal/digerror go.uber.org/dig/internal/digreflect go.uber.org/dig/internal/dot @@ -759,6 +764,7 @@ go/token golang.org/x/exp/constraints golang.org/x/exp/maps golang.org/x/exp/slices +golang.org/x/mod/semver golang.org/x/net/http/httpguts golang.org/x/net/http/httpproxy golang.org/x/net/http2 @@ -923,6 +929,7 @@ gopkg.in/DataDog/dd-trace-go.v1/internal gopkg.in/DataDog/dd-trace-go.v1/internal/appsec gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/config gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo +gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig gopkg.in/DataDog/dd-trace-go.v1/internal/hostname @@ -936,6 +943,7 @@ gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/validate gopkg.in/DataDog/dd-trace-go.v1/internal/log gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema gopkg.in/DataDog/dd-trace-go.v1/internal/normalizer +gopkg.in/DataDog/dd-trace-go.v1/internal/orchestrion gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo gopkg.in/DataDog/dd-trace-go.v1/internal/remoteconfig gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames @@ -961,6 +969,7 @@ log/internal log/slog log/slog/internal log/slog/internal/buffer +maps math math/big math/bits diff --git a/cmd/serverless/main.go b/cmd/serverless/main.go index 30362d11943c3..c1be0ce2f8edb 100644 --- a/cmd/serverless/main.go +++ b/cmd/serverless/main.go @@ -386,22 +386,25 @@ func handleTerminationSignals(serverlessDaemon *daemon.Daemon, stopCh chan struc } func setupLogger() { + logLevel := "error" + if userLogLevel := os.Getenv(logLevelEnvVar); len(userLogLevel) > 0 { + if seelogLogLevel, err := log.ValidateLogLevel(userLogLevel); err == nil { + logLevel = seelogLogLevel + } else { + log.Errorf("Invalid log level '%s', using default log level '%s'", userLogLevel, logLevel) + } + } + // init the logger configuring it to not log in a file (the first empty string) if err := config.SetupLogger( loggerName, - "error", // will be re-set later with the value from the env var - "", // logFile -> by setting this to an empty string, we don't write the logs to any file - "", // syslog URI - false, // syslog_rfc - true, // log_to_console - false, // log_format_json + logLevel, + "", // logFile -> by setting this to an empty string, we don't write the logs to any file + "", // syslog URI + false, // syslog_rfc + true, // log_to_console + false, // log_format_json ); err != nil { log.Errorf("Unable to setup logger: %s", err) } - - if logLevel := os.Getenv(logLevelEnvVar); len(logLevel) > 0 { - if err := configUtils.SetLogLevel(logLevel, config.Datadog(), model.SourceAgentRuntime); err != nil { - log.Errorf("While changing the loglevel: %s", err) - } - } } diff --git a/cmd/system-probe/api/module/factory_linux.go b/cmd/system-probe/api/module/factory_linux.go index 22fd3abc79548..b70e452414f26 100644 --- a/cmd/system-probe/api/module/factory_linux.go +++ b/cmd/system-probe/api/module/factory_linux.go @@ -11,14 +11,12 @@ import ( sysconfigtypes "github.com/DataDog/datadog-agent/cmd/system-probe/config/types" "github.com/DataDog/datadog-agent/comp/core/telemetry" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // Factory encapsulates the initialization of a Module type Factory struct { Name sysconfigtypes.ModuleName ConfigNamespaces []string - Fn func(cfg *sysconfigtypes.Config, wmeta optional.Option[workloadmeta.Component], telemetry telemetry.Component) (Module, error) + Fn func(cfg *sysconfigtypes.Config, wmeta workloadmeta.Component, telemetry telemetry.Component) (Module, error) NeedsEBPF func() bool } diff --git a/cmd/system-probe/api/module/factory_others.go b/cmd/system-probe/api/module/factory_others.go index a46c4174dfe1b..5f5f43f321147 100644 --- a/cmd/system-probe/api/module/factory_others.go +++ b/cmd/system-probe/api/module/factory_others.go @@ -11,13 +11,11 @@ import ( sysconfigtypes "github.com/DataDog/datadog-agent/cmd/system-probe/config/types" "github.com/DataDog/datadog-agent/comp/core/telemetry" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // Factory encapsulates the initialization of a Module type Factory struct { Name sysconfigtypes.ModuleName ConfigNamespaces []string - Fn func(cfg *sysconfigtypes.Config, wmeta optional.Option[workloadmeta.Component], telemetry telemetry.Component) (Module, error) + Fn func(cfg *sysconfigtypes.Config, wmeta workloadmeta.Component, telemetry telemetry.Component) (Module, error) } diff --git a/cmd/system-probe/api/module/loader.go b/cmd/system-probe/api/module/loader.go index bc67a97fbc818..610c2796cd0ad 100644 --- a/cmd/system-probe/api/module/loader.go +++ b/cmd/system-probe/api/module/loader.go @@ -19,7 +19,6 @@ import ( "github.com/DataDog/datadog-agent/comp/core/telemetry" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) var l *loader @@ -64,7 +63,7 @@ func withModule(name sysconfigtypes.ModuleName, fn func()) { // * Initialization using the provided Factory; // * Registering the HTTP endpoints of each module; // * Register the gRPC server; -func Register(cfg *sysconfigtypes.Config, httpMux *mux.Router, factories []Factory, wmeta optional.Option[workloadmeta.Component], telemetry telemetry.Component) error { +func Register(cfg *sysconfigtypes.Config, httpMux *mux.Router, factories []Factory, wmeta workloadmeta.Component, telemetry telemetry.Component) error { var enabledModulesFactories []Factory for _, factory := range factories { if !cfg.ModuleIsEnabled(factory.Name) { @@ -140,7 +139,7 @@ func GetStats() map[string]interface{} { } // RestartModule triggers a module restart -func RestartModule(factory Factory, wmeta optional.Option[workloadmeta.Component], telemetry telemetry.Component) error { +func RestartModule(factory Factory, wmeta workloadmeta.Component, telemetry telemetry.Component) error { l.Lock() defer l.Unlock() @@ -200,6 +199,7 @@ func updateStats() { then := time.Now() now := time.Now() ticker := time.NewTicker(15 * time.Second) + defer ticker.Stop() for { l.Lock() diff --git a/cmd/system-probe/api/restart.go b/cmd/system-probe/api/restart.go index d9ceb119a448d..608f1c014ffe8 100644 --- a/cmd/system-probe/api/restart.go +++ b/cmd/system-probe/api/restart.go @@ -16,10 +16,9 @@ import ( "github.com/DataDog/datadog-agent/cmd/system-probe/modules" "github.com/DataDog/datadog-agent/comp/core/telemetry" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) -func restartModuleHandler(w http.ResponseWriter, r *http.Request, wmeta optional.Option[workloadmeta.Component], telemetry telemetry.Component) { +func restartModuleHandler(w http.ResponseWriter, r *http.Request, wmeta workloadmeta.Component, telemetry telemetry.Component) { vars := mux.Vars(r) moduleName := sysconfigtypes.ModuleName(vars["module-name"]) diff --git a/cmd/system-probe/api/server.go b/cmd/system-probe/api/server.go index 0cad296d09e2d..8ab6909d3db54 100644 --- a/cmd/system-probe/api/server.go +++ b/cmd/system-probe/api/server.go @@ -23,11 +23,10 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/process/net" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // StartServer starts the HTTP and gRPC servers for the system-probe, which registers endpoints from all enabled modules. -func StartServer(cfg *sysconfigtypes.Config, telemetry telemetry.Component, wmeta optional.Option[workloadmeta.Component], settings settings.Component) error { +func StartServer(cfg *sysconfigtypes.Config, telemetry telemetry.Component, wmeta workloadmeta.Component, settings settings.Component) error { conn, err := net.NewListener(cfg.SocketAddress) if err != nil { return fmt.Errorf("error creating IPC socket: %s", err) diff --git a/cmd/system-probe/config/adjust_npm.go b/cmd/system-probe/config/adjust_npm.go index 58cfe1c3ac8a3..ab0fc468bf553 100644 --- a/cmd/system-probe/config/adjust_npm.go +++ b/cmd/system-probe/config/adjust_npm.go @@ -25,6 +25,8 @@ const ( ) func adjustNetwork(cfg config.Config) { + ebpflessEnabled := cfg.GetBool(netNS("enable_ebpfless")) + limitMaxInt(cfg, spNS("max_conns_per_message"), maxConnsMessageBatchSize) if cfg.GetBool(spNS("disable_tcp")) { @@ -99,4 +101,24 @@ func adjustNetwork(cfg config.Config) { log.Warn("disabling NPM connection rollups since USM connection rollups are not enabled") cfg.Set(netNS("enable_connection_rollup"), false, model.SourceAgentRuntime) } + + // disable features that are not supported on certain + // configs/platforms + var disableConfigs []struct { + key, reason string + } + if ebpflessEnabled { + const notSupportedEbpfless = "not supported when ebpf-less is enabled" + disableConfigs = append(disableConfigs, []struct{ key, reason string }{ + {netNS("enable_protocol_classification"), notSupportedEbpfless}, + {evNS("network_process", "enabled"), notSupportedEbpfless}}..., + ) + } + + for _, c := range disableConfigs { + if cfg.GetBool(c.key) { + log.Warnf("disabling %s: %s", c.key, c.reason) + cfg.Set(c.key, false, model.SourceAgentRuntime) + } + } } diff --git a/cmd/system-probe/config/adjust_npm_test.go b/cmd/system-probe/config/adjust_npm_test.go index fac7b1e5e06bf..9aab2b4453eaa 100644 --- a/cmd/system-probe/config/adjust_npm_test.go +++ b/cmd/system-probe/config/adjust_npm_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/config/model" ) @@ -28,8 +28,7 @@ func TestAdjustConnectionRollup(t *testing.T) { for _, te := range tests { t.Run(fmt.Sprintf("npm_enabled_%t_usm_enabled_%t", te.npmEnabled, te.usmEnabled), func(t *testing.T) { - config.ResetSystemProbeConfig(t) - cfg := config.SystemProbe() + cfg := mock.NewSystemProbe(t) cfg.Set(netNS("enable_connection_rollup"), te.npmEnabled, model.SourceUnknown) cfg.Set(smNS("enable_connection_rollup"), te.usmEnabled, model.SourceUnknown) Adjust(cfg) diff --git a/cmd/system-probe/config/config.go b/cmd/system-probe/config/config.go index 29678bac66657..ff21f22169103 100644 --- a/cmd/system-probe/config/config.go +++ b/cmd/system-probe/config/config.go @@ -83,6 +83,9 @@ func newSysprobeConfig(configPath string, fleetPoliciesDirPath string) (*types.C } // Load the remote configuration + if fleetPoliciesDirPath == "" { + fleetPoliciesDirPath = aconfig.SystemProbe().GetString("fleet_policies_dir") + } if fleetPoliciesDirPath != "" { err := aconfig.SystemProbe().MergeFleetPolicy(path.Join(fleetPoliciesDirPath, "system-probe.yaml")) if err != nil { diff --git a/cmd/system-probe/config/config_linux_test.go b/cmd/system-probe/config/config_linux_test.go index a9a71ca6b2928..aab12a5c52ed5 100644 --- a/cmd/system-probe/config/config_linux_test.go +++ b/cmd/system-probe/config/config_linux_test.go @@ -14,11 +14,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/mock" ) func TestNetworkProcessEventMonitoring(t *testing.T) { - config.MockSystemProbe(t) + mock.NewSystemProbe(t) for i, te := range []struct { network, netProcEvents bool @@ -44,7 +44,7 @@ func TestNetworkProcessEventMonitoring(t *testing.T) { } func TestDynamicInstrumentation(t *testing.T) { - config.MockSystemProbe(t) + mock.NewSystemProbe(t) os.Setenv("DD_DYNAMIC_INSTRUMENTATION_ENABLED", "true") defer os.Unsetenv("DD_DYNAMIC_INSTRUMENTATION_ENABLED") @@ -60,9 +60,8 @@ func TestDynamicInstrumentation(t *testing.T) { } func TestEventStreamEnabledForSupportedKernelsLinux(t *testing.T) { - config.ResetSystemProbeConfig(t) t.Setenv("DD_SYSTEM_PROBE_EVENT_MONITORING_NETWORK_PROCESS_ENABLED", strconv.FormatBool(true)) - cfg := config.SystemProbe() + cfg := mock.NewSystemProbe(t) Adjust(cfg) if ProcessEventDataStreamSupported() { @@ -87,7 +86,7 @@ func TestNPMEnabled(t *testing.T) { {true, true, true, true}, } - config.MockSystemProbe(t) + mock.NewSystemProbe(t) for _, te := range tests { t.Run("", func(t *testing.T) { t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLED", strconv.FormatBool(te.npm)) diff --git a/cmd/system-probe/config/config_test.go b/cmd/system-probe/config/config_test.go index db57327068788..26164bfc0cd0f 100644 --- a/cmd/system-probe/config/config_test.go +++ b/cmd/system-probe/config/config_test.go @@ -9,7 +9,6 @@ package config import ( "fmt" - "os" "runtime" "strconv" "testing" @@ -17,11 +16,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/mock" ) func TestEventMonitor(t *testing.T) { - config.MockSystemProbe(t) + mock.NewSystemProbe(t) for i, tc := range []struct { cws, fim, processEvents, networkEvents bool @@ -61,24 +60,12 @@ func TestEventMonitor(t *testing.T) { } func TestEventStreamEnabledForSupportedKernelsWindowsUnsupported(t *testing.T) { - t.Run("does nothing for windows", func(t *testing.T) { - if runtime.GOOS != "windows" { - t.Skip("This is only for windows") - } - config.ResetSystemProbeConfig(t) - t.Setenv("DD_SYSTEM_PROBE_EVENT_MONITORING_NETWORK_PROCESS_ENABLED", strconv.FormatBool(true)) - cfg := config.SystemProbe() - Adjust(cfg) - - require.False(t, cfg.GetBool("event_monitoring_config.network_process.enabled")) - }) t.Run("does nothing for unsupported", func(t *testing.T) { if runtime.GOOS == "windows" || runtime.GOOS == "linux" { t.Skip("This is only for unsupported") } - config.ResetSystemProbeConfig(t) t.Setenv("DD_SYSTEM_PROBE_EVENT_MONITORING_NETWORK_PROCESS_ENABLED", strconv.FormatBool(true)) - cfg := config.SystemProbe() + cfg := mock.NewSystemProbe(t) Adjust(cfg) require.False(t, cfg.GetBool("event_monitoring_config.network_process.enabled")) @@ -87,37 +74,19 @@ func TestEventStreamEnabledForSupportedKernelsWindowsUnsupported(t *testing.T) { func TestEnableDiscovery(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - config.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -discovery: - enabled: true -`) + cfg := mock.NewSystemProbe(t) + cfg.SetWithoutSource("discovery.enabled", true) assert.True(t, cfg.GetBool(discoveryNS("enabled"))) }) t.Run("via ENV variable", func(t *testing.T) { - config.ResetSystemProbeConfig(t) t.Setenv("DD_DISCOVERY_ENABLED", "true") - assert.True(t, config.SystemProbe().GetBool(discoveryNS("enabled"))) + cfg := mock.NewSystemProbe(t) + assert.True(t, cfg.GetBool(discoveryNS("enabled"))) }) t.Run("default", func(t *testing.T) { - config.ResetSystemProbeConfig(t) - assert.False(t, config.SystemProbe().GetBool(discoveryNS("enabled"))) + cfg := mock.NewSystemProbe(t) + assert.False(t, cfg.GetBool(discoveryNS("enabled"))) }) } - -func configurationFromYAML(t *testing.T, yaml string) config.Config { - f, err := os.CreateTemp(t.TempDir(), "system-probe.*.yaml") - require.NoError(t, err) - defer f.Close() - - b := []byte(yaml) - n, err := f.Write(b) - require.NoError(t, err) - require.Equal(t, len(b), n) - f.Sync() - - _, _ = New(f.Name(), "") - return config.SystemProbe() -} diff --git a/cmd/system-probe/config/config_windows.go b/cmd/system-probe/config/config_windows.go index 9d42c7f3727b0..54e1e09b273a8 100644 --- a/cmd/system-probe/config/config_windows.go +++ b/cmd/system-probe/config/config_windows.go @@ -43,5 +43,5 @@ func ValidateSocketAddress(sockAddress string) error { // ProcessEventDataStreamSupported returns true if process event data stream is supported func ProcessEventDataStreamSupported() bool { - return false + return true } diff --git a/cmd/system-probe/modules/compliance.go b/cmd/system-probe/modules/compliance.go index 0ab8d0106ce05..319120435942a 100644 --- a/cmd/system-probe/modules/compliance.go +++ b/cmd/system-probe/modules/compliance.go @@ -23,7 +23,6 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/compliance/dbconfig" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" "go.uber.org/atomic" ) @@ -37,7 +36,7 @@ import ( var ComplianceModule = module.Factory{ Name: config.ComplianceModule, ConfigNamespaces: []string{}, - Fn: func(_ *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], _ telemetry.Component) (module.Module, error) { + Fn: func(_ *sysconfigtypes.Config, _ workloadmeta.Component, _ telemetry.Component) (module.Module, error) { return &complianceModule{}, nil }, NeedsEBPF: func() bool { diff --git a/cmd/system-probe/modules/crashdetect_windows.go b/cmd/system-probe/modules/crashdetect_windows.go index 0d544fdc0adae..67f1245a8a826 100644 --- a/cmd/system-probe/modules/crashdetect_windows.go +++ b/cmd/system-probe/modules/crashdetect_windows.go @@ -19,14 +19,13 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/system/wincrashdetect/probe" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // WinCrashProbe Factory var WinCrashProbe = module.Factory{ Name: config.WindowsCrashDetectModule, ConfigNamespaces: []string{"windows_crash_detection"}, - Fn: func(cfg *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], _ telemetry.Component) (module.Module, error) { + Fn: func(cfg *sysconfigtypes.Config, _ workloadmeta.Component, _ telemetry.Component) (module.Module, error) { log.Infof("Starting the WinCrashProbe probe") cp, err := probe.NewWinCrashProbe(cfg) if err != nil { diff --git a/cmd/system-probe/modules/dynamic_instrumentation.go b/cmd/system-probe/modules/dynamic_instrumentation.go index b6175ca66906a..98eec05108e8f 100644 --- a/cmd/system-probe/modules/dynamic_instrumentation.go +++ b/cmd/system-probe/modules/dynamic_instrumentation.go @@ -18,14 +18,13 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/dynamicinstrumentation" "github.com/DataDog/datadog-agent/pkg/ebpf" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // DynamicInstrumentation is the dynamic instrumentation module factory var DynamicInstrumentation = module.Factory{ Name: config.DynamicInstrumentationModule, ConfigNamespaces: []string{}, - Fn: func(agentConfiguration *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], _ telemetry.Component) (module.Module, error) { + Fn: func(agentConfiguration *sysconfigtypes.Config, _ workloadmeta.Component, _ telemetry.Component) (module.Module, error) { config, err := dynamicinstrumentation.NewConfig(agentConfiguration) if err != nil { return nil, fmt.Errorf("invalid dynamic instrumentation module configuration: %w", err) diff --git a/cmd/system-probe/modules/ebpf.go b/cmd/system-probe/modules/ebpf.go index 4c4f1e4256276..d71a1dbfec6bb 100644 --- a/cmd/system-probe/modules/ebpf.go +++ b/cmd/system-probe/modules/ebpf.go @@ -23,14 +23,13 @@ import ( "github.com/DataDog/datadog-agent/pkg/collector/corechecks/ebpf/probe/ebpfcheck" "github.com/DataDog/datadog-agent/pkg/ebpf" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // EBPFProbe Factory var EBPFProbe = module.Factory{ Name: config.EBPFModule, ConfigNamespaces: []string{}, - Fn: func(_ *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], _ telemetry.Component) (module.Module, error) { + Fn: func(_ *sysconfigtypes.Config, _ workloadmeta.Component, _ telemetry.Component) (module.Module, error) { log.Infof("Starting the ebpf probe") okp, err := ebpfcheck.NewProbe(ebpf.NewConfig()) if err != nil { diff --git a/cmd/system-probe/modules/eventmonitor.go b/cmd/system-probe/modules/eventmonitor.go index 54bb4fc256d7d..4bab66647d039 100644 --- a/cmd/system-probe/modules/eventmonitor.go +++ b/cmd/system-probe/modules/eventmonitor.go @@ -20,12 +20,11 @@ import ( secconfig "github.com/DataDog/datadog-agent/pkg/security/config" secmodule "github.com/DataDog/datadog-agent/pkg/security/module" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) var eventMonitorModuleConfigNamespaces = []string{"event_monitoring_config", "runtime_security_config"} -func createEventMonitorModule(_ *sysconfigtypes.Config, wmeta optional.Option[workloadmeta.Component], telemetry telemetry.Component) (module.Module, error) { +func createEventMonitorModule(_ *sysconfigtypes.Config, wmeta workloadmeta.Component, telemetry telemetry.Component) (module.Module, error) { emconfig := emconfig.NewConfig() secconfig, err := secconfig.NewConfig() diff --git a/cmd/system-probe/modules/eventmonitor_linux.go b/cmd/system-probe/modules/eventmonitor_linux.go index 85c5c1a0deef9..ebea6228c580d 100644 --- a/cmd/system-probe/modules/eventmonitor_linux.go +++ b/cmd/system-probe/modules/eventmonitor_linux.go @@ -14,6 +14,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/eventmonitor" netconfig "github.com/DataDog/datadog-agent/pkg/network/config" usmconfig "github.com/DataDog/datadog-agent/pkg/network/usm/config" + usmstate "github.com/DataDog/datadog-agent/pkg/network/usm/state" procmon "github.com/DataDog/datadog-agent/pkg/process/monitor" ) @@ -28,7 +29,7 @@ var EventMonitor = module.Factory{ } func createProcessMonitorConsumer(evm *eventmonitor.EventMonitor, config *netconfig.Config) (eventmonitor.EventConsumerInterface, error) { - if !usmconfig.IsUSMSupportedAndEnabled(config) || !usmconfig.NeedProcessMonitor(config) { + if !usmconfig.IsUSMSupportedAndEnabled(config) || !usmconfig.NeedProcessMonitor(config) || usmstate.Get() != usmstate.Running { return nil, nil } diff --git a/cmd/system-probe/modules/language_detection.go b/cmd/system-probe/modules/language_detection.go index 47d6d4b354910..04567200d5de1 100644 --- a/cmd/system-probe/modules/language_detection.go +++ b/cmd/system-probe/modules/language_detection.go @@ -23,14 +23,13 @@ import ( "github.com/DataDog/datadog-agent/pkg/languagedetection/privileged" languageDetectionProto "github.com/DataDog/datadog-agent/pkg/proto/pbgo/languagedetection" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // LanguageDetectionModule is the language detection module factory var LanguageDetectionModule = module.Factory{ Name: config.LanguageDetectionModule, ConfigNamespaces: []string{"language_detection"}, - Fn: func(_ *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], _ telemetry.Component) (module.Module, error) { + Fn: func(_ *sysconfigtypes.Config, _ workloadmeta.Component, _ telemetry.Component) (module.Module, error) { return &languageDetectionModule{ languageDetector: privileged.NewLanguageDetector(), }, nil diff --git a/cmd/system-probe/modules/language_detection_test.go b/cmd/system-probe/modules/language_detection_test.go index 2f7f63ac47c0b..483e9b80b8846 100644 --- a/cmd/system-probe/modules/language_detection_test.go +++ b/cmd/system-probe/modules/language_detection_test.go @@ -12,6 +12,7 @@ import ( "io" "net/http" "net/http/httptest" + "os" "testing" "github.com/davecgh/go-spew/spew" @@ -25,7 +26,11 @@ import ( languageDetectionProto "github.com/DataDog/datadog-agent/pkg/proto/pbgo/languagedetection" ) -const mockPid = 1 +var mockPid int32 + +func init() { + mockPid = int32(os.Getpid()) +} func TestLanguageDetectionEndpoint(t *testing.T) { mockGoLanguage := languagemodels.Language{Name: languagemodels.Go, Version: "go version go1.19.10 linux/arm64"} diff --git a/cmd/system-probe/modules/network_tracer.go b/cmd/system-probe/modules/network_tracer.go index b7e7ec5bcb2ad..85a238142334d 100644 --- a/cmd/system-probe/modules/network_tracer.go +++ b/cmd/system-probe/modules/network_tracer.go @@ -38,7 +38,6 @@ import ( usm "github.com/DataDog/datadog-agent/pkg/network/usm/utils" "github.com/DataDog/datadog-agent/pkg/process/statsd" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // ErrSysprobeUnsupported is the unsupported error prefix, for error-class matching from callers @@ -49,7 +48,7 @@ const inactivityRestartDuration = 20 * time.Minute var networkTracerModuleConfigNamespaces = []string{"network_config", "service_monitoring_config"} -func createNetworkTracerModule(cfg *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], telemetryComponent telemetryComponent.Component) (module.Module, error) { +func createNetworkTracerModule(cfg *sysconfigtypes.Config, _ workloadmeta.Component, telemetryComponent telemetryComponent.Component) (module.Module, error) { ncfg := networkconfig.New() // Checking whether the current OS + kernel version is supported by the tracer diff --git a/cmd/system-probe/modules/network_tracer_linux.go b/cmd/system-probe/modules/network_tracer_linux.go index c3274c39df631..9481d9d9208e5 100644 --- a/cmd/system-probe/modules/network_tracer_linux.go +++ b/cmd/system-probe/modules/network_tracer_linux.go @@ -10,6 +10,7 @@ package modules import ( "github.com/DataDog/datadog-agent/cmd/system-probe/api/module" "github.com/DataDog/datadog-agent/cmd/system-probe/config" + "github.com/DataDog/datadog-agent/pkg/network/tracer" ) // NetworkTracer is a factory for NPM's tracer @@ -17,7 +18,5 @@ var NetworkTracer = module.Factory{ Name: config.NetworkTracerModule, ConfigNamespaces: networkTracerModuleConfigNamespaces, Fn: createNetworkTracerModule, - NeedsEBPF: func() bool { - return true - }, + NeedsEBPF: tracer.NeedsEBPF, } diff --git a/cmd/system-probe/modules/oom_kill_probe.go b/cmd/system-probe/modules/oom_kill_probe.go index 250914303f85a..74b8b868b0ac4 100644 --- a/cmd/system-probe/modules/oom_kill_probe.go +++ b/cmd/system-probe/modules/oom_kill_probe.go @@ -23,14 +23,13 @@ import ( "github.com/DataDog/datadog-agent/pkg/collector/corechecks/ebpf/probe/oomkill" "github.com/DataDog/datadog-agent/pkg/ebpf" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // OOMKillProbe Factory var OOMKillProbe = module.Factory{ Name: config.OOMKillProbeModule, ConfigNamespaces: []string{}, - Fn: func(_ *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], _ telemetry.Component) (module.Module, error) { + Fn: func(_ *sysconfigtypes.Config, _ workloadmeta.Component, _ telemetry.Component) (module.Module, error) { log.Infof("Starting the OOM Kill probe") okp, err := oomkill.NewProbe(ebpf.NewConfig()) if err != nil { diff --git a/cmd/system-probe/modules/ping.go b/cmd/system-probe/modules/ping.go index f4ddda1e4cbf1..02d8e1ba5ce60 100644 --- a/cmd/system-probe/modules/ping.go +++ b/cmd/system-probe/modules/ping.go @@ -23,7 +23,6 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" pingcheck "github.com/DataDog/datadog-agent/pkg/networkdevice/pinger" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) const ( @@ -38,7 +37,7 @@ type pinger struct{} var Pinger = module.Factory{ Name: config.PingModule, ConfigNamespaces: []string{"ping"}, - Fn: func(_ *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], _ telemetry.Component) (module.Module, error) { + Fn: func(_ *sysconfigtypes.Config, _ workloadmeta.Component, _ telemetry.Component) (module.Module, error) { return &pinger{}, nil }, NeedsEBPF: func() bool { diff --git a/cmd/system-probe/modules/process.go b/cmd/system-probe/modules/process.go index 277defd88a454..7ffbaad6e4bff 100644 --- a/cmd/system-probe/modules/process.go +++ b/cmd/system-probe/modules/process.go @@ -29,7 +29,6 @@ import ( reqEncoding "github.com/DataDog/datadog-agent/pkg/process/encoding/request" "github.com/DataDog/datadog-agent/pkg/process/procutil" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // ErrProcessUnsupported is an error type indicating that the process module is not support in the running environment @@ -39,7 +38,7 @@ var ErrProcessUnsupported = errors.New("process module unsupported") var Process = module.Factory{ Name: config.ProcessModule, ConfigNamespaces: []string{}, - Fn: func(_ *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], _ telemetry.Component) (module.Module, error) { + Fn: func(_ *sysconfigtypes.Config, _ workloadmeta.Component, _ telemetry.Component) (module.Module, error) { log.Infof("Creating process module for: %s", filepath.Base(os.Args[0])) // we disable returning zero values for stats to reduce parsing work on process-agent side diff --git a/cmd/system-probe/modules/tcp_queue_tracer.go b/cmd/system-probe/modules/tcp_queue_tracer.go index d92206244bd3a..0b5a6fc14b8ca 100644 --- a/cmd/system-probe/modules/tcp_queue_tracer.go +++ b/cmd/system-probe/modules/tcp_queue_tracer.go @@ -22,14 +22,13 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/ebpf/probe/tcpqueuelength" "github.com/DataDog/datadog-agent/pkg/ebpf" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // TCPQueueLength Factory var TCPQueueLength = module.Factory{ Name: config.TCPQueueLengthTracerModule, ConfigNamespaces: []string{}, - Fn: func(_ *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], _ telemetry.Component) (module.Module, error) { + Fn: func(_ *sysconfigtypes.Config, _ workloadmeta.Component, _ telemetry.Component) (module.Module, error) { t, err := tcpqueuelength.NewTracer(ebpf.NewConfig()) if err != nil { return nil, fmt.Errorf("unable to start the TCP queue length tracer: %w", err) diff --git a/cmd/system-probe/modules/traceroute.go b/cmd/system-probe/modules/traceroute.go index 2812462d0cc01..117718f577ee2 100644 --- a/cmd/system-probe/modules/traceroute.go +++ b/cmd/system-probe/modules/traceroute.go @@ -26,7 +26,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/networkpath/payload" tracerouteutil "github.com/DataDog/datadog-agent/pkg/networkpath/traceroute" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) type traceroute struct { @@ -39,7 +38,7 @@ var ( tracerouteConfigNamespaces = []string{"traceroute"} ) -func createTracerouteModule(_ *sysconfigtypes.Config, _ optional.Option[workloadmeta.Component], telemetry telemetry.Component) (module.Module, error) { +func createTracerouteModule(_ *sysconfigtypes.Config, _ workloadmeta.Component, telemetry telemetry.Component) (module.Module, error) { runner, err := tracerouteutil.NewRunner(telemetry) if err != nil { return &traceroute{}, err diff --git a/cmd/system-probe/subcommands/debug/command.go b/cmd/system-probe/subcommands/debug/command.go index ec220f144cd2c..454749bfcf2cd 100644 --- a/cmd/system-probe/subcommands/debug/command.go +++ b/cmd/system-probe/subcommands/debug/command.go @@ -8,6 +8,7 @@ package debug import ( "encoding/json" + "errors" "fmt" "strconv" @@ -79,7 +80,7 @@ func debugRuntime(sysprobeconfig sysprobeconfig.Component, cliParams *cliParams) _ = json.Unmarshal(r, &errMap) // If the error has been marshalled into a json object, check it and return it properly if e, found := errMap["error"]; found { - return fmt.Errorf(e) + return errors.New(e) } return fmt.Errorf("Could not reach system-probe: %s\nMake sure system-probe is running before running this command and contact support if you continue having issues", err) diff --git a/cmd/system-probe/subcommands/run/command.go b/cmd/system-probe/subcommands/run/command.go index 2125677397cd8..c61f0d1316d99 100644 --- a/cmd/system-probe/subcommands/run/command.go +++ b/cmd/system-probe/subcommands/run/command.go @@ -44,11 +44,14 @@ import ( "github.com/DataDog/datadog-agent/comp/core/sysprobeconfig/sysprobeconfigimpl" "github.com/DataDog/datadog-agent/comp/core/telemetry" "github.com/DataDog/datadog-agent/comp/core/telemetry/telemetryimpl" + wmcatalog "github.com/DataDog/datadog-agent/comp/core/workloadmeta/collectors/catalog" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + workloadmetafx "github.com/DataDog/datadog-agent/comp/core/workloadmeta/fx" compstatsd "github.com/DataDog/datadog-agent/comp/dogstatsd/statsd" "github.com/DataDog/datadog-agent/comp/remote-config/rcclient" "github.com/DataDog/datadog-agent/comp/remote-config/rcclient/rcclientimpl" ddconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/config/model" commonsettings "github.com/DataDog/datadog-agent/pkg/config/settings" ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" @@ -104,7 +107,11 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { }), healthprobefx.Module(), systemprobeloggerfx.Module(), - fx.Supply(optional.NewNoneOption[workloadmeta.Component]()), + // workloadmeta setup + wmcatalog.GetCatalog(), + workloadmetafx.Module(workloadmeta.Params{ + AgentType: workloadmeta.Remote, + }), autoexitimpl.Module(), pidimpl.Module(), fx.Supply(pidimpl.NewParams(cliParams.pidfilePath)), @@ -134,7 +141,7 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { } // run starts the main loop. -func run(log log.Component, _ config.Component, statsd compstatsd.Component, telemetry telemetry.Component, sysprobeconfig sysprobeconfig.Component, rcclient rcclient.Component, wmeta optional.Option[workloadmeta.Component], _ pid.Component, _ healthprobe.Component, _ autoexit.Component, settings settings.Component) error { +func run(log log.Component, _ config.Component, statsd compstatsd.Component, telemetry telemetry.Component, sysprobeconfig sysprobeconfig.Component, rcclient rcclient.Component, wmeta workloadmeta.Component, _ pid.Component, _ healthprobe.Component, _ autoexit.Component, settings settings.Component) error { defer func() { stopSystemProbe() }() @@ -220,7 +227,7 @@ func StartSystemProbeWithDefaults(ctxChan <-chan context.Context) (<-chan error, func runSystemProbe(ctxChan <-chan context.Context, errChan chan error) error { return fxutil.OneShot( - func(log log.Component, _ config.Component, statsd compstatsd.Component, telemetry telemetry.Component, sysprobeconfig sysprobeconfig.Component, rcclient rcclient.Component, wmeta optional.Option[workloadmeta.Component], _ healthprobe.Component, settings settings.Component) error { + func(log log.Component, _ config.Component, statsd compstatsd.Component, telemetry telemetry.Component, sysprobeconfig sysprobeconfig.Component, rcclient rcclient.Component, wmeta workloadmeta.Component, _ healthprobe.Component, settings settings.Component) error { defer StopSystemProbeWithDefaults() err := startSystemProbe(log, statsd, telemetry, sysprobeconfig, rcclient, wmeta, settings) if err != nil { @@ -262,7 +269,11 @@ func runSystemProbe(ctxChan <-chan context.Context, errChan chan error) error { } }), healthprobefx.Module(), - fx.Supply(optional.NewNoneOption[workloadmeta.Component]()), + // workloadmeta setup + wmcatalog.GetCatalog(), + workloadmetafx.Module(workloadmeta.Params{ + AgentType: workloadmeta.Remote, + }), systemprobeloggerfx.Module(), fx.Provide(func(sysprobeconfig sysprobeconfig.Component) settings.Params { profilingGoRoutines := commonsettings.NewProfilingGoroutines() @@ -290,7 +301,7 @@ func StopSystemProbeWithDefaults() { } // startSystemProbe Initializes the system-probe process -func startSystemProbe(log log.Component, statsd compstatsd.Component, telemetry telemetry.Component, sysprobeconfig sysprobeconfig.Component, _ rcclient.Component, wmeta optional.Option[workloadmeta.Component], settings settings.Component) error { +func startSystemProbe(log log.Component, statsd compstatsd.Component, telemetry telemetry.Component, sysprobeconfig sysprobeconfig.Component, _ rcclient.Component, wmeta workloadmeta.Component, settings settings.Component) error { var err error cfg := sysprobeconfig.SysProbeObject() @@ -311,7 +322,7 @@ func startSystemProbe(log log.Component, statsd compstatsd.Component, telemetry memoryPressureLevels := sysprobeconfig.GetStringMapString("system_probe_config.memory_controller.pressure_levels") memoryThresholds := sysprobeconfig.GetStringMapString("system_probe_config.memory_controller.thresholds") hierarchy := sysprobeconfig.GetString("system_probe_config.memory_controller.hierarchy") - common.MemoryMonitor, err = utils.NewMemoryMonitor(hierarchy, ddconfig.IsContainerized(), memoryPressureLevels, memoryThresholds) + common.MemoryMonitor, err = utils.NewMemoryMonitor(hierarchy, env.IsContainerized(), memoryPressureLevels, memoryThresholds) if err != nil { log.Warnf("cannot set up memory controller: %s", err) } else { diff --git a/cmd/system-probe/subcommands/runtime/activity_dump.go b/cmd/system-probe/subcommands/runtime/activity_dump.go index 60ba970cdfa6a..72096d1160bbd 100644 --- a/cmd/system-probe/subcommands/runtime/activity_dump.go +++ b/cmd/system-probe/subcommands/runtime/activity_dump.go @@ -133,7 +133,7 @@ func generateDumpCommands(globalParams *command.GlobalParams) []*cobra.Command { activityDumpGenerateDumpCmd := &cobra.Command{ Use: "dump", Short: "generate an activity dump", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, _ []string) error { return fxutil.OneShot(generateActivityDump, fx.Supply(cliParams), fx.Supply(core.BundleParams{ diff --git a/cmd/systray/command/command.go b/cmd/systray/command/command.go index fcfc679410f58..cd421597483e1 100644 --- a/cmd/systray/command/command.go +++ b/cmd/systray/command/command.go @@ -98,7 +98,7 @@ func MakeCommand() *cobra.Command { }), core.Bundle(), // flare - fx.Supply(flare.NewParams( + flare.Module(flare.NewParams( path.GetDistPath(), path.PyChecksPath, path.DefaultLogFile, @@ -107,7 +107,6 @@ func MakeCommand() *cobra.Command { path.DefaultStreamlogsLogFile, )), fx.Supply(optional.NewNoneOption[autodiscovery.Component]()), - flare.Module(), fx.Supply(optional.NewNoneOption[workloadmeta.Component]()), fx.Supply(optional.NewNoneOption[collector.Component]()), compressionimpl.Module(), diff --git a/cmd/trace-agent/subcommands/run/command.go b/cmd/trace-agent/subcommands/run/command.go index 5d6b9ec3cc6b0..a3c790d19f1ad 100644 --- a/cmd/trace-agent/subcommands/run/command.go +++ b/cmd/trace-agent/subcommands/run/command.go @@ -94,11 +94,10 @@ func runTraceAgentProcess(ctx context.Context, cliParams *Params, defaultConfPat logtracefx.Module(), // setup workloadmeta wmcatalog.GetCatalog(), - fx.Supply(workloadmeta.Params{ + workloadmetafx.Module(workloadmeta.Params{ AgentType: workloadmeta.NodeAgent, InitHelper: common.GetWorkloadmetaInit(), }), - workloadmetafx.Module(), autoexitimpl.Module(), statsd.Module(), fx.Provide(func(coreConfig coreconfig.Component) tagger.Params { diff --git a/comp/README.md b/comp/README.md index 023e51463f0ac..357b628c7a3c8 100644 --- a/comp/README.md +++ b/comp/README.md @@ -152,6 +152,10 @@ Package hostnameinterface describes the interface for hostname methods Package log implements a component to handle logging internal to the agent. +### [comp/core/lsof](https://pkg.go.dev/github.com/DataDog/datadog-agent/comp/core/lsof) + +Package lsof provides a flare file with data about files opened by the agent process + ### [comp/core/pid](https://pkg.go.dev/github.com/DataDog/datadog-agent/comp/core/pid) Package pid writes the current PID to a file, ensuring that the file @@ -264,7 +268,8 @@ Package agent contains logs agent component. ### [comp/logs/integrations](https://pkg.go.dev/github.com/DataDog/datadog-agent/comp/logs/integrations) -Package integrations adds a go interface for integrations to send logs. +Package integrations adds a go interface for integrations to register and +send logs. ## [comp/metadata](https://pkg.go.dev/github.com/DataDog/datadog-agent/comp/metadata) (Component Bundle) @@ -378,9 +383,9 @@ Package configstore defines the otel agent configstore component. Package converter defines the otel agent converter component. -### [comp/otelcol/extension](https://pkg.go.dev/github.com/DataDog/datadog-agent/comp/otelcol/extension) +### [comp/otelcol/ddflareextension](https://pkg.go.dev/github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension) -Package extension defines the OpenTelemetry Extension component. +Package ddflareextension defines the OpenTelemetry Extension component. ### [comp/otelcol/logsagentpipeline](https://pkg.go.dev/github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline) diff --git a/comp/agent/autoexit/autoexitimpl/manager.go b/comp/agent/autoexit/autoexitimpl/manager.go index 1ec75cfc7fbe5..db71ad7c4e042 100644 --- a/comp/agent/autoexit/autoexitimpl/manager.go +++ b/comp/agent/autoexit/autoexitimpl/manager.go @@ -69,8 +69,9 @@ func startAutoExit(ctx context.Context, sd exitDetector, log log.Component, tick log.Info("Starting auto-exit watcher") lastConditionNotMet := time.Now() - ticker := time.NewTicker(tickerPeriod) go func() { + ticker := time.NewTicker(tickerPeriod) + defer ticker.Stop() for { select { case <-ctx.Done(): diff --git a/comp/agent/bundle_test.go b/comp/agent/bundle_test.go index 6797c7144574a..2ce804e6894d9 100644 --- a/comp/agent/bundle_test.go +++ b/comp/agent/bundle_test.go @@ -33,7 +33,6 @@ func TestBundleDependencies(t *testing.T) { demultiplexerimpl.Module(), fx.Supply(demultiplexerimpl.NewDefaultParams()), fx.Supply(jmxloggerimpl.NewDefaultParams()), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), ) } diff --git a/comp/agent/cloudfoundrycontainer/cloudfoundrycontainerimpl/cloudfoundrycontainer.go b/comp/agent/cloudfoundrycontainer/cloudfoundrycontainerimpl/cloudfoundrycontainer.go index 9b39ae1dc737f..98135933c7a32 100644 --- a/comp/agent/cloudfoundrycontainer/cloudfoundrycontainerimpl/cloudfoundrycontainer.go +++ b/comp/agent/cloudfoundrycontainer/cloudfoundrycontainerimpl/cloudfoundrycontainer.go @@ -15,7 +15,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/config" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" cloudfoundrycontainertagger "github.com/DataDog/datadog-agent/pkg/cloudfoundry/containertagger" - pkgconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" pkgcommon "github.com/DataDog/datadog-agent/pkg/util/common" "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -37,7 +37,7 @@ type dependencies struct { func newCloudfoundryContainer(deps dependencies) cloudfoundrycontainer.Component { // start the cloudfoundry container tagger - if pkgconfig.IsFeaturePresent(pkgconfig.CloudFoundry) && !deps.Config.GetBool("cloud_foundry_buildpack") { + if env.IsFeaturePresent(env.CloudFoundry) && !deps.Config.GetBool("cloud_foundry_buildpack") { containerTagger, err := cloudfoundrycontainertagger.NewContainerTagger(deps.WMeta) if err != nil { log.Errorf("Failed to create Cloud Foundry container tagger: %v", err) diff --git a/comp/api/api/def/go.mod b/comp/api/api/def/go.mod index 478f3fcfebdfc..e6856d630cfeb 100644 --- a/comp/api/api/def/go.mod +++ b/comp/api/api/def/go.mod @@ -2,11 +2,11 @@ module github.com/DataDog/datadog-agent/comp/api/api/def go 1.22.0 -require go.uber.org/fx v1.18.2 +require go.uber.org/fx v1.22.2 require ( - go.uber.org/dig v1.17.1 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/sys v0.23.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/sys v0.24.0 // indirect ) diff --git a/comp/api/api/def/go.sum b/comp/api/api/def/go.sum index 2832e07f2498c..c26518bc2614a 100644 --- a/comp/api/api/def/go.sum +++ b/comp/api/api/def/go.sum @@ -1,22 +1,20 @@ -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/comp/api/api/utils/stream/stream.go b/comp/api/api/utils/stream/stream.go index 416890d9ffef4..6ed376af548f3 100644 --- a/comp/api/api/utils/stream/stream.go +++ b/comp/api/api/utils/stream/stream.go @@ -76,6 +76,7 @@ func GetStreamFunc(messageReceiverFunc func() MessageReceiver, streamType, agent defer close(done) logChan := messageReceiver.Filter(&filters, done) flushTimer := time.NewTicker(time.Second) + defer flushTimer.Stop() for { // Handlers for detecting a closed connection (from either the server or client) select { diff --git a/comp/autoscaling/datadogclient/impl/client_test.go b/comp/autoscaling/datadogclient/impl/client_test.go index e097a6c089cb2..a5c61bb02567e 100644 --- a/comp/autoscaling/datadogclient/impl/client_test.go +++ b/comp/autoscaling/datadogclient/impl/client_test.go @@ -16,13 +16,12 @@ import ( "github.com/DataDog/datadog-agent/comp/core/config" logmock "github.com/DataDog/datadog-agent/comp/core/log/mock" pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/stretchr/testify/assert" "gopkg.in/zorkian/go-datadog-api.v2" ) func TestNewSingleClient(t *testing.T) { - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) logger := logmock.New(t) cfg.Set("api_key", "apikey123", pkgconfigmodel.SourceLocalConfigProcess) cfg.Set("app_key", "appkey456", pkgconfigmodel.SourceLocalConfigProcess) @@ -34,7 +33,7 @@ func TestNewSingleClient(t *testing.T) { } func TestNewFallbackClient(t *testing.T) { - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) logger := logmock.New(t) cfg.Set("api_key", "apikey123", pkgconfigmodel.SourceLocalConfigProcess) cfg.Set("app_key", "appkey456", pkgconfigmodel.SourceLocalConfigProcess) @@ -66,7 +65,7 @@ func TestExternalMetricsProviderEndpointAndRefresh(t *testing.T) { w.Write([]byte("{\"status\": \"ok\"}")) })) defer ts.Close() - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) logger := logmock.New(t) cfg.Set("api_key", "apikey123", pkgconfigmodel.SourceLocalConfigProcess) cfg.Set("app_key", "appkey456", pkgconfigmodel.SourceLocalConfigProcess) diff --git a/comp/autoscaling/datadogclient/impl/none.go b/comp/autoscaling/datadogclient/impl/none.go index 18181f8d6961b..cfd669d4eb155 100644 --- a/comp/autoscaling/datadogclient/impl/none.go +++ b/comp/autoscaling/datadogclient/impl/none.go @@ -7,8 +7,9 @@ package datadogclientimpl import ( - datadogclient "github.com/DataDog/datadog-agent/comp/autoscaling/datadogclient/def" "gopkg.in/zorkian/go-datadog-api.v2" + + datadogclient "github.com/DataDog/datadog-agent/comp/autoscaling/datadogclient/def" ) // ImplNone is a noop datadogclient implementation @@ -22,7 +23,7 @@ func NewNone() datadogclient.Component { } // QueryMetrics does nothing for the noop datadogclient implementation -func (d *ImplNone) QueryMetrics(from, to int64, query string) ([]datadog.Series, error) { +func (d *ImplNone) QueryMetrics(_, _ int64, _ string) ([]datadog.Series, error) { // noop return nil, nil } diff --git a/comp/core/autodiscovery/autodiscoveryimpl/autoconfig_test.go b/comp/core/autodiscovery/autodiscoveryimpl/autoconfig_test.go index c96486fbaa067..6b4a269ccea64 100644 --- a/comp/core/autodiscovery/autodiscoveryimpl/autoconfig_test.go +++ b/comp/core/autodiscovery/autodiscoveryimpl/autoconfig_test.go @@ -599,5 +599,5 @@ type Deps struct { } func createDeps(t *testing.T) Deps { - return fxutil.Test[Deps](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams()), fx.Supply(tagger.NewFakeTaggerParams()), taggerimpl.Module()) + return fxutil.Test[Deps](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams()), fx.Supply(tagger.NewFakeTaggerParams()), taggerimpl.Module()) } diff --git a/comp/core/autodiscovery/listeners/environment.go b/comp/core/autodiscovery/listeners/environment.go index 7fb364363e32b..a63d7430e6a25 100644 --- a/comp/core/autodiscovery/listeners/environment.go +++ b/comp/core/autodiscovery/listeners/environment.go @@ -10,7 +10,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/telemetry" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/containers" "github.com/DataDog/datadog-agent/pkg/util/log" ) @@ -49,26 +49,26 @@ func (l *EnvironmentListener) Stop() { } func (l *EnvironmentListener) createServices() { - features := map[string]config.Feature{ - "docker": config.Docker, - "kubelet": config.Kubernetes, - "ecs_fargate": config.ECSFargate, - "eks_fargate": config.EKSFargate, - "cri": config.Cri, - "containerd": config.Containerd, - "kube_orchestrator": config.KubeOrchestratorExplorer, - "ecs_orchestrator": config.ECSOrchestratorExplorer, + features := map[string]env.Feature{ + "docker": env.Docker, + "kubelet": env.Kubernetes, + "ecs_fargate": env.ECSFargate, + "eks_fargate": env.EKSFargate, + "cri": env.Cri, + "containerd": env.Containerd, + "kube_orchestrator": env.KubeOrchestratorExplorer, + "ecs_orchestrator": env.ECSOrchestratorExplorer, } for name, feature := range features { - if config.IsFeaturePresent(feature) { + if env.IsFeaturePresent(feature) { log.Infof("Listener created %s service from environment", name) l.newService <- &EnvironmentService{adIdentifier: "_" + name} } } // Handle generic container check auto-activation. - if config.IsAnyContainerFeaturePresent() { + if env.IsAnyContainerFeaturePresent() { log.Infof("Listener created container service from environment") l.newService <- &EnvironmentService{adIdentifier: "_container"} } diff --git a/comp/core/autodiscovery/listeners/snmp.go b/comp/core/autodiscovery/listeners/snmp.go index a16778434212a..fa5fd2937bccc 100644 --- a/comp/core/autodiscovery/listeners/snmp.go +++ b/comp/core/autodiscovery/listeners/snmp.go @@ -220,7 +220,7 @@ func (l *SNMPListener) checkDevices() { } discoveryTicker := time.NewTicker(time.Duration(l.config.DiscoveryInterval) * time.Second) - + defer discoveryTicker.Stop() for { var subnet *snmpSubnet for i := range subnets { diff --git a/comp/core/autodiscovery/listeners/workloadmeta_test.go b/comp/core/autodiscovery/listeners/workloadmeta_test.go index ff9861149cbbf..56597b9accd86 100644 --- a/comp/core/autodiscovery/listeners/workloadmeta_test.go +++ b/comp/core/autodiscovery/listeners/workloadmeta_test.go @@ -94,8 +94,7 @@ func newTestWorkloadmetaListener(t *testing.T) *testWorkloadmetaListener { fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) return &testWorkloadmetaListener{ diff --git a/comp/core/autodiscovery/providers/container_test.go b/comp/core/autodiscovery/providers/container_test.go index 365d35407c262..9f79da48d8a01 100644 --- a/comp/core/autodiscovery/providers/container_test.go +++ b/comp/core/autodiscovery/providers/container_test.go @@ -30,8 +30,7 @@ func TestProcessEvents(t *testing.T) { store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( config.MockModule(), fx.Provide(func() log.Component { return logmock.New(t) }), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) telemetry := fxutil.Test[telemetry.Component](t, telemetryimpl.MockModule()) @@ -423,8 +422,7 @@ func TestGenerateConfig(t *testing.T) { config.MockModule(), fx.Provide(func() log.Component { return logmock.New(t) }), fx.Replace(config.MockParams{Overrides: overrides}), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) if pod, ok := tt.entity.(*workloadmeta.KubernetesPod); ok { diff --git a/comp/core/autodiscovery/providers/kube_endpoints_test.go b/comp/core/autodiscovery/providers/kube_endpoints_test.go index 36b78d68d8add..3ea35201e26a0 100644 --- a/comp/core/autodiscovery/providers/kube_endpoints_test.go +++ b/comp/core/autodiscovery/providers/kube_endpoints_test.go @@ -9,7 +9,6 @@ package providers import ( "context" - "fmt" "strings" "testing" "time" @@ -463,7 +462,7 @@ func TestGenerateConfigs(t *testing.T) { }, }, } { - t.Run(fmt.Sprintf(tc.name), func(t *testing.T) { + t.Run(tc.name, func(t *testing.T) { cfgs := generateConfigs(tc.template, tc.resolveMode, tc.endpoints) assert.EqualValues(t, tc.expectedOut, cfgs) }) diff --git a/comp/core/autodiscovery/providers/kube_services_test.go b/comp/core/autodiscovery/providers/kube_services_test.go index fcecd31581219..57da4676c08f1 100644 --- a/comp/core/autodiscovery/providers/kube_services_test.go +++ b/comp/core/autodiscovery/providers/kube_services_test.go @@ -9,7 +9,6 @@ package providers import ( "context" - "fmt" "strings" "testing" "time" @@ -241,7 +240,7 @@ func TestParseKubeServiceAnnotations(t *testing.T) { }, }, } { - t.Run(fmt.Sprintf(tc.name), func(t *testing.T) { + t.Run(tc.name, func(t *testing.T) { cfg := config.NewConfig("datadog", "DD", strings.NewReplacer(".", "_")) if tc.hybrid { cfg.SetWithoutSource("cluster_checks.support_hybrid_ignore_ad_tags", true) diff --git a/comp/core/autodiscovery/status/status.go b/comp/core/autodiscovery/status/status.go index a52b7952f3d1e..27d7db6ad5615 100644 --- a/comp/core/autodiscovery/status/status.go +++ b/comp/core/autodiscovery/status/status.go @@ -12,13 +12,13 @@ import ( "github.com/DataDog/datadog-agent/comp/core/autodiscovery" "github.com/DataDog/datadog-agent/comp/core/status" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/containers" ) // populateStatus populates the status stats func populateStatus(ac autodiscovery.Component, stats map[string]interface{}) { - stats["adEnabledFeatures"] = config.GetDetectedFeatures() + stats["adEnabledFeatures"] = env.GetDetectedFeatures() stats["adConfigErrors"] = ac.GetAutodiscoveryErrors() stats["filterErrors"] = containers.GetFilterErrors() } @@ -33,7 +33,7 @@ type Provider struct { // GetProvider if agent is running in a container environment returns status.Provider otherwise returns nil func GetProvider(acComp autodiscovery.Component) status.Provider { - if config.IsContainerized() { + if env.IsContainerized() { return Provider{ac: acComp} } diff --git a/comp/core/config/component_mock.go b/comp/core/config/component_mock.go index 37fae0382acee..70d118ff36900 100644 --- a/comp/core/config/component_mock.go +++ b/comp/core/config/component_mock.go @@ -30,7 +30,9 @@ type Mock interface { Component } -// MockModule defines the fx options for the mock component. +// MockModule - deprecated - defines the fx options for the mock component. +// +// This is a legacy helper to get a config mock using Fx, use config.NewMock or config.NewMockFromYAML instead. func MockModule() fxutil.Module { return fxutil.Component( fx.Provide(newMock), diff --git a/comp/core/config/config_mock.go b/comp/core/config/config_mock.go index f4ab0e1242e85..b8c8f000a205e 100644 --- a/comp/core/config/config_mock.go +++ b/comp/core/config/config_mock.go @@ -9,14 +9,14 @@ package config import ( - "strings" "testing" - "github.com/DataDog/datadog-agent/comp/core/secrets" - "github.com/DataDog/datadog-agent/pkg/config/env" - pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model" - pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" "go.uber.org/fx" + + "github.com/DataDog/datadog-agent/comp/core/secrets" + "github.com/DataDog/datadog-agent/pkg/config/mock" + "github.com/DataDog/datadog-agent/pkg/config/model" + setup "github.com/DataDog/datadog-agent/pkg/config/setup" ) type mockDependencies struct { @@ -37,41 +37,34 @@ func (m mockDependencies) getSecretResolver() (secrets.Component, bool) { // newMock exported mock builder to allow modifying mocks that might be // supplied in tests and used for dep injection. func newMock(deps mockDependencies, t testing.TB) (Component, error) { - backupConfig := pkgconfigmodel.NewConfig("", "", strings.NewReplacer()) - backupConfig.CopyConfig(pkgconfigsetup.Datadog()) - - pkgconfigsetup.Datadog().CopyConfig(pkgconfigmodel.NewConfig("mock", "XXXX", strings.NewReplacer())) - - env.SetFeatures(t, deps.Params.Features...) - - // call InitConfig to set defaults. - pkgconfigsetup.InitConfig(pkgconfigsetup.Datadog()) - c := &cfg{ - Config: pkgconfigsetup.Datadog(), - } + var mockConf model.Config - if !deps.Params.SetupConfig { - if deps.Params.ConfFilePath != "" { - pkgconfigsetup.Datadog().SetConfigType("yaml") - err := pkgconfigsetup.Datadog().ReadConfig(strings.NewReader(deps.Params.ConfFilePath)) - if err != nil { - // The YAML was invalid, fail initialization of the mock config. - return nil, err - } - } + if deps.Params.ConfFilePath != "" { + mockConf = mock.NewFromFile(t, deps.Params.ConfFilePath) } else { - warnings, _ := setupConfig(pkgconfigsetup.Datadog(), deps) - c.warnings = warnings + mockConf = mock.New(t) } - // Overrides are explicit and will take precedence over any other - // setting + // Overrides are explicit and will take precedence over any other setting for k, v := range deps.Params.Overrides { - pkgconfigsetup.Datadog().SetWithoutSource(k, v) + mockConf.SetWithoutSource(k, v) } - // swap the existing config back at the end of the test. - t.Cleanup(func() { pkgconfigsetup.Datadog().CopyConfig(backupConfig) }) + setup.LoadProxyFromEnv(mockConf) + return &cfg{Config: mockConf}, nil +} + +// NewMock returns a mock for the config component +func NewMock(t testing.TB) Component { + return &cfg{Config: mock.New(t)} +} + +// NewMockFromYAML returns a mock for the config component with the given YAML content loaded into it. +func NewMockFromYAML(t testing.TB, yaml string) Component { + return &cfg{Config: mock.NewFromYAML(t, yaml)} +} - return c, nil +// NewMockFromYAMLFile returns a mock for the config component with the given YAML file loaded into it. +func NewMockFromYAMLFile(t testing.TB, yamlFilePath string) Component { + return &cfg{Config: mock.NewFromFile(t, yamlFilePath)} } diff --git a/comp/core/config/config_test.go b/comp/core/config/config_test.go index de890c31fdadf..46eb1737f040c 100644 --- a/comp/core/config/config_test.go +++ b/comp/core/config/config_test.go @@ -45,7 +45,7 @@ func TestRealConfig(t *testing.T) { } func TestMockConfig(t *testing.T) { - t.Setenv("XXXX_APP_KEY", "abc1234") + t.Setenv("DD_APP_KEY", "abc1234") t.Setenv("DD_URL", "https://example.com") config := fxutil.Test[Component](t, fx.Options( diff --git a/comp/core/config/go.mod b/comp/core/config/go.mod index f9dc8c96e26b8..2832dc70d1edd 100644 --- a/comp/core/config/go.mod +++ b/comp/core/config/go.mod @@ -12,6 +12,7 @@ replace ( github.com/DataDog/datadog-agent/comp/def => ../../def github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../pkg/config/model/ github.com/DataDog/datadog-agent/pkg/config/setup => ../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/telemetry => ../../../pkg/telemetry @@ -34,7 +35,7 @@ require ( github.com/DataDog/datadog-agent/comp/core/flare/types v0.56.0-rc.3 github.com/DataDog/datadog-agent/comp/core/secrets v0.56.0-rc.3 github.com/DataDog/datadog-agent/comp/core/telemetry v0.56.0-rc.3 - github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/config/setup v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/util/fxutil v0.56.0-rc.3 @@ -42,7 +43,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/winutil v0.56.0-rc.3 github.com/DataDog/viper v1.13.5 github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.18.2 + go.uber.org/fx v1.22.2 ) require ( @@ -50,6 +51,7 @@ require ( github.com/DataDog/datadog-agent/comp/core/flare/builder v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/executable v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/filesystem v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/hostname/validate v0.56.0-rc.3 // indirect @@ -100,15 +102,15 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/comp/core/config/go.sum b/comp/core/config/go.sum index c6025d21bc920..35de5be41fa6e 100644 --- a/comp/core/config/go.sum +++ b/comp/core/config/go.sum @@ -242,27 +242,27 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -305,11 +305,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -322,8 +322,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/comp/core/config/params.go b/comp/core/config/params.go index 52537b23a57b2..188aa742c2bdf 100644 --- a/comp/core/config/params.go +++ b/comp/core/config/params.go @@ -43,12 +43,17 @@ type Params struct { // defaultConfPath determines the default configuration path. // if defaultConfPath is empty, then no default configuration path is used. defaultConfPath string + + // cliOverride is a list of setting overrides from the CLI given to the configuration. The map associate + // settings name like "logs_config.enabled" to its value. + cliOverride map[string]interface{} } // NewParams creates a new instance of Params func NewParams(defaultConfPath string, options ...func(*Params)) Params { params := Params{ defaultConfPath: defaultConfPath, + cliOverride: map[string]interface{}{}, } for _, o := range options { o(¶ms) @@ -141,6 +146,14 @@ func WithFleetPoliciesDirPath(fleetPoliciesDirPath string) func(*Params) { } } +// WithCLIOverride registers a list of settings overrides from the CLI for the configuration. The map associate settings +// name like "logs_config.enabled" to its value. +func WithCLIOverride(setting string, value interface{}) func(*Params) { + return func(b *Params) { + b.cliOverride[setting] = value + } +} + // These functions are used in unit tests. // ConfigMissingOK determines whether it is a fatal error if the config diff --git a/comp/core/config/params_mock.go b/comp/core/config/params_mock.go index a918de8fbdb2d..02137a5168d8c 100644 --- a/comp/core/config/params_mock.go +++ b/comp/core/config/params_mock.go @@ -8,10 +8,6 @@ package config -import ( - pkgconfigenv "github.com/DataDog/datadog-agent/pkg/config/env" -) - // MockParams defines the parameter for the mock config. // It is designed to be used with `fx.Replace` which replaces the default // empty value of `MockParams`. @@ -22,10 +18,4 @@ type MockParams struct { // Overrides is a parameter used to override values of the config Overrides map[string]interface{} - - // Features is a parameter to set features for the mock config - Features []pkgconfigenv.Feature - - // SetupConfig sets up the config as if it weren't a mock; essentially a full init - SetupConfig bool } diff --git a/comp/core/config/params_test.go b/comp/core/config/params_test.go index b80ab5ef4df9a..0709912824c91 100644 --- a/comp/core/config/params_test.go +++ b/comp/core/config/params_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/DataDog/datadog-agent/cmd/agent/common/path" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -52,3 +53,8 @@ func TestNewSecurityAgentParams(t *testing.T) { require.Equal(t, false, configComponentParams.configMissingOK, "configMissingOK values not matching") } } + +func TestWithCLIOverride(t *testing.T) { + params := NewParams("test_path", WithCLIOverride("test.setting", true), WithCLIOverride("test.setting2", "test")) + assert.Equal(t, map[string]interface{}{"test.setting": true, "test.setting2": "test"}, params.cliOverride) +} diff --git a/comp/core/config/setup.go b/comp/core/config/setup.go index 8c6bf36e8701d..a3d29f4a5bbf0 100644 --- a/comp/core/config/setup.go +++ b/comp/core/config/setup.go @@ -77,6 +77,9 @@ func setupConfig(config pkgconfigmodel.Config, deps configDependencies) (*pkgcon } // Load the remote configuration + if p.FleetPoliciesDirPath == "" { + p.FleetPoliciesDirPath = config.GetString("fleet_policies_dir") + } if p.FleetPoliciesDirPath != "" { // Main config file err := config.MergeFleetPolicy(path.Join(p.FleetPoliciesDirPath, "datadog.yaml")) @@ -91,5 +94,9 @@ func setupConfig(config pkgconfigmodel.Config, deps configDependencies) (*pkgcon } } + for k, v := range p.cliOverride { + config.Set(k, v, pkgconfigmodel.SourceCLI) + } + return warnings, nil } diff --git a/comp/core/flare/component.go b/comp/core/flare/component.go index 1fb8c04e78434..0ac0ef51c87a5 100644 --- a/comp/core/flare/component.go +++ b/comp/core/flare/component.go @@ -26,7 +26,8 @@ type Component interface { } // Module defines the fx options for this component. -func Module() fxutil.Module { +func Module(params Params) fxutil.Module { return fxutil.Component( - fx.Provide(newFlare)) + fx.Provide(newFlare), + fx.Supply(params)) } diff --git a/comp/core/flare/helpers/send_flare.go b/comp/core/flare/helpers/send_flare.go index be2d06b157a32..5246ee5306469 100644 --- a/comp/core/flare/helpers/send_flare.go +++ b/comp/core/flare/helpers/send_flare.go @@ -8,6 +8,7 @@ package helpers import ( "context" "encoding/json" + "errors" "fmt" "io" "mime/multipart" @@ -184,7 +185,7 @@ func analyzeResponse(r *http.Response, apiKey string) (string, error) { if res.Error != "" { response := fmt.Sprintf("An error occurred while uploading the flare: %s. Please contact support by email.", res.Error) - return response, fmt.Errorf("%s", res.Error) + return response, errors.New(res.Error) } return fmt.Sprintf("Your logs were successfully uploaded. For future reference, your internal case id is %d", res.CaseID), nil diff --git a/comp/core/flare/helpers/send_flare_test.go b/comp/core/flare/helpers/send_flare_test.go index 216a0786e09a6..759971ad5d0d2 100644 --- a/comp/core/flare/helpers/send_flare_test.go +++ b/comp/core/flare/helpers/send_flare_test.go @@ -17,7 +17,6 @@ import ( "github.com/stretchr/testify/require" "github.com/DataDog/datadog-agent/comp/core/config" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/DataDog/datadog-agent/pkg/util/scrubber" "github.com/DataDog/datadog-agent/pkg/version" ) @@ -30,10 +29,7 @@ func TestMkURL(t *testing.T) { func TestFlareHasRightForm(t *testing.T) { var lastRequest *http.Request - cfg := fxutil.Test[config.Component]( - t, - config.MockModule(), - ) + cfg := config.NewMock(t) testCases := []struct { name string diff --git a/comp/core/flare/types/go.mod b/comp/core/flare/types/go.mod index e1645d0ddafc0..c494bbdb14a68 100644 --- a/comp/core/flare/types/go.mod +++ b/comp/core/flare/types/go.mod @@ -9,7 +9,7 @@ replace ( require ( github.com/DataDog/datadog-agent/comp/core/flare/builder v0.56.0-rc.3 - go.uber.org/fx v1.18.2 + go.uber.org/fx v1.22.2 ) require ( @@ -17,10 +17,9 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.9.0 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.23.0 // indirect - golang.org/x/sys v0.23.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/sys v0.24.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/comp/core/flare/types/go.sum b/comp/core/flare/types/go.sum index 59f1b2c43ed5f..8650f29648e1b 100644 --- a/comp/core/flare/types/go.sum +++ b/comp/core/flare/types/go.sum @@ -1,30 +1,21 @@ -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -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/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/comp/core/gui/guiimpl/agent.go b/comp/core/gui/guiimpl/agent.go index 8604467c25e18..e75b92b66946c 100644 --- a/comp/core/gui/guiimpl/agent.go +++ b/comp/core/gui/guiimpl/agent.go @@ -67,7 +67,7 @@ func getStatus(w http.ResponseWriter, r *http.Request, statusComponent status.Co } if err != nil { - log.Errorf("Error getting status: " + err.Error()) + log.Errorf("Error getting status: %s", err.Error()) w.Write([]byte("Error getting status: " + err.Error())) return } @@ -81,7 +81,7 @@ func getStatus(w http.ResponseWriter, r *http.Request, statusComponent status.Co func getVersion(w http.ResponseWriter, _ *http.Request) { version, e := version.Agent() if e != nil { - log.Errorf("Error getting version: " + e.Error()) + log.Errorf("Error getting version: %s", e.Error()) w.Write([]byte("Error: " + e.Error())) return } @@ -95,7 +95,7 @@ func getVersion(w http.ResponseWriter, _ *http.Request) { func getHostname(w http.ResponseWriter, r *http.Request) { hname, e := hostname.Get(r.Context()) if e != nil { - log.Errorf("Error getting hostname: " + e.Error()) + log.Errorf("Error getting hostname: %s", e.Error()) w.Write([]byte("Error: " + e.Error())) return } @@ -153,19 +153,19 @@ func makeFlare(w http.ResponseWriter, r *http.Request, flare flare.Component) { filePath, e := flare.Create(nil, nil) if e != nil { w.Write([]byte("Error creating flare zipfile: " + e.Error())) - log.Errorf("Error creating flare zipfile: " + e.Error()) + log.Errorf("Error creating flare zipfile: %s", e.Error()) return } res, e := flare.Send(filePath, payload.CaseID, payload.Email, helpers.NewLocalFlareSource()) if e != nil { w.Write([]byte("Flare zipfile successfully created: " + filePath + "

" + e.Error())) - log.Errorf("Flare zipfile successfully created: " + filePath + "\n" + e.Error()) + log.Errorf("Flare zipfile successfully created: %s\n%s", filePath, e.Error()) return } w.Write([]byte("Flare zipfile successfully created: " + filePath + "

" + res)) - log.Errorf("Flare zipfile successfully created: " + filePath + "\n" + res) + log.Infof("Flare zipfile successfully created: %s\n%s", filePath, res) } // Restarts the agent using the appropriate (platform-specific) restart function diff --git a/comp/core/gui/guiimpl/agent_test.go b/comp/core/gui/guiimpl/agent_test.go index 1232db2cc871f..ed0659b4bae9a 100644 --- a/comp/core/gui/guiimpl/agent_test.go +++ b/comp/core/gui/guiimpl/agent_test.go @@ -19,7 +19,6 @@ import ( "github.com/stretchr/testify/require" "github.com/DataDog/datadog-agent/comp/core/config" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) func Test_makeFlare(t *testing.T) { @@ -94,9 +93,7 @@ func Test_getConfigSetting(t *testing.T) { fakeGuiStartTimestamp := time.Now().Unix() - c := fxutil.Test[config.Component](t, - config.MockModule(), - ) + c := config.NewMock(t) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/comp/core/gui/guiimpl/checks.go b/comp/core/gui/guiimpl/checks.go index a66ba66a93d45..c72a4e8f39c64 100644 --- a/comp/core/gui/guiimpl/checks.go +++ b/comp/core/gui/guiimpl/checks.go @@ -83,7 +83,7 @@ func runCheckHandler(collector collector.Component, ac autodiscovery.Component) for _, ch := range instances { collector.RunCheck(ch) //nolint:errcheck } - log.Infof("Scheduled new check: " + name) + log.Infof("Scheduled new check: %s", name) } } @@ -156,14 +156,14 @@ func reloadCheckHandler(collector collector.Component, ac autodiscovery.Componen name := html.EscapeString(mux.Vars(r)["name"]) instances := pkgcollector.GetChecksByNameForConfigs(name, ac.GetAllConfigs()) if len(instances) == 0 { - log.Errorf("Can't reload " + name + ": check has no new instances.") + log.Errorf("Can't reload %s: check has no new instances.", name) w.Write([]byte("Can't reload " + name + ": check has no new instances")) return } killed, e := collector.ReloadAllCheckInstances(name, instances) if e != nil { - log.Errorf("Error reloading check: " + e.Error()) + log.Errorf("Error reloading check: %s", e.Error()) w.Write([]byte("Error reloading check: " + e.Error())) return } @@ -309,7 +309,7 @@ func setCheckConfigFile(w http.ResponseWriter, r *http.Request) { return } - log.Infof("Successfully wrote new " + fileName + " config file.") + log.Infof("Successfully wrote new %s config file.", fileName) w.Write([]byte("Success")) } else if r.Method == "DELETE" { // Attempt to write new configs to custom checks directory @@ -336,7 +336,7 @@ func setCheckConfigFile(w http.ResponseWriter, r *http.Request) { return } - log.Infof("Successfully disabled integration " + fileName + " config file.") + log.Infof("Successfully disabled integration %s config file.", fileName) w.Write([]byte("Success")) } } diff --git a/comp/core/gui/guiimpl/gui.go b/comp/core/gui/guiimpl/gui.go index 8685d49a89630..f05b6d45e32e4 100644 --- a/comp/core/gui/guiimpl/gui.go +++ b/comp/core/gui/guiimpl/gui.go @@ -38,6 +38,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/api/security" "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/DataDog/datadog-agent/pkg/util/optional" + "github.com/DataDog/datadog-agent/pkg/util/system" ) // Module defines the fx options for this component. @@ -50,7 +51,7 @@ func Module() fxutil.Module { type gui struct { logger log.Component - port string + address string listener net.Listener router *mux.Router @@ -105,8 +106,14 @@ func newGui(deps dependencies) provides { return p } + guiHost, err := system.IsLocalAddress(deps.Config.GetString("GUI_host")) + if err != nil { + deps.Log.Errorf("GUI server host is not a local address: %s", err) + return p + } + g := gui{ - port: guiPort, + address: net.JoinHostPort(guiHost, guiPort), logger: deps.Log, intentTokens: make(map[string]bool), } @@ -160,13 +167,13 @@ func (g *gui) start(_ context.Context) error { // Set start time... g.startTimestamp = time.Now().Unix() - g.listener, e = net.Listen("tcp", "127.0.0.1:"+g.port) + g.listener, e = net.Listen("tcp", g.address) if e != nil { g.logger.Errorf("GUI server didn't achieved to start: ", e) return nil } go http.Serve(g.listener, g.router) //nolint:errcheck - g.logger.Infof("GUI server is listening at 127.0.0.1:" + g.port) + g.logger.Info("GUI server is listening at " + g.address) return nil } diff --git a/comp/core/gui/guiimpl/views/private/js/javascript.js b/comp/core/gui/guiimpl/views/private/js/javascript.js index c78ea3c6168b5..e481cfbf7bf0d 100644 --- a/comp/core/gui/guiimpl/views/private/js/javascript.js +++ b/comp/core/gui/guiimpl/views/private/js/javascript.js @@ -63,10 +63,10 @@ function setError(status, message) { message = "Unable to contact the Datadog Agent. Please ensure it is running." } else if (status == 401) { - message = `Not logged in. Please ensure that your GUI session has not expired. (Agent replied with: ${message.trim()})` + message = "Not logged in. Please ensure that your GUI session has not expired. (Agent replied with: " + DOMPurify.sanitize(message.trim()) + ")" } - $("#error_content").html(`

Error

${DOMPurify.sanitize(message)}`) + $("#error_content").html("

Error

" + message) if (status == 401) { $("#logged_out").css("display", "block"); @@ -310,7 +310,8 @@ function loadManageChecks() { // Fetches the names of all the configuration (.yaml) files and fills the list of // checks to configure with the configurations for all currently enabled checks function loadCheckConfigFiles() { - $(".list").html(""); + // Create a temporary container (IE doesn't like adding elements in HTML elements) + var tempList = $("
"); sendMessage("checks/listConfigs", "", "post", function(data, status, xhr){ @@ -326,10 +327,13 @@ function loadCheckConfigFiles() { item.endsWith("auto_conf.yaml")) return; item = DOMPurify.sanitize(item) - $(".list").append('' + item + ''); }); + // Replace the existing .list content with the new HTML + $(".list").html(tempList.html()); + // Add highlighting current check functionality $(".check").click(function(){ $(".active_check").removeClass("active_check"); @@ -341,7 +345,8 @@ function loadCheckConfigFiles() { // Fetches the names of all the check (.py) files and fills the list of checks to add // with the checks which are not already enabled function loadNewChecks() { - $(".list").html(""); + // Create a temporary container (IE doesn't like adding elements in HTML elements) + var tempList = $("
"); // Get a list of all the currently enabled checks (aka checks with a valid config file) var enabledChecks = []; @@ -378,9 +383,13 @@ function loadNewChecks() { // Only display checks that aren't already enabled if (enabledChecks.indexOf(checkName) != -1) return; - $(".list").append('' + DOMPurify.sanitize(item) + ''); }); + + // Replace the existing .list content with the new HTML + $(".list").html(tempList.html()); + // Add current item highlighting $(".check").click(function(){ $(".active_check").removeClass("active_check"); @@ -720,7 +729,10 @@ function restartAgent() { if (data != "Success") { $("#general_status").css("display", "block"); $('#general_status').html("Error restarting agent: " + DOMPurify.sanitize(data) + ""); - } else loadStatus("general"); + } else { + $("#restart_status").hide() + loadStatus("general"); + } }, 10000); }, function(requestObject, error, errorThrown) { $(".loading_spinner").remove(); diff --git a/comp/core/hostname/hostnameinterface/go.mod b/comp/core/hostname/hostnameinterface/go.mod index 3b1233c54a4fe..62cb99d039257 100644 --- a/comp/core/hostname/hostnameinterface/go.mod +++ b/comp/core/hostname/hostnameinterface/go.mod @@ -11,7 +11,7 @@ replace ( require ( github.com/DataDog/datadog-agent/pkg/util/fxutil v0.56.0-rc.3 github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.18.2 + go.uber.org/fx v1.22.2 ) require ( @@ -22,10 +22,9 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.23.0 // indirect - golang.org/x/sys v0.23.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/sys v0.24.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/comp/core/hostname/hostnameinterface/go.sum b/comp/core/hostname/hostnameinterface/go.sum index c0c82340f4f98..fe7d4e245cb35 100644 --- a/comp/core/hostname/hostnameinterface/go.sum +++ b/comp/core/hostname/hostnameinterface/go.sum @@ -1,13 +1,8 @@ -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/cpuguy83/go-md2man/v2 v2.0.2/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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -15,24 +10,20 @@ github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/comp/core/log/impl-trace/go.mod b/comp/core/log/impl-trace/go.mod index 408810d6a5bcd..e3a9026fa0081 100644 --- a/comp/core/log/impl-trace/go.mod +++ b/comp/core/log/impl-trace/go.mod @@ -46,12 +46,12 @@ require ( github.com/DataDog/datadog-agent/pkg/util/log v0.56.0-rc.3 github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect; v2.6 github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.18.2 // indirect + go.uber.org/fx v1.22.2 // indirect ) require ( github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 - github.com/DataDog/datadog-agent/pkg/config/mock v0.0.0-00010101000000-000000000000 + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel github.com/DataDog/datadog-agent/pkg/util/log/setup v0.0.0-00010101000000-000000000000 ) @@ -123,16 +123,16 @@ require ( go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect + go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // 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 diff --git a/comp/core/log/impl-trace/go.sum b/comp/core/log/impl-trace/go.sum index 6ac06beb4393a..208e4a57ff402 100644 --- a/comp/core/log/impl-trace/go.sum +++ b/comp/core/log/impl-trace/go.sum @@ -21,8 +21,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -298,10 +296,10 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -319,11 +317,11 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U 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/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -353,8 +351,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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= @@ -393,8 +391,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -402,8 +400,8 @@ 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -423,8 +421,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/comp/core/log/impl/go.mod b/comp/core/log/impl/go.mod index cfb622287c7de..427c90bd25c8f 100644 --- a/comp/core/log/impl/go.mod +++ b/comp/core/log/impl/go.mod @@ -60,7 +60,7 @@ require ( github.com/DataDog/datadog-agent/comp/core/config v0.0.0-00010101000000-000000000000 github.com/DataDog/datadog-agent/comp/core/log/def v0.0.0-00010101000000-000000000000 github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 - github.com/DataDog/datadog-agent/pkg/config/mock v0.0.0-20240726104123-0f372a5f7b15 + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel github.com/DataDog/datadog-agent/pkg/util/log v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/util/log/setup v0.0.0-00010101000000-000000000000 github.com/stretchr/testify v1.9.0 @@ -112,16 +112,16 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/comp/core/log/impl/go.sum b/comp/core/log/impl/go.sum index 7d9bb18a9b376..c0f06ba5f32fa 100644 --- a/comp/core/log/impl/go.sum +++ b/comp/core/log/impl/go.sum @@ -12,8 +12,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -238,27 +236,27 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -301,11 +299,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -318,8 +316,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/comp/core/log/mock/go.mod b/comp/core/log/mock/go.mod index 5e0fbb6617091..1efe0ab121ea3 100644 --- a/comp/core/log/mock/go.mod +++ b/comp/core/log/mock/go.mod @@ -47,8 +47,8 @@ require ( github.com/spf13/jwalterweatherman v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/comp/core/log/mock/go.sum b/comp/core/log/mock/go.sum index 2d0841eb54f66..17a6b55b5cc64 100644 --- a/comp/core/log/mock/go.sum +++ b/comp/core/log/mock/go.sum @@ -178,8 +178,8 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -212,11 +212,11 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/comp/core/lsof/def/component.go b/comp/core/lsof/def/component.go new file mode 100644 index 0000000000000..2ff4766afa9f5 --- /dev/null +++ b/comp/core/lsof/def/component.go @@ -0,0 +1,13 @@ +// 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 2024-present Datadog, Inc. + +// Package lsof provides a flare file with data about files opened by the agent process +package lsof + +// team: agent-shared-components + +// Component is the component type. +type Component interface { +} diff --git a/comp/logs/integrations/fx/fx.go b/comp/core/lsof/fx/fx.go similarity index 51% rename from comp/logs/integrations/fx/fx.go rename to comp/core/lsof/fx/fx.go index 2c0b9011bf00a..97ace14de8aa6 100644 --- a/comp/logs/integrations/fx/fx.go +++ b/comp/core/lsof/fx/fx.go @@ -3,12 +3,12 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package fx provides the fx module for the integrations component +// Package fx provides the fx module for the lsof component package fx import ( - integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/impl" - integrationsmock "github.com/DataDog/datadog-agent/comp/logs/integrations/mock" + lsof "github.com/DataDog/datadog-agent/comp/core/lsof/def" + lsofimpl "github.com/DataDog/datadog-agent/comp/core/lsof/impl" "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) @@ -16,16 +16,8 @@ import ( func Module() fxutil.Module { return fxutil.Component( fxutil.ProvideComponentConstructor( - integrations.NewComponent, - ), - ) -} - -// MockModule provides the mock integrations component to fx -func MockModule() fxutil.Module { - return fxutil.Component( - fxutil.ProvideComponentConstructor( - integrationsmock.Mock, + lsofimpl.NewComponent, ), + fxutil.ProvideOptional[lsof.Component](), ) } diff --git a/comp/core/lsof/impl/lsof.go b/comp/core/lsof/impl/lsof.go new file mode 100644 index 0000000000000..82b5ad49465b7 --- /dev/null +++ b/comp/core/lsof/impl/lsof.go @@ -0,0 +1,53 @@ +// 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 2024-present Datadog, Inc. + +// Package lsofimpl implements the lsof component interface +package lsofimpl + +import ( + "errors" + "runtime" + + flaretypes "github.com/DataDog/datadog-agent/comp/core/flare/types" + lsofdef "github.com/DataDog/datadog-agent/comp/core/lsof/def" + "github.com/DataDog/datadog-agent/pkg/util/flavor" + "github.com/DataDog/datadog-agent/pkg/util/lsof" +) + +// Requires defines the dependencies for the lsof component +type Requires struct{} + +// Provides defines the output of the lsof component +type Provides struct { + Comp lsofdef.Component + FlareProvider flaretypes.Provider +} + +func fillFlare(fb flaretypes.FlareBuilder) error { + if fb.IsLocal() { + _ = fb.Logf("listing open files is not supported in local mode") + return nil + } + + files, err := lsof.ListOpenFilesFromSelf() + if err != nil { + if errors.Is(err, lsof.ErrNotImplemented) { + _ = fb.Logf("listing files opened by the agent process is not supported on %s/%s", runtime.GOOS, runtime.GOARCH) + return nil + } + _ = fb.Logf("could not list agent open files: %v", err) + return err + } + + return fb.AddFile(flavor.GetFlavor()+"_open_files.txt", []byte(files.String())) +} + +// NewComponent creates a new lsof component +func NewComponent(Requires) (Provides, error) { + provides := Provides{ + FlareProvider: flaretypes.NewProvider(fillFlare), + } + return provides, nil +} diff --git a/comp/core/lsof/mock/mock.go b/comp/core/lsof/mock/mock.go new file mode 100644 index 0000000000000..96483f892c7da --- /dev/null +++ b/comp/core/lsof/mock/mock.go @@ -0,0 +1,20 @@ +// 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 2024-present Datadog, Inc. + +//go:build test + +// Package mock provides a mock of the lsof component +package mock + +import ( + "testing" + + lsof "github.com/DataDog/datadog-agent/comp/core/lsof/def" +) + +// Mock returns a mock for lsof component. +func Mock(*testing.T) lsof.Component { + return struct{}{} +} diff --git a/comp/core/pid/pidimpl/pid.go b/comp/core/pid/pidimpl/pid.go index 1fae757733d72..3fa8142c331ea 100644 --- a/comp/core/pid/pidimpl/pid.go +++ b/comp/core/pid/pidimpl/pid.go @@ -55,7 +55,12 @@ func newPID(deps dependencies) (pid.Component, error) { deps.Lc.Append(fx.Hook{ OnStop: func(context.Context) error { - _ = os.Remove(pidfilePath) + err = os.Remove(pidfilePath) + if err != nil { + deps.Log.Errorf("Error while removing PID file: %v", err) + } else { + deps.Log.Infof("Removed PID file: %s", pidfilePath) + } return nil }}) } diff --git a/comp/core/secrets/go.mod b/comp/core/secrets/go.mod index b8f6a20dc49f4..6252656fb5509 100644 --- a/comp/core/secrets/go.mod +++ b/comp/core/secrets/go.mod @@ -26,9 +26,9 @@ require ( github.com/DataDog/datadog-agent/pkg/util/winutil v0.56.0-rc.3 github.com/benbjohnson/clock v1.3.0 github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.18.2 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/sys v0.23.0 + go.uber.org/fx v1.22.2 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/sys v0.24.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -40,7 +40,6 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect github.com/davecgh/go-spew v1.1.1 // 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/golang/protobuf v1.5.3 // indirect @@ -60,9 +59,9 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/comp/core/secrets/go.sum b/comp/core/secrets/go.sum index d9cd59ebe7aae..549ba4cbfdc4b 100644 --- a/comp/core/secrets/go.sum +++ b/comp/core/secrets/go.sum @@ -9,8 +9,6 @@ github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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/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= @@ -64,21 +62,21 @@ go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5 go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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/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/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/comp/core/settings/settingsimpl/settingsimpl_test.go b/comp/core/settings/settingsimpl/settingsimpl_test.go index 9f22a0e1887bb..5aca0e4fbc7da 100644 --- a/comp/core/settings/settingsimpl/settingsimpl_test.go +++ b/comp/core/settings/settingsimpl/settingsimpl_test.go @@ -312,7 +312,7 @@ func TestRuntimeSettings(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), fx.Supply( settings.Params{ - Config: fxutil.Test[config.Component](t, config.MockModule()), + Config: config.NewMock(t), Settings: map[string]settings.RuntimeSetting{ "foo": &runtimeTestSetting{ hidden: false, diff --git a/comp/core/status/go.mod b/comp/core/status/go.mod index c9d7ca18c1aa0..27b312c85a5be 100644 --- a/comp/core/status/go.mod +++ b/comp/core/status/go.mod @@ -7,8 +7,8 @@ require ( github.com/fatih/color v1.16.0 github.com/spf13/cast v1.6.0 github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.18.2 - golang.org/x/text v0.16.0 + go.uber.org/fx v1.22.2 + golang.org/x/text v0.17.0 ) require ( @@ -17,14 +17,9 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.uber.org/atomic v1.6.0 // indirect - go.uber.org/dig v1.15.0 // indirect - go.uber.org/multierr v1.5.0 // indirect - go.uber.org/zap v1.16.0 // indirect - golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/tools v0.23.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/sys v0.24.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/comp/core/status/go.sum b/comp/core/status/go.sum index d8b3ba6dc0b2a..87c5a4683792c 100644 --- a/comp/core/status/go.sum +++ b/comp/core/status/go.sum @@ -1,8 +1,3 @@ -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -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/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -13,13 +8,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -27,75 +17,31 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 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= -go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= -go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -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/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -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= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= -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/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.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= diff --git a/comp/core/status/statusimpl/common_header_provider_test.go b/comp/core/status/statusimpl/common_header_provider_test.go index bfe9461204d07..bdf9cda786b18 100644 --- a/comp/core/status/statusimpl/common_header_provider_test.go +++ b/comp/core/status/statusimpl/common_header_provider_test.go @@ -24,7 +24,7 @@ import ( ) func TestCommonHeaderProviderIndex(t *testing.T) { - config := fxutil.Test[config.Component](t, config.MockModule()) + config := config.NewMock(t) provider := newCommonHeaderProvider(agentParams, config) @@ -43,7 +43,7 @@ func TestCommonHeaderProviderJSON(t *testing.T) { os.Setenv("TZ", originalTZ) }() - config := fxutil.Test[config.Component](t, config.MockModule()) + config := config.NewMock(t) provider := newCommonHeaderProvider(agentParams, config) stats := map[string]interface{}{} @@ -73,7 +73,7 @@ func TestCommonHeaderProviderText(t *testing.T) { startTimeProvider = pkgconfigsetup.StartTime }() - config := fxutil.Test[config.Component](t, config.MockModule()) + config := config.NewMock(t) provider := newCommonHeaderProvider(agentParams, config) @@ -112,7 +112,7 @@ func TestCommonHeaderProviderTime(t *testing.T) { } defer func() { nowFunc = time.Now }() - config := fxutil.Test[config.Component](t, config.MockModule()) + config := config.NewMock(t) provider := newCommonHeaderProvider(agentParams, config) @@ -193,7 +193,7 @@ func TestCommonHeaderProviderHTML(t *testing.T) { os.Setenv("TZ", originalTZ) }() - config := fxutil.Test[config.Component](t, config.MockModule()) + config := config.NewMock(t) provider := newCommonHeaderProvider(agentParams, config) diff --git a/comp/core/status/statusimpl/go.mod b/comp/core/status/statusimpl/go.mod index f8467f1d037f6..a144e2c7ab101 100644 --- a/comp/core/status/statusimpl/go.mod +++ b/comp/core/status/statusimpl/go.mod @@ -16,6 +16,7 @@ replace ( github.com/DataDog/datadog-agent/comp/def => ../../../def github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../../pkg/config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/telemetry => ../../../../pkg/telemetry @@ -49,8 +50,8 @@ require ( github.com/DataDog/datadog-agent/pkg/version v0.56.0-rc.3 github.com/gorilla/mux v1.8.1 github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.18.2 - golang.org/x/text v0.16.0 + go.uber.org/fx v1.22.2 + golang.org/x/text v0.17.0 ) require ( @@ -59,6 +60,7 @@ require ( github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel // indirect github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/executable v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/filesystem v0.56.0-rc.3 // indirect @@ -104,11 +106,11 @@ require ( github.com/tklauser/numcpus v0.8.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect + go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/sys v0.24.0 // indirect google.golang.org/protobuf v1.34.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/comp/core/status/statusimpl/go.sum b/comp/core/status/statusimpl/go.sum index 083a327c9b4de..7099150b7bf3c 100644 --- a/comp/core/status/statusimpl/go.sum +++ b/comp/core/status/statusimpl/go.sum @@ -11,8 +11,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -249,10 +247,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -268,8 +266,8 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -307,11 +305,11 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/comp/core/tagger/README.md b/comp/core/tagger/README.md index 9f675f848d968..88ad5d8229623 100644 --- a/comp/core/tagger/README.md +++ b/comp/core/tagger/README.md @@ -53,7 +53,7 @@ Tagger entities are identified by a string-typed ID, with one of the following f | workloadmeta.KindContainer | `container_id://` | | workloadmeta.KindContainerImageMetadata | `container_image_metadata://` | | workloadmeta.KindECSTask | `ecs_task://` | -| workloadmeta.KindHost | `host` | +| workloadmeta.KindHost | `host://` | | workloadmeta.KindKubernetesDeployment | `deployment:///` | | workloadmeta.KindKubernetesMetadata | `kubernetes_metadata://///` (`` is empty in cluster-scoped objects) | | workloadmeta.KindKubernetesPod | `kubernetes_pod_uid://` | diff --git a/comp/core/tagger/common/prefixes.go b/comp/core/tagger/common/prefixes.go new file mode 100644 index 0000000000000..6988fcb1c8675 --- /dev/null +++ b/comp/core/tagger/common/prefixes.go @@ -0,0 +1,42 @@ +// 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 2024-present Datadog, Inc. + +// Package common provides common constants and methods for the tagger component and implementation +package common + +import "github.com/DataDog/datadog-agent/comp/core/tagger/types" + +const ( + // ContainerID is the prefix `container_id` + ContainerID types.EntityIDPrefix = "container_id" + // ContainerImageMetadata is the prefix `container_image_metadata` + ContainerImageMetadata types.EntityIDPrefix = "container_image_metadata" + // ECSTask is the prefix `ecs_task` + ECSTask types.EntityIDPrefix = "ecs_task" + // Host is the prefix `host` + Host types.EntityIDPrefix = "host" + // KubernetesDeployment is the prefix `deployment` + KubernetesDeployment types.EntityIDPrefix = "deployment" + // KubernetesMetadata is the prefix `kubernetes_metadata` + KubernetesMetadata types.EntityIDPrefix = "kubernetes_metadata" + // KubernetesPodUID is the prefix `kubernetes_pod_uid` + KubernetesPodUID types.EntityIDPrefix = "kubernetes_pod_uid" + // Process is the prefix `process` + Process types.EntityIDPrefix = "process" +) + +// AllPrefixesSet returns a set of all possible entity id prefixes that can be used in the tagger +func AllPrefixesSet() map[types.EntityIDPrefix]struct{} { + return map[types.EntityIDPrefix]struct{}{ + ContainerID: {}, + ContainerImageMetadata: {}, + ECSTask: {}, + Host: {}, + KubernetesDeployment: {}, + KubernetesMetadata: {}, + KubernetesPodUID: {}, + Process: {}, + } +} diff --git a/comp/core/tagger/taggerimpl/collectors/workloadmeta_extract.go b/comp/core/tagger/taggerimpl/collectors/workloadmeta_extract.go index d5692a04d53f4..aa4208829ca7e 100644 --- a/comp/core/tagger/taggerimpl/collectors/workloadmeta_extract.go +++ b/comp/core/tagger/taggerimpl/collectors/workloadmeta_extract.go @@ -9,18 +9,16 @@ import ( "encoding/json" "errors" "fmt" - "slices" "strings" + "github.com/DataDog/datadog-agent/comp/core/tagger/common" k8smetadata "github.com/DataDog/datadog-agent/comp/core/tagger/k8s_metadata" "github.com/DataDog/datadog-agent/comp/core/tagger/taglist" "github.com/DataDog/datadog-agent/comp/core/tagger/tags" "github.com/DataDog/datadog-agent/comp/core/tagger/types" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/config" - "github.com/DataDog/datadog-agent/pkg/util/containers" "github.com/DataDog/datadog-agent/pkg/util/kubernetes" - "github.com/DataDog/datadog-agent/pkg/util/kubernetes/kubelet" "github.com/DataDog/datadog-agent/pkg/util/log" ) @@ -114,8 +112,6 @@ var ( highCardOrchestratorLabels = map[string]string{ "io.rancher.container.name": tags.RancherContainer, } - - handledKubernetesMetadataResources = []string{"namespaces", "nodes"} ) func (c *WorkloadMetaCollector) processEvents(evBundle workloadmeta.EventBundle) { @@ -156,7 +152,7 @@ func (c *WorkloadMetaCollector) processEvents(evBundle workloadmeta.EventBundle) case workloadmeta.KindProcess: // tagInfos = append(tagInfos, c.handleProcess(ev)...) No tags for now case workloadmeta.KindKubernetesDeployment: - // tagInfos = append(tagInfos, c.handleDeployment(ev)...) No tags for now + tagInfos = append(tagInfos, c.handleKubeDeployment(ev)...) default: log.Errorf("cannot handle event for entity %q with kind %q", entityID.ID, entityID.Kind) } @@ -346,16 +342,24 @@ func (c *WorkloadMetaCollector) handleKubePod(ev workloadmeta.Event) []*types.Ta c.extractTagsFromPodLabels(pod, tagList) + // pod labels as tags + for name, value := range pod.Labels { + k8smetadata.AddMetadataAsTags(name, value, c.k8sResourcesLabelsAsTags["pods"], c.globK8sResourcesLabels["pods"], tagList) + } + + // pod annotations as tags for name, value := range pod.Annotations { - k8smetadata.AddMetadataAsTags(name, value, c.annotationsAsTags, c.globAnnotations, tagList) + k8smetadata.AddMetadataAsTags(name, value, c.k8sResourcesAnnotationsAsTags["pods"], c.globK8sResourcesAnnotations["pods"], tagList) } + // namespace labels as tags for name, value := range pod.NamespaceLabels { - k8smetadata.AddMetadataAsTags(name, value, c.nsLabelsAsTags, c.globNsLabels, tagList) + k8smetadata.AddMetadataAsTags(name, value, c.k8sResourcesLabelsAsTags["namespaces"], c.globK8sResourcesLabels["namespaces"], tagList) } + // namespace annotations as tags for name, value := range pod.NamespaceAnnotations { - k8smetadata.AddMetadataAsTags(name, value, c.nsAnnotationsAsTags, c.globNsAnnotations, tagList) + k8smetadata.AddMetadataAsTags(name, value, c.k8sResourcesAnnotationsAsTags["namespaces"], c.globK8sResourcesAnnotations["namespaces"], tagList) } kubeServiceDisabled := false @@ -513,31 +517,79 @@ func (c *WorkloadMetaCollector) handleGardenContainer(container *workloadmeta.Co } } -func (c *WorkloadMetaCollector) handleKubeMetadata(ev workloadmeta.Event) []*types.TagInfo { - kubeMetadata := ev.Entity.(*workloadmeta.KubernetesMetadata) +func (c *WorkloadMetaCollector) handleKubeDeployment(ev workloadmeta.Event) []*types.TagInfo { + deployment := ev.Entity.(*workloadmeta.KubernetesDeployment) - resource := kubeMetadata.GVR.Resource + groupResource := "deployments.apps" - if !slices.Contains(handledKubernetesMetadataResources, resource) { + labelsAsTags := c.k8sResourcesLabelsAsTags[groupResource] + annotationsAsTags := c.k8sResourcesAnnotationsAsTags[groupResource] + + if len(labelsAsTags)+len(annotationsAsTags) == 0 { return nil } + globLabels := c.globK8sResourcesLabels[groupResource] + globAnnotations := c.globK8sResourcesAnnotations[groupResource] + tagList := taglist.NewTagList() - switch resource { - case "nodes": - // No tags for nodes - case "namespaces": - for name, value := range kubeMetadata.Labels { - k8smetadata.AddMetadataAsTags(name, value, c.nsLabelsAsTags, c.globNsLabels, tagList) - } + for name, value := range deployment.Labels { + k8smetadata.AddMetadataAsTags(name, value, labelsAsTags, globLabels, tagList) + } - for name, value := range kubeMetadata.Annotations { - k8smetadata.AddMetadataAsTags(name, value, c.nsAnnotationsAsTags, c.globNsAnnotations, tagList) - } + for name, value := range deployment.Annotations { + k8smetadata.AddMetadataAsTags(name, value, annotationsAsTags, globAnnotations, tagList) + } + + low, orch, high, standard := tagList.Compute() + + if len(low)+len(orch)+len(high)+len(standard) == 0 { + return nil + } + + tagInfos := []*types.TagInfo{ + { + Source: deploymentSource, + Entity: buildTaggerEntityID(deployment.EntityID), + HighCardTags: high, + OrchestratorCardTags: orch, + LowCardTags: low, + StandardTags: standard, + }, + } + + return tagInfos +} + +func (c *WorkloadMetaCollector) handleKubeMetadata(ev workloadmeta.Event) []*types.TagInfo { + kubeMetadata := ev.Entity.(*workloadmeta.KubernetesMetadata) + + tagList := taglist.NewTagList() + + // Generic resource annotations and labels as tags + groupResource := kubeMetadata.GVR.GroupResource().String() + + labelsAsTags := c.k8sResourcesLabelsAsTags[groupResource] + annotationsAsTags := c.k8sResourcesAnnotationsAsTags[groupResource] + + globLabels := c.globK8sResourcesLabels[groupResource] + globAnnotations := c.globK8sResourcesAnnotations[groupResource] + + for name, value := range kubeMetadata.Labels { + k8smetadata.AddMetadataAsTags(name, value, labelsAsTags, globLabels, tagList) + } + + for name, value := range kubeMetadata.Annotations { + k8smetadata.AddMetadataAsTags(name, value, annotationsAsTags, globAnnotations, tagList) } low, orch, high, standard := tagList.Compute() + + if len(low)+len(orch)+len(high)+len(standard) == 0 { + return nil + } + tagInfos := []*types.TagInfo{ { Source: kubeMetadataSource, @@ -575,7 +627,7 @@ func (c *WorkloadMetaCollector) extractTagsFromPodLabels(pod *workloadmeta.Kuber tagList.AddLow(tags.KubeAppManagedBy, value) } - k8smetadata.AddMetadataAsTags(name, value, c.labelsAsTags, c.globLabels, tagList) + k8smetadata.AddMetadataAsTags(name, value, c.k8sResourcesLabelsAsTags["pods"], c.globK8sResourcesLabels["pods"], tagList) } } @@ -769,21 +821,21 @@ func (c *WorkloadMetaCollector) addOpenTelemetryStandardTags(container *workload func buildTaggerEntityID(entityID workloadmeta.EntityID) string { switch entityID.Kind { case workloadmeta.KindContainer: - return containers.BuildTaggerEntityName(entityID.ID) + return common.ContainerID.ToUID(entityID.ID) case workloadmeta.KindKubernetesPod: - return kubelet.PodUIDToTaggerEntityName(entityID.ID) + return common.KubernetesPodUID.ToUID(entityID.ID) case workloadmeta.KindECSTask: - return fmt.Sprintf("ecs_task://%s", entityID.ID) + return common.ECSTask.ToUID(entityID.ID) case workloadmeta.KindContainerImageMetadata: - return fmt.Sprintf("container_image_metadata://%s", entityID.ID) + return common.ContainerImageMetadata.ToUID(entityID.ID) case workloadmeta.KindProcess: - return fmt.Sprintf("process://%s", entityID.ID) + return common.Process.ToUID(entityID.ID) case workloadmeta.KindKubernetesDeployment: - return fmt.Sprintf("deployment://%s", entityID.ID) + return common.KubernetesDeployment.ToUID(entityID.ID) case workloadmeta.KindHost: - return fmt.Sprintf("host://%s", entityID.ID) + return common.Host.ToUID(entityID.ID) case workloadmeta.KindKubernetesMetadata: - return fmt.Sprintf("kubernetes_metadata://%s", entityID.ID) + return common.KubernetesMetadata.ToUID(entityID.ID) default: log.Errorf("can't recognize entity %q with kind %q; trying %s://%s as tagger entity", entityID.ID, entityID.Kind, entityID.ID, entityID.Kind) diff --git a/comp/core/tagger/taggerimpl/collectors/workloadmeta_main.go b/comp/core/tagger/taggerimpl/collectors/workloadmeta_main.go index becd0400a307d..3103c0bb777a6 100644 --- a/comp/core/tagger/taggerimpl/collectors/workloadmeta_main.go +++ b/comp/core/tagger/taggerimpl/collectors/workloadmeta_main.go @@ -16,6 +16,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/tagger/types" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/config" + configutils "github.com/DataDog/datadog-agent/pkg/config/utils" "github.com/DataDog/datadog-agent/pkg/status/health" "github.com/DataDog/datadog-agent/pkg/util" "github.com/DataDog/datadog-agent/pkg/util/flavor" @@ -34,6 +35,7 @@ const ( processSource = workloadmetaCollectorName + "-" + string(workloadmeta.KindProcess) hostSource = workloadmetaCollectorName + "-" + string(workloadmeta.KindHost) kubeMetadataSource = workloadmetaCollectorName + "-" + string(workloadmeta.KindKubernetesMetadata) + deploymentSource = workloadmetaCollectorName + "-" + string(workloadmeta.KindKubernetesDeployment) clusterTagNamePrefix = "kube_cluster_name" ) @@ -55,17 +57,13 @@ type WorkloadMetaCollector struct { containerEnvAsTags map[string]string containerLabelsAsTags map[string]string - staticTags map[string]string - labelsAsTags map[string]string - annotationsAsTags map[string]string - nsLabelsAsTags map[string]string - nsAnnotationsAsTags map[string]string - globLabels map[string]glob.Glob - globAnnotations map[string]glob.Glob - globNsLabels map[string]glob.Glob - globNsAnnotations map[string]glob.Glob - globContainerLabels map[string]glob.Glob - globContainerEnvLabels map[string]glob.Glob + staticTags map[string]string + k8sResourcesAnnotationsAsTags map[string]map[string]string + k8sResourcesLabelsAsTags map[string]map[string]string + globContainerLabels map[string]glob.Glob + globContainerEnvLabels map[string]glob.Glob + globK8sResourcesAnnotations map[string]map[string]glob.Glob + globK8sResourcesLabels map[string]map[string]glob.Glob collectEC2ResourceTags bool collectPersistentVolumeClaimsTags bool @@ -76,11 +74,19 @@ func (c *WorkloadMetaCollector) initContainerMetaAsTags(labelsAsTags, envAsTags c.containerEnvAsTags, c.globContainerEnvLabels = k8smetadata.InitMetadataAsTags(envAsTags) } -func (c *WorkloadMetaCollector) initPodMetaAsTags(labelsAsTags, annotationsAsTags, nsLabelsAsTags, nsAnnotationsAsTags map[string]string) { - c.labelsAsTags, c.globLabels = k8smetadata.InitMetadataAsTags(labelsAsTags) - c.annotationsAsTags, c.globAnnotations = k8smetadata.InitMetadataAsTags(annotationsAsTags) - c.nsLabelsAsTags, c.globNsLabels = k8smetadata.InitMetadataAsTags(nsLabelsAsTags) - c.nsAnnotationsAsTags, c.globNsAnnotations = k8smetadata.InitMetadataAsTags(nsAnnotationsAsTags) +func (c *WorkloadMetaCollector) initK8sResourcesMetaAsTags(resourcesLabelsAsTags, resourcesAnnotationsAsTags map[string]map[string]string) { + c.k8sResourcesAnnotationsAsTags = map[string]map[string]string{} + c.k8sResourcesLabelsAsTags = map[string]map[string]string{} + c.globK8sResourcesAnnotations = map[string]map[string]glob.Glob{} + c.globK8sResourcesLabels = map[string]map[string]glob.Glob{} + + for resource, labelsAsTags := range resourcesLabelsAsTags { + c.k8sResourcesLabelsAsTags[resource], c.globK8sResourcesLabels[resource] = k8smetadata.InitMetadataAsTags(labelsAsTags) + } + + for resource, annotationsAsTags := range resourcesAnnotationsAsTags { + c.k8sResourcesAnnotationsAsTags[resource], c.globK8sResourcesAnnotations[resource] = k8smetadata.InitMetadataAsTags(annotationsAsTags) + } } // Run runs the continuous event watching loop and sends new tags to the @@ -178,11 +184,9 @@ func NewWorkloadMetaCollector(_ context.Context, store workloadmeta.Component, p ) c.initContainerMetaAsTags(containerLabelsAsTags, containerEnvAsTags) - labelsAsTags := config.Datadog().GetStringMapString("kubernetes_pod_labels_as_tags") - annotationsAsTags := config.Datadog().GetStringMapString("kubernetes_pod_annotations_as_tags") - nsLabelsAsTags := config.Datadog().GetStringMapString("kubernetes_namespace_labels_as_tags") - nsAnnotationsAsTags := config.Datadog().GetStringMapString("kubernetes_namespace_annotations_as_tags") - c.initPodMetaAsTags(labelsAsTags, annotationsAsTags, nsLabelsAsTags, nsAnnotationsAsTags) + // kubernetes resources metadata as tags + metadataAsTags := configutils.GetMetadataAsTags(config.Datadog()) + c.initK8sResourcesMetaAsTags(metadataAsTags.GetResourcesLabelsAsTags(), metadataAsTags.GetResourcesAnnotationsAsTags()) return c } diff --git a/comp/core/tagger/taggerimpl/collectors/workloadmeta_test.go b/comp/core/tagger/taggerimpl/collectors/workloadmeta_test.go index 303604ad0c003..76a8f164dd136 100644 --- a/comp/core/tagger/taggerimpl/collectors/workloadmeta_test.go +++ b/comp/core/tagger/taggerimpl/collectors/workloadmeta_test.go @@ -21,6 +21,7 @@ import ( logmock "github.com/DataDog/datadog-agent/comp/core/log/mock" "github.com/DataDog/datadog-agent/comp/core/tagger/taglist" "github.com/DataDog/datadog-agent/comp/core/tagger/types" + "github.com/DataDog/datadog-agent/comp/core/workloadmeta/collectors/util" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" workloadmetafxmock "github.com/DataDog/datadog-agent/comp/core/workloadmeta/fx-mock" workloadmetamock "github.com/DataDog/datadog-agent/comp/core/workloadmeta/mock" @@ -68,9 +69,8 @@ func TestHandleKubePod(t *testing.T) { store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), fx.Supply(context.Background()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) store.Set(&workloadmeta.Container{ EntityID: workloadmeta.EntityID{ @@ -112,32 +112,38 @@ func TestHandleKubePod(t *testing.T) { }) tests := []struct { - name string - staticTags map[string]string - labelsAsTags map[string]string - annotationsAsTags map[string]string - nsLabelsAsTags map[string]string - nsAnnotationsAsTags map[string]string - pod workloadmeta.KubernetesPod - expected []*types.TagInfo + name string + staticTags map[string]string + k8sResourcesAnnotationsAsTags map[string]map[string]string + k8sResourcesLabelsAsTags map[string]map[string]string + pod workloadmeta.KubernetesPod + expected []*types.TagInfo }{ { name: "fully formed pod (no containers)", - annotationsAsTags: map[string]string{ - "gitcommit": "+gitcommit", - "component": "component", - }, - labelsAsTags: map[string]string{ - "ownerteam": "team", - "tier": "tier", - }, - nsLabelsAsTags: map[string]string{ - "ns_env": "ns_env", - "ns-ownerteam": "ns-team", + k8sResourcesAnnotationsAsTags: map[string]map[string]string{ + "pods": { + "ns_tier": "ns_tier", + "ns_custom": "custom_generic_annotation", + "gitcommit": "+gitcommit", + "component": "component", + }, + "namespaces": { + "ns_tier": "ns_tier", + "namespace_security": "ns_security", + }, }, - nsAnnotationsAsTags: map[string]string{ - "ns_tier": "ns_tier", - "namespace_security": "ns_security", + k8sResourcesLabelsAsTags: map[string]map[string]string{ + "pods": { + "ns_env": "ns_env", + "ns_custom": "custom_generic_label", + "ownerteam": "team", + "tier": "tier", + }, + "namespaces": { + "ns_env": "ns_env", + "ns_ownerteam": "ns_team", + }, }, pod: workloadmeta.KubernetesPod{ EntityID: podEntityID, @@ -149,6 +155,7 @@ func TestHandleKubePod(t *testing.T) { "GitCommit": "foobar", "ignoreme": "ignore", "component": "agent", + "ns_custom": "gee", // Custom tags from map "ad.datadoghq.com/tags": `{"pod_template_version":"1.0.0"}`, @@ -158,6 +165,7 @@ func TestHandleKubePod(t *testing.T) { "OwnerTeam": "container-integrations", "tier": "node", "pod-template-hash": "490794276", + "ns_custom": "zoo", // Standard tags "tags.datadoghq.com/env": env, @@ -177,7 +185,7 @@ func TestHandleKubePod(t *testing.T) { // NS labels as tags NamespaceLabels: map[string]string{ "ns_env": "dev", - "ns-ownerteam": "containers", + "ns_ownerteam": "containers", "foo": "bar", }, @@ -239,7 +247,7 @@ func TestHandleKubePod(t *testing.T) { "kube_service:service2", "kube_qos:guaranteed", "kube_runtime_class:myclass", - "ns-team:containers", + "ns_team:containers", "ns_env:dev", "ns_tier:some_tier", "ns_security:critical", @@ -247,6 +255,8 @@ func TestHandleKubePod(t *testing.T) { "pod_template_version:1.0.0", "team:container-integrations", "tier:node", + "custom_generic_label:zoo", + "custom_generic_annotation:gee", }, standardTags...), StandardTags: standardTags, }, @@ -837,8 +847,7 @@ func TestHandleKubePod(t *testing.T) { t.Run(tt.name, func(t *testing.T) { collector := NewWorkloadMetaCollector(context.Background(), store, nil) collector.staticTags = tt.staticTags - - collector.initPodMetaAsTags(tt.labelsAsTags, tt.annotationsAsTags, tt.nsLabelsAsTags, tt.nsAnnotationsAsTags) + collector.initK8sResourcesMetaAsTags(tt.k8sResourcesLabelsAsTags, tt.k8sResourcesAnnotationsAsTags) actual := collector.handleKubePod(workloadmeta.Event{ Type: workloadmeta.EventTypeSet, @@ -877,9 +886,8 @@ func TestHandleKubePodWithoutPvcAsTags(t *testing.T) { store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), fx.Supply(context.Background()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), ), fx.Replace(config.MockParams{Overrides: map[string]any{ "kubernetes_persistent_volume_claims_as_tags": false, }})) @@ -970,8 +978,6 @@ func TestHandleKubePodWithoutPvcAsTags(t *testing.T) { collector := NewWorkloadMetaCollector(context.Background(), store, nil) collector.staticTags = tt.staticTags - collector.initPodMetaAsTags(tt.labelsAsTags, tt.annotationsAsTags, tt.nsLabelsAsTags, tt.nsAnnotationsAsTags) - actual := collector.handleKubePod(workloadmeta.Event{ Type: workloadmeta.EventTypeSet, Entity: &tt.pod, @@ -1020,9 +1026,8 @@ func TestHandleKubePodNoContainerName(t *testing.T) { store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), fx.Supply(context.Background()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) store.Set(&workloadmeta.Container{ @@ -1118,8 +1123,6 @@ func TestHandleKubePodNoContainerName(t *testing.T) { collector := NewWorkloadMetaCollector(context.Background(), store, nil) collector.staticTags = tt.staticTags - collector.initPodMetaAsTags(tt.labelsAsTags, tt.annotationsAsTags, tt.nsLabelsAsTags, tt.annotationsAsTags) - actual := collector.handleKubePod(workloadmeta.Event{ Type: workloadmeta.EventTypeSet, Entity: &tt.pod, @@ -1138,14 +1141,11 @@ func TestHandleKubeMetadata(t *testing.T) { ID: fmt.Sprintf("namespaces//%s", namespace), } - taggerEntityID := fmt.Sprintf("kubernetes_metadata://%s", kubeMetadataEntityID.ID) - store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), fx.Supply(context.Background()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) store.Set(&workloadmeta.Container{ @@ -1159,36 +1159,37 @@ func TestHandleKubeMetadata(t *testing.T) { }) tests := []struct { - name string - labelsAsTags map[string]string - annotationsAsTags map[string]string - nsLabelsAsTags map[string]string - nsAnnotationsAsTags map[string]string - kubeMetadata workloadmeta.KubernetesMetadata - expected []*types.TagInfo + name string + k8sResourcesAnnotationsAsTags map[string]map[string]string + k8sResourcesLabelsAsTags map[string]map[string]string + kubeMetadata workloadmeta.KubernetesMetadata + expected []*types.TagInfo }{ { - name: "namespace", - nsLabelsAsTags: map[string]string{ - "ns_env": "ns_env", - "ns-ownerteam": "ns-team", + name: "namespace with labels and annotations as tags", + k8sResourcesAnnotationsAsTags: map[string]map[string]string{ + "namespaces": { + "ns_tier": "ns_tier", + "ns_custom": "custom_generic_annotation", + "namespace_security": "ns_security", + }, }, - nsAnnotationsAsTags: map[string]string{ - "ns_tier": "ns_tier", - "namespace_security": "ns_security", + k8sResourcesLabelsAsTags: map[string]map[string]string{ + "namespaces": { + "ns_env": "ns_env", + "ns_custom": "custom_generic_label", + "ns_ownerteam": "ns_team", + }, }, kubeMetadata: workloadmeta.KubernetesMetadata{ EntityID: kubeMetadataEntityID, EntityMeta: workloadmeta.EntityMeta{ Name: namespace, Labels: map[string]string{ - "ns_env": "dev", - "ns-ownerteam": "containers", - "foo": "bar", + "a": "dev", }, Annotations: map[string]string{ - "ns_tier": "some_tier", - "namespace_security": "critical", + "b": "some_tier", }, }, GVR: &schema.GroupVersionResource{ @@ -1196,6 +1197,132 @@ func TestHandleKubeMetadata(t *testing.T) { Resource: "namespaces", }, }, + expected: nil, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + collector := NewWorkloadMetaCollector(context.Background(), store, nil) + + collector.initK8sResourcesMetaAsTags(test.k8sResourcesLabelsAsTags, test.k8sResourcesAnnotationsAsTags) + + actual := collector.handleKubeMetadata(workloadmeta.Event{ + Type: workloadmeta.EventTypeSet, + Entity: &test.kubeMetadata, + }) + + assertTagInfoListEqual(tt, test.expected, actual) + }) + } +} + +func TestHandleKubeDeployment(t *testing.T) { + const deploymentName = "fooapp" + + kubeMetadataID := string(util.GenerateKubeMetadataEntityID("apps", "deployments", "default", deploymentName)) + + kubeMetadataEntityID := workloadmeta.EntityID{ + Kind: workloadmeta.KindKubernetesMetadata, + ID: kubeMetadataID, + } + + taggerEntityID := fmt.Sprintf("kubernetes_metadata://%s", kubeMetadataEntityID.ID) + + store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( + fx.Provide(func() log.Component { return logmock.New(t) }), + config.MockModule(), + fx.Supply(context.Background()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), + )) + + store.Set(&workloadmeta.Container{ + EntityID: workloadmeta.EntityID{ + Kind: workloadmeta.KindKubernetesMetadata, + ID: kubeMetadataID, + }, + EntityMeta: workloadmeta.EntityMeta{ + Name: deploymentName, + Namespace: "default", + }, + }) + + tests := []struct { + name string + k8sResourcesAnnotationsAsTags map[string]map[string]string + k8sResourcesLabelsAsTags map[string]map[string]string + kubeMetadata workloadmeta.KubernetesMetadata + expected []*types.TagInfo + }{ + { + name: "deployment with no matching labels/annotations for annotations/labels as tags. should return nil to avoid empty tagger entity", + k8sResourcesAnnotationsAsTags: map[string]map[string]string{ + "deployments.apps": { + "depl_tier": "depl_tier", + "depl_custom": "custom_generic_annotation", + }, + }, + k8sResourcesLabelsAsTags: map[string]map[string]string{ + "deployments.apps": { + "depl_env": "depl_env", + "depl_custom": "custom_generic_label", + }, + }, + kubeMetadata: workloadmeta.KubernetesMetadata{ + EntityID: kubeMetadataEntityID, + EntityMeta: workloadmeta.EntityMeta{ + Name: deploymentName, + Labels: map[string]string{ + "a": "dev", + }, + Annotations: map[string]string{ + "b": "some_tier", + }, + }, + GVR: &schema.GroupVersionResource{ + Version: "v1", + Group: "apps", + Resource: "deployments", + }, + }, + expected: nil, + }, + { + name: "deployment with generic annotations/labels as tags", + k8sResourcesAnnotationsAsTags: map[string]map[string]string{ + "deployments.apps": { + "depl_tier": "depl_tier", + "depl_custom": "custom_generic_annotation", + }, + }, + k8sResourcesLabelsAsTags: map[string]map[string]string{ + "deployments.apps": { + "depl_env": "depl_env", + "depl_custom": "custom_generic_label", + }, + }, + kubeMetadata: workloadmeta.KubernetesMetadata{ + EntityID: kubeMetadataEntityID, + EntityMeta: workloadmeta.EntityMeta{ + Name: deploymentName, + Labels: map[string]string{ + "depl_env": "dev", + "depl_ownerteam": "containers", + "foo": "bar", + "depl_custom": "zoo", + }, + Annotations: map[string]string{ + "depl_tier": "some_tier", + "depl_security": "critical", + "depl_custom": "gee", + }, + }, + GVR: &schema.GroupVersionResource{ + Version: "v1", + Group: "apps", + Resource: "deployments", + }, + }, expected: []*types.TagInfo{ { Source: kubeMetadataSource, @@ -1203,10 +1330,10 @@ func TestHandleKubeMetadata(t *testing.T) { HighCardTags: []string{}, OrchestratorCardTags: []string{}, LowCardTags: []string{ - "ns_env:dev", - "ns-team:containers", - "ns_tier:some_tier", - "ns_security:critical", + "depl_env:dev", + "depl_tier:some_tier", + "custom_generic_label:zoo", + "custom_generic_annotation:gee", }, StandardTags: []string{}, }, @@ -1214,18 +1341,18 @@ func TestHandleKubeMetadata(t *testing.T) { }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { collector := NewWorkloadMetaCollector(context.Background(), store, nil) - collector.initPodMetaAsTags(tt.labelsAsTags, tt.annotationsAsTags, tt.nsLabelsAsTags, tt.nsAnnotationsAsTags) + collector.initK8sResourcesMetaAsTags(test.k8sResourcesLabelsAsTags, test.k8sResourcesAnnotationsAsTags) actual := collector.handleKubeMetadata(workloadmeta.Event{ Type: workloadmeta.EventTypeSet, - Entity: &tt.kubeMetadata, + Entity: &test.kubeMetadata, }) - assertTagInfoListEqual(t, tt.expected, actual) + assertTagInfoListEqual(tt, test.expected, actual) }) } } @@ -1246,8 +1373,7 @@ func TestHandleECSTask(t *testing.T) { store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), ), fx.Replace(config.MockParams{Overrides: map[string]any{ "ecs_collect_resource_tags_ec2": true, }})) @@ -2059,8 +2185,7 @@ func TestHandleDelete(t *testing.T) { store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) store.Set(&workloadmeta.Container{ @@ -2135,8 +2260,7 @@ func TestHandlePodWithDeletedContainer(t *testing.T) { fakeStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) collector := NewWorkloadMetaCollector(context.Background(), fakeStore, &fakeProcessor{collectorCh}) collector.children = map[string]map[string]struct{}{ diff --git a/comp/core/tagger/taggerimpl/local/tagger_test.go b/comp/core/tagger/taggerimpl/local/tagger_test.go index bdfb0e28bdca4..1e03371474607 100644 --- a/comp/core/tagger/taggerimpl/local/tagger_test.go +++ b/comp/core/tagger/taggerimpl/local/tagger_test.go @@ -33,8 +33,7 @@ func TestTagBuilder(t *testing.T) { fx.Supply(log.Params{}), fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) tel := fxutil.Test[telemetry.Component](t, telemetryimpl.MockModule()) diff --git a/comp/core/tagger/taggerimpl/tagger.go b/comp/core/tagger/taggerimpl/tagger.go index 0292acddf03b4..65e75abe51ddd 100644 --- a/comp/core/tagger/taggerimpl/tagger.go +++ b/comp/core/tagger/taggerimpl/tagger.go @@ -437,7 +437,7 @@ func (t *TaggerClient) EnrichTags(tb tagset.TagsAccumulator, originInfo taggerty if originInfo.FromUDS != packets.NoOrigin && (originInfo.FromTag == "" || !t.datadogConfig.dogstatsdEntityIDPrecedenceEnabled) { if err := t.AccumulateTagsFor(originInfo.FromUDS, cardinality, tb); err != nil { - t.log.Errorf(err.Error()) + t.log.Errorf("%s", err.Error()) } } @@ -462,7 +462,7 @@ func (t *TaggerClient) EnrichTags(tb tagset.TagsAccumulator, originInfo taggerty // Tag using Local Data if originInfo.FromUDS != packets.NoOrigin { if err := t.AccumulateTagsFor(originInfo.FromUDS, cardinality, tb); err != nil { - t.log.Errorf(err.Error()) + t.log.Errorf("%s", err.Error()) } } diff --git a/comp/core/tagger/taggerimpl/tagger_mock.go b/comp/core/tagger/taggerimpl/tagger_mock.go index 0ab0db74c98a9..68d46a19d0707 100644 --- a/comp/core/tagger/taggerimpl/tagger_mock.go +++ b/comp/core/tagger/taggerimpl/tagger_mock.go @@ -69,9 +69,8 @@ func MockModule() fxutil.Module { config.MockModule(), sysprobeconfigimpl.MockModule(), fx.Supply(tagger.NewFakeTaggerParams()), - fx.Supply(workloadmeta.NewParams()), + workloadmetafx.Module(workloadmeta.NewParams()), telemetryimpl.MockModule(), - workloadmetafx.Module(), ) } diff --git a/comp/core/tagger/types/types.go b/comp/core/tagger/types/types.go index 5cc3df3487001..cbe90462ce2b3 100644 --- a/comp/core/tagger/types/types.go +++ b/comp/core/tagger/types/types.go @@ -164,3 +164,16 @@ type EntityEvent struct { EventType EventType Entity Entity } + +// EntityIDPrefix represents the prefix of a TagEntity id +type EntityIDPrefix string + +// ToUID builds a unique id from the passed id +// if the passed id is empty, an empty string is returned +// else it returns `{entityPrefix}://{id}` +func (e EntityIDPrefix) ToUID(id string) string { + if id == "" { + return "" + } + return fmt.Sprintf("%s://%s", e, id) +} diff --git a/comp/core/telemetry/go.mod b/comp/core/telemetry/go.mod index 7317611131838..a668c00c8d120 100644 --- a/comp/core/telemetry/go.mod +++ b/comp/core/telemetry/go.mod @@ -16,7 +16,7 @@ require ( go.opentelemetry.io/otel/exporters/prometheus v0.42.0 go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk/metric v1.27.0 - go.uber.org/fx v1.18.2 + go.uber.org/fx v1.22.2 ) require ( @@ -38,11 +38,10 @@ require ( go.opentelemetry.io/otel v1.27.0 // indirect go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.23.0 // indirect - golang.org/x/sys v0.23.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/sys v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/comp/core/telemetry/go.sum b/comp/core/telemetry/go.sum index a0165a70e28ad..2c258e412605d 100644 --- a/comp/core/telemetry/go.sum +++ b/comp/core/telemetry/go.sum @@ -1,11 +1,8 @@ -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.2/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/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -28,8 +25,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= @@ -47,8 +42,6 @@ github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= @@ -63,21 +56,19 @@ go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2N 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.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/comp/core/workloadmeta/collectors/internal/cloudfoundry/container/cf_container.go b/comp/core/workloadmeta/collectors/internal/cloudfoundry/container/cf_container.go index 9b43ed3394a9d..d19169605b4cc 100644 --- a/comp/core/workloadmeta/collectors/internal/cloudfoundry/container/cf_container.go +++ b/comp/core/workloadmeta/collectors/internal/cloudfoundry/container/cf_container.go @@ -16,6 +16,7 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/errors" "github.com/DataDog/datadog-agent/pkg/util/cloudproviders/cloudfoundry" "github.com/DataDog/datadog-agent/pkg/util/common" @@ -51,7 +52,7 @@ func GetFxOptions() fx.Option { } func (c *collector) Start(_ context.Context, store workloadmeta.Component) error { - if !config.IsFeaturePresent(config.CloudFoundry) { + if !env.IsFeaturePresent(env.CloudFoundry) { return errors.NewDisabled(componentName, "Agent is not running on CloudFoundry") } diff --git a/comp/core/workloadmeta/collectors/internal/cloudfoundry/container/cf_container_test.go b/comp/core/workloadmeta/collectors/internal/cloudfoundry/container/cf_container_test.go index 07ee6192e8ee8..6fde95aa449a9 100644 --- a/comp/core/workloadmeta/collectors/internal/cloudfoundry/container/cf_container_test.go +++ b/comp/core/workloadmeta/collectors/internal/cloudfoundry/container/cf_container_test.go @@ -23,8 +23,7 @@ import ( func TestStartError(t *testing.T) { workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) c := collector{ store: workloadmetaStore, @@ -37,8 +36,7 @@ func TestStartError(t *testing.T) { func TestPull(t *testing.T) { workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) fakeNodeName := "fake-hostname" diff --git a/comp/core/workloadmeta/collectors/internal/cloudfoundry/vm/cf_vm.go b/comp/core/workloadmeta/collectors/internal/cloudfoundry/vm/cf_vm.go index b4f9203145958..7f8cb0263a984 100644 --- a/comp/core/workloadmeta/collectors/internal/cloudfoundry/vm/cf_vm.go +++ b/comp/core/workloadmeta/collectors/internal/cloudfoundry/vm/cf_vm.go @@ -16,6 +16,7 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/errors" "github.com/DataDog/datadog-agent/pkg/util/cloudproviders/cloudfoundry" "github.com/DataDog/datadog-agent/pkg/util/clusteragent" @@ -58,7 +59,7 @@ func GetFxOptions() fx.Option { } func (c *collector) Start(_ context.Context, store workloadmeta.Component) error { - if !config.IsFeaturePresent(config.CloudFoundry) { + if !env.IsFeaturePresent(env.CloudFoundry) { return errors.NewDisabled(componentName, "Agent is not running on CloudFoundry") } diff --git a/comp/core/workloadmeta/collectors/internal/cloudfoundry/vm/cf_vm_test.go b/comp/core/workloadmeta/collectors/internal/cloudfoundry/vm/cf_vm_test.go index ec6b3f8afd9f7..b887c131de8aa 100644 --- a/comp/core/workloadmeta/collectors/internal/cloudfoundry/vm/cf_vm_test.go +++ b/comp/core/workloadmeta/collectors/internal/cloudfoundry/vm/cf_vm_test.go @@ -223,8 +223,7 @@ func TestStartError(t *testing.T) { workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) c := collector{ @@ -241,8 +240,7 @@ func TestPullNoContainers(t *testing.T) { fakeDCAClient := FakeDCAClient{} workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) c := collector{ @@ -284,8 +282,7 @@ func TestPullActiveContainer(t *testing.T) { fakeDCAClient := FakeDCAClient{} workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) c := collector{ @@ -324,8 +321,7 @@ func TestPullStoppedContainer(t *testing.T) { fakeDCAClient := FakeDCAClient{} workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) c := collector{ @@ -364,8 +360,7 @@ func TestPullDetectsDeletedContainers(t *testing.T) { fakeDCAClient := FakeDCAClient{} workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) c := collector{ @@ -405,8 +400,7 @@ func TestPullAppNameWithDCA(t *testing.T) { fakeDCAClient := FakeDCAClient{} workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) c := collector{ @@ -441,8 +435,7 @@ func TestPullNoAppNameWithoutDCA(t *testing.T) { workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) c := collector{ @@ -479,8 +472,7 @@ func TestPullAppNameWithGardenPropertiesWithoutDCA(t *testing.T) { // and initialize it out-of-band below. That's OK. workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) c := collector{ diff --git a/comp/core/workloadmeta/collectors/internal/containerd/container_builder.go b/comp/core/workloadmeta/collectors/internal/containerd/container_builder.go index 199e532fc71e1..e9565885baaaa 100644 --- a/comp/core/workloadmeta/collectors/internal/containerd/container_builder.go +++ b/comp/core/workloadmeta/collectors/internal/containerd/container_builder.go @@ -16,8 +16,8 @@ import ( "time" "github.com/containerd/containerd" - "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/namespaces" + "github.com/containerd/errdefs" "github.com/DataDog/datadog-agent/comp/core/workloadmeta/collectors/util" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" diff --git a/comp/core/workloadmeta/collectors/internal/containerd/container_builder_test.go b/comp/core/workloadmeta/collectors/internal/containerd/container_builder_test.go index da0934ef11dd6..485a29608b2f8 100644 --- a/comp/core/workloadmeta/collectors/internal/containerd/container_builder_test.go +++ b/comp/core/workloadmeta/collectors/internal/containerd/container_builder_test.go @@ -245,8 +245,7 @@ func TestBuildWorkloadMetaContainer(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) imageMetadata := &workloadmeta.ContainerImageMetadata{ diff --git a/comp/core/workloadmeta/collectors/internal/containerd/containerd.go b/comp/core/workloadmeta/collectors/internal/containerd/containerd.go index 553f414551041..08a592772291d 100644 --- a/comp/core/workloadmeta/collectors/internal/containerd/containerd.go +++ b/comp/core/workloadmeta/collectors/internal/containerd/containerd.go @@ -21,6 +21,7 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" agentErrors "github.com/DataDog/datadog-agent/pkg/errors" "github.com/DataDog/datadog-agent/pkg/sbom/scanner" "github.com/DataDog/datadog-agent/pkg/status/health" @@ -123,7 +124,7 @@ func GetFxOptions() fx.Option { } func (c *collector) Start(ctx context.Context, store workloadmeta.Component) error { - if !config.IsFeaturePresent(config.Containerd) { + if !env.IsFeaturePresent(env.Containerd) { return agentErrors.NewDisabled(componentName, "Agent is not running on containerd") } @@ -189,7 +190,7 @@ func (c *collector) stream(ctx context.Context) { case ev := <-c.eventsChan: if err := c.handleEvent(ctx, ev); err != nil { - log.Warnf(err.Error()) + log.Warnf("%s", err.Error()) } case err := <-c.errorsChan: @@ -261,7 +262,7 @@ func (c *collector) generateInitialContainerEvents(namespace string) ([]workload ev, err := createSetEvent(container, namespace, c.containerdClient, c.store) if err != nil { - log.Warnf(err.Error()) + log.Warnf("%s", err.Error()) continue } diff --git a/comp/core/workloadmeta/collectors/internal/containerd/event_builder_test.go b/comp/core/workloadmeta/collectors/internal/containerd/event_builder_test.go index 90b35be5e4e1e..9f8dd89cd3bb6 100644 --- a/comp/core/workloadmeta/collectors/internal/containerd/event_builder_test.go +++ b/comp/core/workloadmeta/collectors/internal/containerd/event_builder_test.go @@ -73,8 +73,7 @@ func TestBuildCollectorEvent(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) workloadMetaContainer, err := buildWorkloadMetaContainer(namespace, &container, &client, workloadmetaStore) workloadMetaContainer.Namespace = namespace diff --git a/comp/core/workloadmeta/collectors/internal/containerd/network_linux.go b/comp/core/workloadmeta/collectors/internal/containerd/network_linux.go index 5fdba9efa38b7..f42b8cc219d39 100644 --- a/comp/core/workloadmeta/collectors/internal/containerd/network_linux.go +++ b/comp/core/workloadmeta/collectors/internal/containerd/network_linux.go @@ -13,6 +13,7 @@ import ( "github.com/containerd/containerd" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" cutil "github.com/DataDog/datadog-agent/pkg/util/containerd" "github.com/DataDog/datadog-agent/pkg/util/system" ) @@ -29,7 +30,7 @@ import ( // them. That means that if a container is attached to multiple networks this // might not work as expected. func extractIP(namespace string, container containerd.Container, containerdClient cutil.ContainerdItf) (string, error) { - if !config.IsHostProcAvailable() { + if !env.IsHostProcAvailable() { return "", nil } diff --git a/comp/core/workloadmeta/collectors/internal/docker/docker.go b/comp/core/workloadmeta/collectors/internal/docker/docker.go index f0d2de3527e9a..cf4d5e68fb270 100644 --- a/comp/core/workloadmeta/collectors/internal/docker/docker.go +++ b/comp/core/workloadmeta/collectors/internal/docker/docker.go @@ -28,7 +28,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/workloadmeta/collectors/util" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" errorspkg "github.com/DataDog/datadog-agent/pkg/errors" "github.com/DataDog/datadog-agent/pkg/sbom/scanner" "github.com/DataDog/datadog-agent/pkg/status/health" @@ -85,7 +85,7 @@ func GetFxOptions() fx.Option { } func (c *collector) Start(ctx context.Context, store workloadmeta.Component) error { - if !config.IsFeaturePresent(config.Docker) { + if !env.IsFeaturePresent(env.Docker) { return errorspkg.NewDisabled(componentName, "Agent is not running on Docker") } @@ -149,13 +149,13 @@ func (c *collector) stream(ctx context.Context) { case ev := <-c.containerEventsCh: err := c.handleContainerEvent(ctx, ev) if err != nil { - log.Warnf(err.Error()) + log.Warnf("%s", err.Error()) } case ev := <-c.imageEventsCh: err := c.handleImageEvent(ctx, ev, nil) if err != nil { - log.Warnf(err.Error()) + log.Warnf("%s", err.Error()) } case <-ctx.Done(): @@ -195,7 +195,7 @@ func (c *collector) generateEventsFromContainerList(ctx context.Context, filter Action: events.ActionStart, }) if err != nil { - log.Warnf(err.Error()) + log.Warnf("%s", err.Error()) continue } @@ -220,7 +220,7 @@ func (c *collector) generateEventsFromImageList(ctx context.Context) error { for _, img := range images { imgMetadata, err := c.getImageMetadata(ctx, img.ID, nil) if err != nil { - log.Warnf(err.Error()) + log.Warnf("%s", err.Error()) continue } diff --git a/comp/core/workloadmeta/collectors/internal/ecs/ecs.go b/comp/core/workloadmeta/collectors/internal/ecs/ecs.go index 9f92027c61e3b..462bc2ab42c9e 100644 --- a/comp/core/workloadmeta/collectors/internal/ecs/ecs.go +++ b/comp/core/workloadmeta/collectors/internal/ecs/ecs.go @@ -18,7 +18,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/comp/core/workloadmeta/collectors/util" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - pkgConfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/errors" ecsutil "github.com/DataDog/datadog-agent/pkg/util/ecs" ecsmeta "github.com/DataDog/datadog-agent/pkg/util/ecs/metadata" @@ -94,7 +94,7 @@ func GetFxOptions() fx.Option { } func (c *collector) Start(ctx context.Context, store workloadmeta.Component) error { - if !pkgConfig.IsFeaturePresent(pkgConfig.ECSEC2) { + if !env.IsFeaturePresent(env.ECSEC2) { return errors.NewDisabled(componentName, "Agent is not running on ECS EC2") } diff --git a/comp/core/workloadmeta/collectors/internal/ecsfargate/ecsfargate.go b/comp/core/workloadmeta/collectors/internal/ecsfargate/ecsfargate.go index 5ca36a30d25f7..6f4f0cb8e1cb9 100644 --- a/comp/core/workloadmeta/collectors/internal/ecsfargate/ecsfargate.go +++ b/comp/core/workloadmeta/collectors/internal/ecsfargate/ecsfargate.go @@ -17,7 +17,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/comp/core/workloadmeta/collectors/util" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - pkgConfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/errors" ecsmeta "github.com/DataDog/datadog-agent/pkg/util/ecs/metadata" v2 "github.com/DataDog/datadog-agent/pkg/util/ecs/metadata/v2" @@ -67,7 +67,7 @@ func GetFxOptions() fx.Option { } func (c *collector) Start(_ context.Context, store workloadmeta.Component) error { - if !pkgConfig.IsFeaturePresent(pkgConfig.ECSFargate) { + if !env.IsFeaturePresent(env.ECSFargate) { return errors.NewDisabled(componentName, "Agent is not running on ECS Fargate") } diff --git a/comp/core/workloadmeta/collectors/internal/host/host_test.go b/comp/core/workloadmeta/collectors/internal/host/host_test.go index 917191eb2d88b..a7b49a782cb74 100644 --- a/comp/core/workloadmeta/collectors/internal/host/host_test.go +++ b/comp/core/workloadmeta/collectors/internal/host/host_test.go @@ -44,9 +44,8 @@ func TestHostCollector(t *testing.T) { deps := fxutil.Test[testDeps](t, fx.Options( fx.Replace(config.MockParams{Overrides: overrides}), core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), fx.Supply(context.Background()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) mockClock := clock.NewMock() diff --git a/comp/core/workloadmeta/collectors/internal/kubeapiserver/kubeapiserver.go b/comp/core/workloadmeta/collectors/internal/kubeapiserver/kubeapiserver.go index 7aa6449939bd5..0666db1755b75 100644 --- a/comp/core/workloadmeta/collectors/internal/kubeapiserver/kubeapiserver.go +++ b/comp/core/workloadmeta/collectors/internal/kubeapiserver/kubeapiserver.go @@ -21,6 +21,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/config" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + configutils "github.com/DataDog/datadog-agent/pkg/config/utils" "github.com/DataDog/datadog-agent/pkg/status/health" "github.com/DataDog/datadog-agent/pkg/util/kubernetes/apiserver" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -42,11 +43,19 @@ type dependencies struct { type storeGenerator func(context.Context, workloadmeta.Component, config.Reader, kubernetes.Interface) (*cache.Reflector, *reflectorStore) func shouldHavePodStore(cfg config.Reader) bool { - return cfg.GetBool("cluster_agent.collect_kubernetes_tags") || cfg.GetBool("autoscaling.workload.enabled") + metadataAsTags := configutils.GetMetadataAsTags(cfg) + hasPodLabelsAsTags := len(metadataAsTags.GetPodLabelsAsTags()) > 0 + hasPodAnnotationsAsTags := len(metadataAsTags.GetPodAnnotationsAsTags()) > 0 + + return cfg.GetBool("cluster_agent.collect_kubernetes_tags") || cfg.GetBool("autoscaling.workload.enabled") || hasPodLabelsAsTags || hasPodAnnotationsAsTags } func shouldHaveDeploymentStore(cfg config.Reader) bool { - return cfg.GetBool("language_detection.enabled") && cfg.GetBool("language_detection.reporting.enabled") + metadataAsTags := configutils.GetMetadataAsTags(cfg) + hasDeploymentsLabelsAsTags := len(metadataAsTags.GetResourcesLabelsAsTags()["deployments.apps"]) > 0 + hasDeploymentsAnnotationsAsTags := len(metadataAsTags.GetResourcesAnnotationsAsTags()["deployments.apps"]) > 0 + + return cfg.GetBool("language_detection.enabled") && cfg.GetBool("language_detection.reporting.enabled") || hasDeploymentsLabelsAsTags || hasDeploymentsAnnotationsAsTags } func storeGenerators(cfg config.Reader) []storeGenerator { @@ -82,10 +91,27 @@ func resourcesWithMetadataCollectionEnabled(cfg config.Reader) []string { func resourcesWithRequiredMetadataCollection(cfg config.Reader) []string { res := []string{"nodes"} // nodes are always needed - namespaceLabelsAsTagsEnabled := len(cfg.GetStringMapString("kubernetes_namespace_labels_as_tags")) > 0 - namespaceAnnotationsAsTagsEnabled := len(cfg.GetStringMapString("kubernetes_namespace_annotations_as_tags")) > 0 - if namespaceLabelsAsTagsEnabled || namespaceAnnotationsAsTagsEnabled { - res = append(res, "namespaces") + metadataAsTags := configutils.GetMetadataAsTags(cfg) + + for groupResource, labelsAsTags := range metadataAsTags.GetResourcesLabelsAsTags() { + + if strings.HasPrefix(groupResource, "pods") || strings.HasPrefix(groupResource, "deployments") || len(labelsAsTags) == 0 { + continue + } + requestedResource := groupResourceToGVRString(groupResource) + if requestedResource != "" { + res = append(res, requestedResource) + } + } + + for groupResource, annotationsAsTags := range metadataAsTags.GetResourcesAnnotationsAsTags() { + if strings.HasPrefix(groupResource, "pods") || strings.HasPrefix(groupResource, "deployments") || len(annotationsAsTags) == 0 { + continue + } + requestedResource := groupResourceToGVRString(groupResource) + if requestedResource != "" { + res = append(res, requestedResource) + } } return res @@ -104,12 +130,12 @@ func resourcesWithExplicitMetadataCollectionEnabled(cfg config.Reader) []string var resources []string requestedResources := cfg.GetStringSlice("cluster_agent.kube_metadata_collection.resources") for _, resource := range requestedResources { - if strings.HasSuffix(resource, "pods") && shouldHavePodStore(cfg) { + if strings.HasSuffix(resource, "pods") { log.Debugf("skipping pods from metadata collection because a separate pod store is initialised in workload metadata store.") continue } - if strings.HasSuffix(resource, "deployments") && shouldHaveDeploymentStore(cfg) { + if strings.HasSuffix(resource, "deployments") { log.Debugf("skipping deployments from metadata collection because a separate deployment store is initialised in workload metadata store.") continue } diff --git a/comp/core/workloadmeta/collectors/internal/kubeapiserver/kubeapiserver_test.go b/comp/core/workloadmeta/collectors/internal/kubeapiserver/kubeapiserver_test.go index c6b34fc9f70ea..e29400bf2d3a2 100644 --- a/comp/core/workloadmeta/collectors/internal/kubeapiserver/kubeapiserver_test.go +++ b/comp/core/workloadmeta/collectors/internal/kubeapiserver/kubeapiserver_test.go @@ -135,7 +135,27 @@ func Test_metadataCollectionGVRs_WithFunctionalDiscovery(t *testing.T) { }, }, { - name: "only one resource (deployments), only one version, correct resource requested", + name: "only one resource (statefulsets), only one version, correct resource requested", + apiServerResourceList: []*metav1.APIResourceList{ + { + GroupVersion: "apps/v1", + APIResources: []metav1.APIResource{ + { + Name: "statefulsets", + Kind: "Statefulset", + Namespaced: true, + }, + }, + }, + }, + expectedGVRs: []schema.GroupVersionResource{{Resource: "statefulsets", Group: "apps", Version: "v1"}}, + cfg: map[string]interface{}{ + "cluster_agent.kube_metadata_collection.enabled": true, + "cluster_agent.kube_metadata_collection.resources": "apps/statefulsets", + }, + }, + { + name: "deployments should be skipped from metadata collection", apiServerResourceList: []*metav1.APIResourceList{ { GroupVersion: "apps/v1", @@ -148,30 +168,50 @@ func Test_metadataCollectionGVRs_WithFunctionalDiscovery(t *testing.T) { }, }, }, - expectedGVRs: []schema.GroupVersionResource{{Resource: "deployments", Group: "apps", Version: "v1"}}, + expectedGVRs: []schema.GroupVersionResource{}, cfg: map[string]interface{}{ "cluster_agent.kube_metadata_collection.enabled": true, "cluster_agent.kube_metadata_collection.resources": "apps/deployments", }, }, { - name: "only one resource (deployments), only one version, correct resource requested, but version is empty (with double slash)", + name: "pods should be skipped from metadata collection", apiServerResourceList: []*metav1.APIResourceList{ { GroupVersion: "apps/v1", APIResources: []metav1.APIResource{ { - Name: "deployments", - Kind: "Deployment", + Name: "pods", + Kind: "Pod", Namespaced: true, }, }, }, }, - expectedGVRs: []schema.GroupVersionResource{{Resource: "deployments", Group: "apps", Version: "v1"}}, + expectedGVRs: []schema.GroupVersionResource{}, cfg: map[string]interface{}{ "cluster_agent.kube_metadata_collection.enabled": true, - "cluster_agent.kube_metadata_collection.resources": "apps//deployments", + "cluster_agent.kube_metadata_collection.resources": "/pods", + }, + }, + { + name: "only one resource (statefulsets), only one version, correct resource requested, but version is empty (with double slash)", + apiServerResourceList: []*metav1.APIResourceList{ + { + GroupVersion: "apps/v1", + APIResources: []metav1.APIResource{ + { + Name: "statefulsets", + Kind: "Statefulset", + Namespaced: true, + }, + }, + }, + }, + expectedGVRs: []schema.GroupVersionResource{{Resource: "statefulsets", Group: "apps", Version: "v1"}}, + cfg: map[string]interface{}{ + "cluster_agent.kube_metadata_collection.enabled": true, + "cluster_agent.kube_metadata_collection.resources": "apps//statefulsets", }, }, { @@ -248,7 +288,6 @@ func Test_metadataCollectionGVRs_WithFunctionalDiscovery(t *testing.T) { }, }, expectedGVRs: []schema.GroupVersionResource{ - {Resource: "deployments", Group: "apps", Version: "v1"}, {Resource: "statefulsets", Group: "apps", Version: "v1"}, }, cfg: map[string]interface{}{ @@ -300,7 +339,7 @@ func Test_metadataCollectionGVRs_WithFunctionalDiscovery(t *testing.T) { }, }, }, - expectedGVRs: []schema.GroupVersionResource{{Resource: "deployments", Group: "apps", Version: "v1"}}, + expectedGVRs: []schema.GroupVersionResource{}, cfg: map[string]interface{}{ "cluster_agent.kube_metadata_collection.enabled": true, "cluster_agent.kube_metadata_collection.resources": "apps/deployments", @@ -329,6 +368,26 @@ func Test_metadataCollectionGVRs_WithFunctionalDiscovery(t *testing.T) { }, }, }, + { + GroupVersion: "apps/v1", + APIResources: []metav1.APIResource{ + { + Name: "daemonsets", + Kind: "Daemonset", + Namespaced: true, + }, + }, + }, + { + GroupVersion: "apps/v1beta1", + APIResources: []metav1.APIResource{ + { + Name: "daemonsets", + Kind: "Daemonset", + Namespaced: true, + }, + }, + }, { GroupVersion: "apps/v1", APIResources: []metav1.APIResource{ @@ -351,11 +410,11 @@ func Test_metadataCollectionGVRs_WithFunctionalDiscovery(t *testing.T) { }, }, expectedGVRs: []schema.GroupVersionResource{ - {Resource: "deployments", Group: "apps", Version: "v1"}, + {Resource: "daemonsets", Group: "apps", Version: "v1"}, }, cfg: map[string]interface{}{ "cluster_agent.kube_metadata_collection.enabled": true, - "cluster_agent.kube_metadata_collection.resources": "apps/deployments apps/statefulsetsy", + "cluster_agent.kube_metadata_collection.resources": "apps/daemonsets apps/statefulsetsy", }, }, } @@ -401,10 +460,22 @@ func TestResourcesWithMetadataCollectionEnabled(t *testing.T) { "cluster_agent.kube_metadata_collection.enabled": true, "cluster_agent.kube_metadata_collection.resources": "apps/deployments apps/statefulsets apps//deployments apps/v1/statefulsets apps/v1/daemonsets", }, - expectedResources: []string{"//nodes", "apps//deployments", "apps/v1/daemonsets"}, + expectedResources: []string{"//nodes", "apps/v1/daemonsets"}, + }, + { + name: "with generic resource tagging based on annotations and/or labels configured", + cfg: map[string]interface{}{ + "language_detection.enabled": false, + "language_detection.reporting.enabled": false, + "cluster_agent.kube_metadata_collection.enabled": false, + "cluster_agent.kube_metadata_collection.resources": "", + "kubernetes_resources_labels_as_tags": `{"deployments.apps": {"x-team": "team"}}`, + "kubernetes_resources_annotations_as_tags": `{"namespaces": {"x-team": "team"}}`, + }, + expectedResources: []string{"//nodes", "//namespaces"}, }, { - name: "deployments needed for language detection should be excluded from metadata collection", + name: "deployments should be excluded from metadata collection", cfg: map[string]interface{}{ "language_detection.enabled": true, "language_detection.reporting.enabled": true, @@ -414,7 +485,7 @@ func TestResourcesWithMetadataCollectionEnabled(t *testing.T) { expectedResources: []string{"apps//daemonsets", "//nodes"}, }, { - name: "pods needed for autoscaling should be excluded from metadata collection", + name: "pods should be excluded from metadata collection", cfg: map[string]interface{}{ "autoscaling.workload.enabled": true, "cluster_agent.kube_metadata_collection.enabled": true, @@ -428,7 +499,7 @@ func TestResourcesWithMetadataCollectionEnabled(t *testing.T) { "cluster_agent.kube_metadata_collection.enabled": true, "cluster_agent.kube_metadata_collection.resources": "apps/deployments apps/statefulsets", }, - expectedResources: []string{"//nodes", "apps//deployments", "apps//statefulsets"}, + expectedResources: []string{"//nodes", "apps//statefulsets"}, }, { name: "namespaces needed for namespace labels as tags", @@ -451,12 +522,8 @@ func TestResourcesWithMetadataCollectionEnabled(t *testing.T) { { name: "namespaces needed for namespace labels and annotations as tags", cfg: map[string]interface{}{ - "kubernetes_namespace_labels_as_tags": map[string]string{ - "label1": "tag1", - }, - "kubernetes_namespace_annotations_as_tags": map[string]string{ - "annotation1": "tag2", - }, + "kubernetes_namespace_labels_as_tags": `{"label1": "tag1"}`, + "kubernetes_namespace_annotations_as_tags": `{"annotation1": "tag2"}`, }, expectedResources: []string{"//nodes", "//namespaces"}, }, @@ -465,16 +532,14 @@ func TestResourcesWithMetadataCollectionEnabled(t *testing.T) { cfg: map[string]interface{}{ "cluster_agent.kube_metadata_collection.enabled": true, "cluster_agent.kube_metadata_collection.resources": "namespaces apps/deployments", - "kubernetes_namespace_labels_as_tags": map[string]string{ - "label1": "tag1", - }, + "kubernetes_namespace_labels_as_tags": `{"label1": "tag1"}`, }, - expectedResources: []string{"//nodes", "//namespaces", "apps//deployments"}, // namespaces are not duplicated + expectedResources: []string{"//nodes", "//namespaces"}, // namespaces are not duplicated }, } for _, test := range tests { - t.Run(test.name, func(_ *testing.T) { + t.Run(test.name, func(t *testing.T) { cfg := fxutil.Test[config.Component](t, fx.Options( config.MockModule(), fx.Replace(config.MockParams{Overrides: test.cfg}), diff --git a/comp/core/workloadmeta/collectors/internal/kubeapiserver/reflector_store_test.go b/comp/core/workloadmeta/collectors/internal/kubeapiserver/reflector_store_test.go index 175f7b135e3c0..8902b716e7eed 100644 --- a/comp/core/workloadmeta/collectors/internal/kubeapiserver/reflector_store_test.go +++ b/comp/core/workloadmeta/collectors/internal/kubeapiserver/reflector_store_test.go @@ -259,7 +259,6 @@ func TestReplace(t *testing.T) { func mockedWorkloadmeta(t *testing.T) workloadmetamock.Mock { return fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) } diff --git a/comp/core/workloadmeta/collectors/internal/kubeapiserver/test_helpers.go b/comp/core/workloadmeta/collectors/internal/kubeapiserver/test_helpers.go index a0c288e4dcb18..9e105cddab688 100644 --- a/comp/core/workloadmeta/collectors/internal/kubeapiserver/test_helpers.go +++ b/comp/core/workloadmeta/collectors/internal/kubeapiserver/test_helpers.go @@ -9,7 +9,6 @@ package kubeapiserver import ( "context" - "fmt" "testing" "time" @@ -49,8 +48,7 @@ func testCollectEvent(t *testing.T, createResource func(*fake.Clientset) error, core.MockBundle(), fx.Replace(config.MockParams{Overrides: overrides}), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) ctx := context.TODO() @@ -114,16 +112,13 @@ func testCollectMetadataEvent(t *testing.T, createObjects func() []runtime.Objec wlm := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) ctx := context.TODO() // Create a fake metadata client to mock API calls. - - response, err := metadataclient.Resource(gvr).List(ctx, v1.ListOptions{}) + _, err = metadataclient.Resource(gvr).List(ctx, v1.ListOptions{}) assert.NoError(t, err) - fmt.Println("metadata client listing: ", response.String()) store, _ := newMetadataStore(ctx, wlm, wlm.GetConfig(), metadataclient, gvr) stopStore := make(chan struct{}) diff --git a/comp/core/workloadmeta/collectors/internal/kubeapiserver/utils.go b/comp/core/workloadmeta/collectors/internal/kubeapiserver/utils.go index fc737658332c1..6f2d04314ab36 100644 --- a/comp/core/workloadmeta/collectors/internal/kubeapiserver/utils.go +++ b/comp/core/workloadmeta/collectors/internal/kubeapiserver/utils.go @@ -60,6 +60,28 @@ func filterToRegex(filter string) (*regexp.Regexp, error) { return r, nil } +// groupResourceToGVRString is a helper function that converts a group resource string to +// a group-version-resource string +// a group resource string is in the form `{resource}.{group}` or `{resource}` (example: deployments.apps, pods) +// a group version resource string is in the form `{group}/{version}/{resource}` (example: apps/v1/deployments) +// if the groupResource argument is not in the correct format, an empty string is returned +func groupResourceToGVRString(groupResource string) string { + parts := strings.Split(groupResource, ".") + + if len(parts) > 2 { + // incorrect format + log.Errorf("unexpected group resource format %q. correct format should be `{resource}.{group}` or `{resource}`", groupResource) + } else if len(parts) == 1 { + // format is `{resource}` + return parts[0] + } else { + // format is `{resource}/{group}` + return fmt.Sprintf("%s//%s", parts[1], parts[0]) + } + + return "" +} + // cleanDuplicateVersions detects if different versions are requested for the same resource within the same group // it logs an error for each occurrence, and a clean slice that doesn't contain any such duplication func cleanDuplicateVersions(resources []string) []string { diff --git a/comp/core/workloadmeta/collectors/internal/kubeapiserver/utils_test.go b/comp/core/workloadmeta/collectors/internal/kubeapiserver/utils_test.go index 1c00d0ed31551..c409965fa260c 100644 --- a/comp/core/workloadmeta/collectors/internal/kubeapiserver/utils_test.go +++ b/comp/core/workloadmeta/collectors/internal/kubeapiserver/utils_test.go @@ -11,10 +11,7 @@ import ( "reflect" "testing" - "go.uber.org/fx" - "github.com/DataDog/datadog-agent/comp/core/config" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) func Test_filterMapStringKey(t *testing.T) { @@ -30,9 +27,7 @@ func Test_filterMapStringKey(t *testing.T) { "ad.datadoghq.com/tags": `["bar","foo"]`, } - conf := fxutil.Test[config.Component](t, fx.Options( - config.MockModule(), - )) + conf := config.NewMock(t) defaultExclude := conf.GetStringSlice("cluster_agent.kubernetes_resources_collection.pod_annotations_exclude") extraExclude := append(defaultExclude, "foo") diff --git a/comp/core/workloadmeta/collectors/internal/kubelet/kubelet.go b/comp/core/workloadmeta/collectors/internal/kubelet/kubelet.go index 5b1885c40f965..c346809148780 100644 --- a/comp/core/workloadmeta/collectors/internal/kubelet/kubelet.go +++ b/comp/core/workloadmeta/collectors/internal/kubelet/kubelet.go @@ -18,7 +18,7 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/internal/third_party/golang/expansion" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/errors" "github.com/DataDog/datadog-agent/pkg/util/containers" "github.com/DataDog/datadog-agent/pkg/util/kubernetes" @@ -59,7 +59,7 @@ func GetFxOptions() fx.Option { } func (c *collector) Start(_ context.Context, store workloadmeta.Component) error { - if !config.IsFeaturePresent(config.Kubernetes) { + if !env.IsFeaturePresent(env.Kubernetes) { return errors.NewDisabled(componentName, "Agent is not running on Kubernetes") } diff --git a/comp/core/workloadmeta/collectors/internal/kubemetadata/kubemetadata.go b/comp/core/workloadmeta/collectors/internal/kubemetadata/kubemetadata.go index fd287abed6dc4..8dd66cacd8a79 100644 --- a/comp/core/workloadmeta/collectors/internal/kubemetadata/kubemetadata.go +++ b/comp/core/workloadmeta/collectors/internal/kubemetadata/kubemetadata.go @@ -20,6 +20,8 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" apiv1 "github.com/DataDog/datadog-agent/pkg/clusteragent/api/v1" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" + configutils "github.com/DataDog/datadog-agent/pkg/config/utils" "github.com/DataDog/datadog-agent/pkg/errors" "github.com/DataDog/datadog-agent/pkg/util/clusteragent" "github.com/DataDog/datadog-agent/pkg/util/kubernetes/apiserver" @@ -67,7 +69,7 @@ func GetFxOptions() fx.Option { // Start tries to connect to the kubelet, the DCA and the API Server if the DCA is not available. func (c *collector) Start(_ context.Context, store workloadmeta.Component) error { - if !config.IsFeaturePresent(config.Kubernetes) { + if !env.IsFeaturePresent(env.Kubernetes) { return errors.NewDisabled(componentName, "Agent is not running on Kubernetes") } @@ -114,8 +116,10 @@ func (c *collector) Start(_ context.Context, store workloadmeta.Component) error } c.updateFreq = time.Duration(config.Datadog().GetInt("kubernetes_metadata_tag_update_freq")) * time.Second - c.collectNamespaceLabels = len(config.Datadog().GetStringMapString("kubernetes_namespace_labels_as_tags")) > 0 - c.collectNamespaceAnnotations = len(config.Datadog().GetStringMapString("kubernetes_namespace_annotations_as_tags")) > 0 + + metadataAsTags := configutils.GetMetadataAsTags(config.Datadog()) + c.collectNamespaceLabels = len(metadataAsTags.GetNamespaceLabelsAsTags()) > 0 + c.collectNamespaceAnnotations = len(metadataAsTags.GetNamespaceAnnotationsAsTags()) > 0 return err } diff --git a/comp/core/workloadmeta/collectors/internal/podman/podman.go b/comp/core/workloadmeta/collectors/internal/podman/podman.go index e1b13f2dd1dbe..9c171d5ed168c 100644 --- a/comp/core/workloadmeta/collectors/internal/podman/podman.go +++ b/comp/core/workloadmeta/collectors/internal/podman/podman.go @@ -19,6 +19,7 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" dderrors "github.com/DataDog/datadog-agent/pkg/errors" "github.com/DataDog/datadog-agent/pkg/util/containers" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -62,7 +63,7 @@ func GetFxOptions() fx.Option { // Start the collector for the provided workloadmeta component func (c *collector) Start(_ context.Context, store workloadmeta.Component) error { - if !config.IsFeaturePresent(config.Podman) { + if !env.IsFeaturePresent(env.Podman) { return dderrors.NewDisabled(componentName, "Podman not detected") } diff --git a/comp/core/workloadmeta/collectors/internal/process/process_collector_test.go b/comp/core/workloadmeta/collectors/internal/process/process_collector_test.go index 8ef9940a66811..3f5415f442e49 100644 --- a/comp/core/workloadmeta/collectors/internal/process/process_collector_test.go +++ b/comp/core/workloadmeta/collectors/internal/process/process_collector_test.go @@ -54,10 +54,9 @@ func setUpCollectorTest(t *testing.T, configOverrides map[string]interface{}) co mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), fx.Replace(config.MockParams{Overrides: configOverrides}), - fx.Supply(workloadmeta.Params{ + workloadmetafxmock.MockModule(workloadmeta.Params{ AgentType: workloadmeta.NodeAgent, }), - workloadmetafxmock.MockModule(), )) wlmExtractor := processwlm.NewWorkloadMetaExtractor(mockStore.GetConfig()) diff --git a/comp/core/workloadmeta/collectors/internal/remote/processcollector/process_collector_test.go b/comp/core/workloadmeta/collectors/internal/remote/processcollector/process_collector_test.go index c80bdb2df4f2b..a9e46426cc829 100644 --- a/comp/core/workloadmeta/collectors/internal/remote/processcollector/process_collector_test.go +++ b/comp/core/workloadmeta/collectors/internal/remote/processcollector/process_collector_test.go @@ -249,10 +249,7 @@ func TestCollection(t *testing.T) { mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), fx.Replace(config.MockParams{Overrides: overrides}), - fx.Supply(workloadmeta.Params{ - AgentType: workloadmeta.Remote, - }), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.Params{AgentType: workloadmeta.Remote}), )) time.Sleep(time.Second) diff --git a/comp/core/workloadmeta/collectors/internal/remote/workloadmeta/workloadmeta_test.go b/comp/core/workloadmeta/collectors/internal/remote/workloadmeta/workloadmeta_test.go index 5d8eed89b5c06..f4e4b47395b23 100644 --- a/comp/core/workloadmeta/collectors/internal/remote/workloadmeta/workloadmeta_test.go +++ b/comp/core/workloadmeta/collectors/internal/remote/workloadmeta/workloadmeta_test.go @@ -167,10 +167,7 @@ func TestHandleWorkloadmetaStreamResponse(t *testing.T) { // workloadmeta client store mockClientStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.Params{ - AgentType: workloadmeta.Remote, - }), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.Params{AgentType: workloadmeta.Remote}), )) expectedEvent, err := proto.WorkloadmetaEventFromProtoEvent(protoWorkloadmetaEvent) @@ -205,8 +202,7 @@ func TestCollection(t *testing.T) { // workloadmeta server mockServerStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) server := &serverSecure{workloadmetaServer: server.NewServer(mockServerStore)} @@ -241,16 +237,13 @@ func TestCollection(t *testing.T) { // workloadmeta client store mockClientStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.Params{ - AgentType: workloadmeta.Remote, - }), fx.Provide( fx.Annotate(func() workloadmeta.Collector { return collector }, fx.ResultTags(`group:"workloadmeta"`)), ), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.Params{AgentType: workloadmeta.Remote}), )) time.Sleep(3 * time.Second) diff --git a/comp/core/workloadmeta/fx-mock/fx.go b/comp/core/workloadmeta/fx-mock/fx.go index 57a63215dbdaf..8af26b2a550de 100644 --- a/comp/core/workloadmeta/fx-mock/fx.go +++ b/comp/core/workloadmeta/fx-mock/fx.go @@ -21,12 +21,13 @@ import ( // team: container-platform // MockModule defines the fx options for the mock component. -func MockModule() fxutil.Module { +func MockModule(params wmdef.Params) fxutil.Module { return fxutil.Component( fxutil.ProvideComponentConstructor(wmimpl.NewWorkloadMetaMock), fx.Provide(func(mock wmmock.Mock) wmdef.Component { return mock }), fx.Provide(func(mock wmmock.Mock) optional.Option[wmdef.Component] { return optional.NewOption[wmdef.Component](mock) }), + fx.Supply(params), ) } diff --git a/comp/core/workloadmeta/fx/fx.go b/comp/core/workloadmeta/fx/fx.go index 33bcbeb80cc6e..96f4c659db370 100644 --- a/comp/core/workloadmeta/fx/fx.go +++ b/comp/core/workloadmeta/fx/fx.go @@ -18,7 +18,17 @@ import ( // team: container-platform // Module defines the fx options for this component. -func Module() fxutil.Module { +func Module(params wmdef.Params) fxutil.Module { + return module(fx.Supply(params)) +} + +// ModuleWithProvider defines the fx options for this component using a provider to get the parameter. +// T is the type of a component, typically component.Config. +func ModuleWithProvider[T any](paramsProvider func(T) wmdef.Params) fxutil.Module { + return module(fx.Provide(paramsProvider)) +} + +func module(options ...fx.Option) fxutil.Module { return fxutil.Component( fxutil.ProvideComponentConstructor( workloadmeta.NewWorkloadMeta, @@ -26,5 +36,6 @@ func Module() fxutil.Module { fx.Provide(func(wmeta wmdef.Component) optional.Option[wmdef.Component] { return optional.NewOption(wmeta) }), + fx.Options(options...), ) } diff --git a/comp/dogstatsd/listeners/ratelimit/cgroup_memory_usage_linux.go b/comp/dogstatsd/listeners/ratelimit/cgroup_memory_usage_linux.go index bb3f5fe56dc94..e349988692882 100644 --- a/comp/dogstatsd/listeners/ratelimit/cgroup_memory_usage_linux.go +++ b/comp/dogstatsd/listeners/ratelimit/cgroup_memory_usage_linux.go @@ -11,7 +11,7 @@ package ratelimit import ( "errors" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/cgroups" ) @@ -23,7 +23,7 @@ type cgroupMemoryUsage struct { } func newCgroupMemoryUsage() (*cgroupMemoryUsage, error) { - selfReader, err := cgroups.NewSelfReader("/proc", config.IsContainerized()) + selfReader, err := cgroups.NewSelfReader("/proc", env.IsContainerized()) if err != nil { return nil, err } diff --git a/comp/dogstatsd/mapper/mapper_test.go b/comp/dogstatsd/mapper/mapper_test.go index 0e47268cf35c6..ce07e09ee3dde 100644 --- a/comp/dogstatsd/mapper/mapper_test.go +++ b/comp/dogstatsd/mapper/mapper_test.go @@ -14,11 +14,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.uber.org/fx" configComponent "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/pkg/config" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) func TestMappings(t *testing.T) { @@ -520,12 +518,7 @@ dogstatsd_mapper_profiles: func getMapper(t *testing.T, configString string) (*MetricMapper, error) { var profiles []config.MappingProfile - cfg := fxutil.Test[configComponent.Component](t, fx.Options( - configComponent.MockModule(), - fx.Replace(configComponent.MockParams{ - Params: configComponent.Params{ConfFilePath: configString}, - }), - )) + cfg := configComponent.NewMockFromYAML(t, configString) err := cfg.UnmarshalKey("dogstatsd_mapper_profiles", &profiles) if err != nil { diff --git a/comp/dogstatsd/replay/impl/writer_test.go b/comp/dogstatsd/replay/impl/writer_test.go index 08e6c5e381816..be394e23ba315 100644 --- a/comp/dogstatsd/replay/impl/writer_test.go +++ b/comp/dogstatsd/replay/impl/writer_test.go @@ -36,7 +36,7 @@ func writerTest(t *testing.T, z bool) { file, path, err := OpenFile(fs, "foo/bar", "") require.NoError(t, err) - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) writer := NewTrafficCaptureWriter(1) diff --git a/comp/dogstatsd/server/convert_bench_test.go b/comp/dogstatsd/server/convert_bench_test.go index c756db1025073..eaf39be242898 100644 --- a/comp/dogstatsd/server/convert_bench_test.go +++ b/comp/dogstatsd/server/convert_bench_test.go @@ -83,5 +83,5 @@ type ServerDeps struct { } func newServerDeps(t testing.TB, options ...fx.Option) ServerDeps { - return fxutil.Test[ServerDeps](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams()), fx.Options(options...)) + return fxutil.Test[ServerDeps](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams()), fx.Options(options...)) } diff --git a/comp/dogstatsd/server/server.go b/comp/dogstatsd/server/server.go index b1f97ef2f34db..c187855c648db 100644 --- a/comp/dogstatsd/server/server.go +++ b/comp/dogstatsd/server/server.go @@ -393,7 +393,7 @@ func (s *server) start(context.Context) error { if s.config.GetString("dogstatsd_port") == listeners.RandomPortName || s.config.GetInt("dogstatsd_port") > 0 { udpListener, err := listeners.NewUDPListener(packetsChannel, sharedPacketPoolManager, s.config, s.tCapture, s.listernersTelemetry, s.packetsTelemetry) if err != nil { - s.log.Errorf(err.Error()) + s.log.Errorf("%s", err.Error()) } else { tmpListeners = append(tmpListeners, udpListener) s.udpLocalAddr = udpListener.LocalAddr() diff --git a/comp/dogstatsd/server/server_test.go b/comp/dogstatsd/server/server_test.go index 824fd83546478..da10d18be6b0f 100644 --- a/comp/dogstatsd/server/server_test.go +++ b/comp/dogstatsd/server/server_test.go @@ -10,7 +10,6 @@ package server import ( "context" "fmt" - "github.com/DataDog/datadog-agent/pkg/util/testutil/flake" "net" "runtime" "sort" @@ -18,6 +17,8 @@ import ( "testing" "time" + "github.com/DataDog/datadog-agent/pkg/util/testutil/flake" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/fx" @@ -26,8 +27,11 @@ import ( "github.com/DataDog/datadog-agent/comp/aggregator/demultiplexer/demultiplexerimpl" "github.com/DataDog/datadog-agent/comp/core" configComponent "github.com/DataDog/datadog-agent/comp/core/config" + "github.com/DataDog/datadog-agent/comp/core/hostname/hostnameimpl" log "github.com/DataDog/datadog-agent/comp/core/log/def" + logmock "github.com/DataDog/datadog-agent/comp/core/log/mock" "github.com/DataDog/datadog-agent/comp/core/telemetry" + "github.com/DataDog/datadog-agent/comp/core/telemetry/telemetryimpl" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" workloadmetafxmock "github.com/DataDog/datadog-agent/comp/core/workloadmeta/fx-mock" "github.com/DataDog/datadog-agent/comp/dogstatsd/listeners" @@ -39,6 +43,7 @@ import ( "github.com/DataDog/datadog-agent/comp/dogstatsd/serverDebug/serverdebugimpl" "github.com/DataDog/datadog-agent/comp/serializer/compression/compressionimpl" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/metrics" "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/DataDog/datadog-agent/pkg/util/optional" @@ -77,8 +82,7 @@ func fulfillDeps(t testing.TB) serverDeps { return fulfillDepsWithConfigOverride(t, map[string]interface{}{}) } -func fulfillDepsWithConfigOverrideAndFeatures(t testing.TB, overrides map[string]interface{}, features []config.Feature) serverDeps { - +func fulfillDepsWithConfigOverride(t testing.TB, overrides map[string]interface{}) serverDeps { // TODO: https://datadoghq.atlassian.net/browse/AMLII-1948 if runtime.GOOS == "darwin" { flake.Mark(t) @@ -88,37 +92,30 @@ func fulfillDepsWithConfigOverrideAndFeatures(t testing.TB, overrides map[string serverdebugimpl.MockModule(), fx.Replace(configComponent.MockParams{ Overrides: overrides, - Features: features, }), fx.Supply(Params{Serverless: false}), replaymock.MockModule(), compressionimpl.MockModule(), pidmapimpl.Module(), demultiplexerimpl.FakeSamplerMockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), Module(), )) } -func fulfillDepsWithConfigOverride(t testing.TB, overrides map[string]interface{}) serverDeps { - return fulfillDepsWithConfigOverrideAndFeatures(t, overrides, nil) -} - func fulfillDepsWithConfigYaml(t testing.TB, yaml string) serverDeps { return fxutil.Test[serverDeps](t, fx.Options( - core.MockBundle(), + fx.Provide(func(t testing.TB) log.Component { return logmock.New(t) }), + fx.Provide(func(t testing.TB) configComponent.Component { return configComponent.NewMockFromYAML(t, yaml) }), + telemetryimpl.MockModule(), + hostnameimpl.MockModule(), serverdebugimpl.MockModule(), - fx.Replace(configComponent.MockParams{ - Params: configComponent.Params{ConfFilePath: yaml}, - }), fx.Supply(Params{Serverless: false}), replaymock.MockModule(), compressionimpl.MockModule(), pidmapimpl.Module(), demultiplexerimpl.FakeSamplerMockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), Module(), )) } @@ -148,8 +145,7 @@ func TestStopServer(t *testing.T) { compressionimpl.MockModule(), pidmapimpl.Module(), demultiplexerimpl.FakeSamplerMockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) s := newServerCompat(deps.Config, deps.Log, deps.Replay, deps.Debug, false, deps.Demultiplexer, deps.WMeta, deps.PidMap, deps.Telemetry) @@ -196,8 +192,7 @@ func TestNoRaceOriginTagMaps(t *testing.T) { compressionimpl.MockModule(), pidmapimpl.Module(), demultiplexerimpl.FakeSamplerMockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) s := newServerCompat(deps.Config, deps.Log, deps.Replay, deps.Debug, false, deps.Demultiplexer, deps.WMeta, deps.PidMap, deps.Telemetry) @@ -684,7 +679,8 @@ func TestExtraTags(t *testing.T) { cfg["dogstatsd_port"] = listeners.RandomPortName cfg["dogstatsd_tags"] = []string{"sometag3:somevalue3"} - deps := fulfillDepsWithConfigOverrideAndFeatures(t, cfg, []config.Feature{config.EKSFargate}) + env.SetFeatures(t, env.EKSFargate) + deps := fulfillDepsWithConfigOverride(t, cfg) demux := deps.Demultiplexer requireStart(t, deps.Server) @@ -713,7 +709,8 @@ func TestStaticTags(t *testing.T) { cfg["dogstatsd_tags"] = []string{"sometag3:somevalue3"} cfg["tags"] = []string{"from:dd_tags"} - deps := fulfillDepsWithConfigOverrideAndFeatures(t, cfg, []config.Feature{config.EKSFargate}) + env.SetFeatures(t, env.EKSFargate) + deps := fulfillDepsWithConfigOverride(t, cfg) demux := deps.Demultiplexer requireStart(t, deps.Server) @@ -776,8 +773,7 @@ func TestParseMetricMessageTelemetry(t *testing.T) { compressionimpl.MockModule(), pidmapimpl.Module(), demultiplexerimpl.FakeSamplerMockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) s := newServerCompat(deps.Config, deps.Log, deps.Replay, deps.Debug, false, deps.Demultiplexer, deps.WMeta, deps.PidMap, deps.Telemetry) @@ -941,8 +937,7 @@ func TestParseEventMessageTelemetry(t *testing.T) { compressionimpl.MockModule(), pidmapimpl.Module(), demultiplexerimpl.FakeSamplerMockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) s := newServerCompat(deps.Config, deps.Log, deps.Replay, deps.Debug, false, deps.Demultiplexer, deps.WMeta, deps.PidMap, deps.Telemetry) @@ -992,8 +987,7 @@ func TestParseServiceCheckMessageTelemetry(t *testing.T) { compressionimpl.MockModule(), pidmapimpl.Module(), demultiplexerimpl.FakeSamplerMockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) s := newServerCompat(deps.Config, deps.Log, deps.Replay, deps.Debug, false, deps.Demultiplexer, deps.WMeta, deps.PidMap, deps.Telemetry) diff --git a/comp/forwarder/bundle.go b/comp/forwarder/bundle.go index c8d73f810782d..412d5e6860269 100644 --- a/comp/forwarder/bundle.go +++ b/comp/forwarder/bundle.go @@ -14,7 +14,13 @@ import ( // team: agent-processing-and-routing // Bundle defines the fx options for this bundle. -func Bundle() fxutil.BundleOptions { +func Bundle(params defaultforwarder.Params) fxutil.BundleOptions { return fxutil.Bundle( - defaultforwarder.Module()) + defaultforwarder.Module(params)) +} + +// BundleWithProvider defines the fx options for this bundle with a provider. +func BundleWithProvider[T1 any, T2 any](provider func(T1, T2) defaultforwarder.Params) fxutil.BundleOptions { + return fxutil.Bundle( + defaultforwarder.ModuleWithProvider(provider)) } diff --git a/comp/forwarder/bundle_test.go b/comp/forwarder/bundle_test.go index e75eb54289bce..fd31959b71b58 100644 --- a/comp/forwarder/bundle_test.go +++ b/comp/forwarder/bundle_test.go @@ -11,12 +11,10 @@ import ( "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder" "github.com/DataDog/datadog-agent/pkg/util/fxutil" - "go.uber.org/fx" ) func TestBundleDependencies(t *testing.T) { - fxutil.TestBundle(t, Bundle(), + fxutil.TestBundle(t, Bundle(defaultforwarder.Params{}), core.MockBundle(), - fx.Supply(defaultforwarder.Params{}), ) } diff --git a/comp/forwarder/defaultforwarder/component.go b/comp/forwarder/defaultforwarder/component.go index 8cbb3c1a65465..81987ba6f9a6b 100644 --- a/comp/forwarder/defaultforwarder/component.go +++ b/comp/forwarder/defaultforwarder/component.go @@ -22,9 +22,19 @@ type Component interface { } // Module defines the fx options for this component. -func Module() fxutil.Module { +func Module(params Params) fxutil.Module { return fxutil.Component( - fx.Provide(newForwarder)) + fx.Provide(newForwarder), + fx.Supply(params), + ) +} + +// ModuleWithProvider defines the fx options for this component. +func ModuleWithProvider[T1 any, T2 any](provider func(T1, T2) Params) fxutil.Module { + return fxutil.Component( + fx.Provide(newForwarder), + fx.Provide(provider), + ) } // Mock implements mock-specific methods. diff --git a/comp/forwarder/defaultforwarder/default_forwarder_test.go b/comp/forwarder/defaultforwarder/default_forwarder_test.go index 1f95cd572921f..7e8122997f314 100644 --- a/comp/forwarder/defaultforwarder/default_forwarder_test.go +++ b/comp/forwarder/defaultforwarder/default_forwarder_test.go @@ -12,10 +12,8 @@ import ( "github.com/DataDog/datadog-agent/comp/core/config" logmock "github.com/DataDog/datadog-agent/comp/core/log/mock" pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.uber.org/fx" ) // domainAPIKeyMap used by tests to get API keys from each domain resolver @@ -28,9 +26,7 @@ func (f *DefaultForwarder) domainAPIKeyMap() map[string][]string { } func TestDefaultForwarderUpdateAPIKey(t *testing.T) { - mockConfig := fxutil.Test[config.Component](t, fx.Options( - config.MockModule(), - )) + mockConfig := config.NewMock(t) mockConfig.Set("api_key", "api_key1", pkgconfigmodel.SourceAgentRuntime) log := logmock.New(t) diff --git a/comp/forwarder/defaultforwarder/forwarder_health_test.go b/comp/forwarder/defaultforwarder/forwarder_health_test.go index 4883af9f5afe9..81800f815142c 100644 --- a/comp/forwarder/defaultforwarder/forwarder_health_test.go +++ b/comp/forwarder/defaultforwarder/forwarder_health_test.go @@ -20,7 +20,6 @@ import ( "github.com/DataDog/datadog-agent/comp/core/config" logmock "github.com/DataDog/datadog-agent/comp/core/log/mock" "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder/resolver" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) func TestCheckValidAPIKey(t *testing.T) { @@ -38,7 +37,7 @@ func TestCheckValidAPIKey(t *testing.T) { ts2.URL: {"key3"}, } log := logmock.New(t) - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) fh := forwarderHealth{log: log, config: cfg, domainResolvers: resolver.NewSingleDomainResolvers(keysPerDomains)} fh.init() assert.True(t, fh.checkValidAPIKey()) @@ -119,7 +118,7 @@ func TestCheckValidAPIKeyErrors(t *testing.T) { ts3.URL: {"key4"}, } log := logmock.New(t) - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) fh := forwarderHealth{log: log, config: cfg} fh.init() fh.keysPerAPIEndpoint = keysPerAPIEndpoint @@ -166,7 +165,7 @@ func TestUpdateAPIKey(t *testing.T) { } log := logmock.New(t) - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) fh := forwarderHealth{log: log, config: cfg, domainResolvers: resolver.NewSingleDomainResolvers(keysPerDomains)} fh.init() diff --git a/comp/forwarder/defaultforwarder/go.mod b/comp/forwarder/defaultforwarder/go.mod index 19d29b4fb7b43..f5639feb1e15a 100644 --- a/comp/forwarder/defaultforwarder/go.mod +++ b/comp/forwarder/defaultforwarder/go.mod @@ -17,6 +17,7 @@ replace ( github.com/DataDog/datadog-agent/comp/serializer/compression => ../../../comp/serializer/compression/ github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../pkg/config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../../pkg/config/utils @@ -69,8 +70,8 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/stretchr/testify v1.9.0 go.uber.org/atomic v1.11.0 - go.uber.org/fx v1.18.2 - golang.org/x/text v0.16.0 + go.uber.org/fx v1.22.2 + golang.org/x/text v0.17.0 ) require ( @@ -81,6 +82,7 @@ require ( github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel // indirect github.com/DataDog/datadog-agent/pkg/util/executable v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/hostname/validate v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/log v0.56.0-rc.3 // indirect @@ -138,15 +140,15 @@ require ( 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.uber.org/dig v1.17.1 // indirect + go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/comp/forwarder/defaultforwarder/go.sum b/comp/forwarder/defaultforwarder/go.sum index 2cc955cc1776b..1a380bd019cc6 100644 --- a/comp/forwarder/defaultforwarder/go.sum +++ b/comp/forwarder/defaultforwarder/go.sum @@ -11,8 +11,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -267,10 +265,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -286,8 +284,8 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -307,8 +305,8 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/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.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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= @@ -334,11 +332,11 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -351,8 +349,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/comp/forwarder/defaultforwarder/status_test.go b/comp/forwarder/defaultforwarder/status_test.go index 7bb75f2461487..6a229babb851c 100644 --- a/comp/forwarder/defaultforwarder/status_test.go +++ b/comp/forwarder/defaultforwarder/status_test.go @@ -18,9 +18,7 @@ import ( ) func TestJSON(t *testing.T) { - config := fxutil.Test[config.Component](t, fx.Options( - config.MockModule(), - )) + config := config.NewMock(t) provider := statusProvider{ config: config, @@ -63,9 +61,7 @@ func TestJSONWith_forwarder_storage_max_size_in_bytes(t *testing.T) { } func TestText(t *testing.T) { - config := fxutil.Test[config.Component](t, fx.Options( - config.MockModule(), - )) + config := config.NewMock(t) provider := statusProvider{ config: config, @@ -78,9 +74,7 @@ func TestText(t *testing.T) { } func TestHTML(t *testing.T) { - config := fxutil.Test[config.Component](t, fx.Options( - config.MockModule(), - )) + config := config.NewMock(t) provider := statusProvider{ config: config, diff --git a/comp/forwarder/eventplatform/eventplatformimpl/epforwarder.go b/comp/forwarder/eventplatform/eventplatformimpl/epforwarder.go index 8313dcf57c71a..b4432b81ffc7f 100644 --- a/comp/forwarder/eventplatform/eventplatformimpl/epforwarder.go +++ b/comp/forwarder/eventplatform/eventplatformimpl/epforwarder.go @@ -36,8 +36,8 @@ import ( //go:generate mockgen -source=$GOFILE -package=$GOPACKAGE -destination=epforwarder_mockgen.go // Module defines the fx options for this component. -func Module() fxutil.Module { - return fxutil.Component(fx.Provide(newEventPlatformForwarder)) +func Module(params Params) fxutil.Module { + return fxutil.Component(fx.Provide(newEventPlatformForwarder), fx.Supply(params)) } const ( diff --git a/comp/forwarder/orchestrator/orchestratorinterface/go.mod b/comp/forwarder/orchestrator/orchestratorinterface/go.mod index 067690c13cda4..f8417fb044dc5 100644 --- a/comp/forwarder/orchestrator/orchestratorinterface/go.mod +++ b/comp/forwarder/orchestrator/orchestratorinterface/go.mod @@ -18,6 +18,7 @@ replace ( github.com/DataDog/datadog-agent/pkg/aggregator/ckey => ../../../../pkg/aggregator/ckey github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../../pkg/config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../../../pkg/config/utils @@ -71,6 +72,7 @@ require ( github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel // indirect github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/setup v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/utils v0.56.0-rc.3 // indirect @@ -144,17 +146,17 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/comp/forwarder/orchestrator/orchestratorinterface/go.sum b/comp/forwarder/orchestrator/orchestratorinterface/go.sum index ee2708062f45d..01bf30ced87c1 100644 --- a/comp/forwarder/orchestrator/orchestratorinterface/go.sum +++ b/comp/forwarder/orchestrator/orchestratorinterface/go.sum @@ -13,8 +13,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -263,10 +261,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -282,8 +280,8 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -303,8 +301,8 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/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.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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= @@ -330,11 +328,11 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -347,8 +345,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/comp/languagedetection/client/clientimpl/client_test.go b/comp/languagedetection/client/clientimpl/client_test.go index 19e5a3f24c2d5..bc69601771407 100644 --- a/comp/languagedetection/client/clientimpl/client_test.go +++ b/comp/languagedetection/client/clientimpl/client_test.go @@ -58,8 +58,7 @@ func newTestClient(t *testing.T) (*client, chan *pbgo.ParentLanguageAnnotationRe }}), telemetryimpl.MockModule(), fx.Provide(func() log.Component { return logmock.New(t) }), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) optComponent := newClient(deps).(optional.Option[clientComp.Component]) @@ -105,8 +104,7 @@ func TestClientEnabled(t *testing.T) { secretsimpl.MockModule(), telemetryimpl.MockModule(), fx.Provide(func() log.Component { return logmock.New(t) }), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) optionalCl := newClient(deps).(optional.Option[clientComp.Component]) diff --git a/comp/logs/agent/agentimpl/agent.go b/comp/logs/agent/agentimpl/agent.go index 582d698e774ef..396dd20a51785 100644 --- a/comp/logs/agent/agentimpl/agent.go +++ b/comp/logs/agent/agentimpl/agent.go @@ -10,6 +10,7 @@ import ( "context" "errors" "fmt" + "sync" "time" "github.com/hashicorp/go-multierror" @@ -25,7 +26,8 @@ import ( "github.com/DataDog/datadog-agent/comp/logs/agent" "github.com/DataDog/datadog-agent/comp/logs/agent/config" flareController "github.com/DataDog/datadog-agent/comp/logs/agent/flare" - "github.com/DataDog/datadog-agent/comp/logs/integrations/def" + integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/def" + integrationsimpl "github.com/DataDog/datadog-agent/comp/logs/integrations/impl" "github.com/DataDog/datadog-agent/comp/metadata/inventoryagent" rctypes "github.com/DataDog/datadog-agent/comp/remote-config/rcclient/types" pkgConfig "github.com/DataDog/datadog-agent/pkg/config" @@ -78,7 +80,6 @@ type dependencies struct { Hostname hostname.Component WMeta optional.Option[workloadmeta.Component] SchedulerProviders []schedulers.Scheduler `group:"log-agent-scheduler"` - IntegrationsLogs integrations.Component } type provides struct { @@ -88,6 +89,7 @@ type provides struct { FlareProvider flaretypes.Provider StatusProvider statusComponent.InformationProvider RCListener rctypes.ListenerProvider + LogsReciever optional.Option[integrations.Component] } // logAgent represents the data pipeline that collects, decodes, @@ -115,8 +117,11 @@ type logAgent struct { schedulerProviders []schedulers.Scheduler integrationsLogs integrations.Component + // make sure this is done only once, when we're ready + prepareSchedulers sync.Once + // started is true if the logs agent is running - started *atomic.Bool + started *atomic.Uint32 } func newLogsAgent(deps dependencies) provides { @@ -125,12 +130,14 @@ func newLogsAgent(deps dependencies) provides { deps.Log.Warn(`"log_enabled" is deprecated, use "logs_enabled" instead`) } + integrationsLogs := integrationsimpl.NewLogsIntegration() + logsAgent := &logAgent{ log: deps.Log, config: deps.Config, inventoryAgent: deps.InventoryAgent, hostname: deps.Hostname, - started: atomic.NewBool(false), + started: atomic.NewUint32(status.StatusNotStarted), sources: sources.NewLogSources(), services: service.NewServices(), @@ -138,7 +145,7 @@ func newLogsAgent(deps dependencies) provides { flarecontroller: flareController.NewFlareController(), wmeta: deps.WMeta, schedulerProviders: deps.SchedulerProviders, - integrationsLogs: deps.IntegrationsLogs, + integrationsLogs: integrationsLogs, } deps.Lc.Append(fx.Hook{ OnStart: logsAgent.start, @@ -158,6 +165,7 @@ func newLogsAgent(deps dependencies) provides { StatusProvider: statusComponent.NewInformationProvider(NewStatusProvider()), FlareProvider: flaretypes.NewProvider(logsAgent.flarecontroller.FillFlare), RCListener: rcListener, + LogsReciever: optional.NewOption[integrations.Component](integrationsLogs), } } @@ -165,6 +173,7 @@ func newLogsAgent(deps dependencies) provides { return provides{ Comp: optional.NewNoneOption[agent.Component](), StatusProvider: statusComponent.NewInformationProvider(NewStatusProvider()), + LogsReciever: optional.NewNoneOption[integrations.Component](), } } @@ -190,12 +199,6 @@ func (a *logAgent) start(context.Context) error { } a.startPipeline() - a.log.Info("logs-agent started") - - for _, scheduler := range a.schedulerProviders { - a.AddScheduler(scheduler) - } - return nil } @@ -225,6 +228,10 @@ func (a *logAgent) setupAgent() error { status.AddGlobalWarning(invalidProcessingRules, multiLineWarning) } + if err := sds.ValidateConfigField(a.config); err != nil { + a.log.Error(fmt.Errorf("error while reading configuration, will block until the Agents receive an SDS configuration: %v", err)) + } + a.SetupPipeline(processingRules, a.wmeta, a.integrationsLogs) return nil } @@ -232,7 +239,6 @@ func (a *logAgent) setupAgent() error { // Start starts all the elements of the data pipeline // in the right order to prevent data loss func (a *logAgent) startPipeline() { - a.started.Store(true) // setup the status status.Init(a.started, a.endpoints, a.sources, a.tracker, metrics.LogsExpvars) @@ -243,9 +249,28 @@ func (a *logAgent) startPipeline() { a.pipelineProvider, a.diagnosticMessageReceiver, a.launchers, - a.schedulers, ) starter.Start() + + if !sds.ShouldBlockCollectionUntilSDSConfiguration(a.config) { + a.startSchedulers() + } else { + a.log.Info("logs-agent ready, schedulers not started: waiting for an SDS configuration to start the logs collection") + a.started.Store(status.StatusCollectionNotStarted) + } +} + +func (a *logAgent) startSchedulers() { + a.prepareSchedulers.Do(func() { + a.schedulers.Start() + + for _, scheduler := range a.schedulerProviders { + a.AddScheduler(scheduler) + } + + a.log.Info("logs-agent started") + a.started.Store(status.StatusRunning) + }) } func (a *logAgent) stop(context.Context) error { @@ -318,45 +343,40 @@ func (a *logAgent) GetPipelineProvider() pipeline.Provider { } func (a *logAgent) onUpdateSDSRules(updates map[string]state.RawConfig, applyStateCallback func(string, state.ApplyStatus)) { //nolint:revive - var err error - for _, config := range updates { - if rerr := a.pipelineProvider.ReconfigureSDSStandardRules(config.Config); rerr != nil { - err = multierror.Append(err, rerr) - } - } - - if err != nil { - a.log.Errorf("Can't update SDS standard rules: %v", err) - } - - // Apply the new status to all configs - for cfgPath := range updates { - if err == nil { - applyStateCallback(cfgPath, state.ApplyStatus{State: state.ApplyStateAcknowledged}) - } else { - applyStateCallback(cfgPath, state.ApplyStatus{ - State: state.ApplyStateError, - Error: err.Error(), - }) - } - } - + a.onUpdateSDS(sds.StandardRules, updates, applyStateCallback) } func (a *logAgent) onUpdateSDSAgentConfig(updates map[string]state.RawConfig, applyStateCallback func(string, state.ApplyStatus)) { //nolint:revive + a.onUpdateSDS(sds.AgentConfig, updates, applyStateCallback) +} + +func (a *logAgent) onUpdateSDS(reconfigType sds.ReconfigureOrderType, updates map[string]state.RawConfig, applyStateCallback func(string, state.ApplyStatus)) { //nolint:revive var err error + allScannersActiveWithAllUpdatesApplied := true // We received a hit that new updates arrived, but if the list of updates // is empty, it means we don't have any updates applying to this agent anymore - // Send a reconfiguration with an empty payload, indicating that - // the scanners have to be dropped. + // In this case, send the signal to stop the SDS processing. if len(updates) == 0 { - err = a.pipelineProvider.ReconfigureSDSAgentConfig([]byte("{}")) + err = a.pipelineProvider.StopSDSProcessing() } else { for _, config := range updates { - if rerr := a.pipelineProvider.ReconfigureSDSAgentConfig(config.Config); rerr != nil { + var allScannersActive bool + var rerr error + + if reconfigType == sds.AgentConfig { + allScannersActive, rerr = a.pipelineProvider.ReconfigureSDSAgentConfig(config.Config) + } else if reconfigType == sds.StandardRules { + allScannersActive, rerr = a.pipelineProvider.ReconfigureSDSStandardRules(config.Config) + } + + if rerr != nil { err = multierror.Append(err, rerr) } + + if !allScannersActive { + allScannersActiveWithAllUpdatesApplied = false + } } } @@ -364,6 +384,10 @@ func (a *logAgent) onUpdateSDSAgentConfig(updates map[string]state.RawConfig, ap a.log.Errorf("Can't update SDS configurations: %v", err) } + if allScannersActiveWithAllUpdatesApplied && sds.ShouldBlockCollectionUntilSDSConfiguration(a.config) { + a.startSchedulers() + } + // Apply the new status to all configs for cfgPath := range updates { if err == nil { diff --git a/comp/logs/agent/agentimpl/agent_core_init_test.go b/comp/logs/agent/agentimpl/agent_core_init_test.go index bfb080f7c450f..547b8ae5dd3fd 100644 --- a/comp/logs/agent/agentimpl/agent_core_init_test.go +++ b/comp/logs/agent/agentimpl/agent_core_init_test.go @@ -11,15 +11,11 @@ import ( "testing" "github.com/DataDog/datadog-agent/comp/core/config" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/stretchr/testify/assert" - "go.uber.org/fx" ) func TestBuildEndpoints(t *testing.T) { - config := fxutil.Test[config.Component](t, fx.Options( - config.MockModule(), - )) + config := config.NewMock(t) endpoints, err := buildEndpoints(config) assert.Nil(t, err) diff --git a/comp/logs/agent/agentimpl/agent_serverless_init.go b/comp/logs/agent/agentimpl/agent_serverless_init.go index d2f61f730da34..d5276a6db9567 100644 --- a/comp/logs/agent/agentimpl/agent_serverless_init.go +++ b/comp/logs/agent/agentimpl/agent_serverless_init.go @@ -12,8 +12,9 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/comp/logs/agent/config" - "github.com/DataDog/datadog-agent/comp/logs/integrations/def" + integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/def" pkgConfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/logs/auditor" "github.com/DataDog/datadog-agent/pkg/logs/client" "github.com/DataDog/datadog-agent/pkg/logs/diagnostic" @@ -69,5 +70,13 @@ func (a *logAgent) SetupPipeline( // buildEndpoints builds endpoints for the logs agent func buildEndpoints(coreConfig pkgConfig.Reader) (*config.Endpoints, error) { - return config.BuildServerlessEndpoints(coreConfig, intakeTrackType, config.DefaultIntakeProtocol) + config, err := config.BuildServerlessEndpoints(coreConfig, intakeTrackType, config.DefaultIntakeProtocol) + if err != nil { + return nil, err + } + if env.IsServerless() { + // in AWS Lambda, we never want the batch strategy to flush with a tick + config.BatchWait = 365 * 24 * time.Hour + } + return config, nil } diff --git a/comp/logs/agent/agentimpl/agent_serverless_init_test.go b/comp/logs/agent/agentimpl/agent_serverless_init_test.go index c122e6f418903..edd7b90ffe231 100644 --- a/comp/logs/agent/agentimpl/agent_serverless_init_test.go +++ b/comp/logs/agent/agentimpl/agent_serverless_init_test.go @@ -9,21 +9,19 @@ package agentimpl import ( "testing" + "time" "github.com/stretchr/testify/assert" - "go.uber.org/fx" "github.com/DataDog/datadog-agent/comp/core/config" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) func TestBuildServerlessEndpoints(t *testing.T) { - config := fxutil.Test[config.Component](t, fx.Options( - config.MockModule(), - )) + config := config.NewMock(t) endpoints, err := buildEndpoints() assert.Nil(t, err) assert.Equal(t, "http-intake.logs.datadoghq.com", endpoints.Main.Host) assert.Equal(t, "lambda-extension", string(endpoints.Main.Origin)) + assert.True(t, endpoints.Main.BatchWait > config.BatchWait*time.Second) } diff --git a/comp/logs/agent/agentimpl/agent_test.go b/comp/logs/agent/agentimpl/agent_test.go index b92a59a794502..a8f7e0b327ef9 100644 --- a/comp/logs/agent/agentimpl/agent_test.go +++ b/comp/logs/agent/agentimpl/agent_test.go @@ -29,13 +29,13 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" workloadmetafxmock "github.com/DataDog/datadog-agent/comp/core/workloadmeta/fx-mock" "github.com/DataDog/datadog-agent/comp/logs/agent/config" - integrationsLogs "github.com/DataDog/datadog-agent/comp/logs/integrations/def" - integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/fx" + integrationsimpl "github.com/DataDog/datadog-agent/comp/logs/integrations/impl" "github.com/DataDog/datadog-agent/comp/metadata/inventoryagent" flareController "github.com/DataDog/datadog-agent/comp/logs/agent/flare" "github.com/DataDog/datadog-agent/comp/metadata/inventoryagent/inventoryagentimpl" coreConfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/logs/client/http" "github.com/DataDog/datadog-agent/pkg/logs/client/mock" "github.com/DataDog/datadog-agent/pkg/logs/client/tcp" @@ -61,10 +61,9 @@ type AgentTestSuite struct { type testDeps struct { fx.In - Config configComponent.Component - Log log.Component - InventoryAgent inventoryagent.Component - IntegrationsLogs integrationsLogs.Component + Config configComponent.Component + Log log.Component + InventoryAgent inventoryagent.Component } func (suite *AgentTestSuite) SetupTest() { @@ -118,15 +117,14 @@ func createAgent(suite *AgentTestSuite, endpoints *config.Endpoints) (*logAgent, hostnameimpl.MockModule(), fx.Replace(configComponent.MockParams{Overrides: suite.configOverrides}), inventoryagentimpl.MockModule(), - integrations.MockModule(), )) agent := &logAgent{ log: deps.Log, config: deps.Config, inventoryAgent: deps.InventoryAgent, - started: atomic.NewBool(false), - integrationsLogs: deps.IntegrationsLogs, + started: atomic.NewUint32(0), + integrationsLogs: integrationsimpl.NewLogsIntegration(), sources: sources, services: services, @@ -140,7 +138,7 @@ func createAgent(suite *AgentTestSuite, endpoints *config.Endpoints) (*logAgent, } func (suite *AgentTestSuite) testAgent(endpoints *config.Endpoints) { - coreConfig.SetFeatures(suite.T(), coreConfig.Docker, coreConfig.Kubernetes) + coreConfig.SetFeatures(suite.T(), env.Docker, env.Kubernetes) agent, sources, _ := createAgent(suite, endpoints) @@ -187,7 +185,7 @@ func (suite *AgentTestSuite) TestAgentStopsWithWrongBackendTcp() { endpoint := config.NewEndpoint("", "fake:", 0, false) endpoints := config.NewEndpoints(endpoint, []config.Endpoint{}, true, false) - coreConfig.SetFeatures(suite.T(), coreConfig.Docker, coreConfig.Kubernetes) + coreConfig.SetFeatures(suite.T(), env.Docker, env.Kubernetes) agent, sources, _ := createAgent(suite, endpoints) @@ -397,9 +395,7 @@ func (suite *AgentTestSuite) createDeps() dependencies { hostnameimpl.MockModule(), fx.Replace(configComponent.MockParams{Overrides: suite.configOverrides}), inventoryagentimpl.MockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), - integrations.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) } diff --git a/comp/logs/agent/agentimpl/serverless.go b/comp/logs/agent/agentimpl/serverless.go index 82afcbc110d98..66ec9b23ef7ee 100644 --- a/comp/logs/agent/agentimpl/serverless.go +++ b/comp/logs/agent/agentimpl/serverless.go @@ -23,7 +23,7 @@ func NewServerlessLogsAgent() agent.ServerlessLogsAgent { logsAgent := &logAgent{ log: logComponent.NewTemporaryLoggerWithoutInit(), config: pkgConfig.Datadog(), - started: atomic.NewBool(false), + started: atomic.NewUint32(0), sources: sources.NewLogSources(), services: service.NewServices(), diff --git a/comp/logs/agent/agentimpl/status_templates/logsagent.tmpl b/comp/logs/agent/agentimpl/status_templates/logsagent.tmpl index 2da805ecc9d64..71440cac2e718 100644 --- a/comp/logs/agent/agentimpl/status_templates/logsagent.tmpl +++ b/comp/logs/agent/agentimpl/status_templates/logsagent.tmpl @@ -1,7 +1,7 @@ {{ with .logsStats }} {{- if eq .IsRunning false }} Logs Agent is not running -{{- end }} +{{- end }}{{ if eq .WaitingForSDSConfig true }} (waiting for an SDS configuration){{ end }} {{- if .Endpoints }} diff --git a/comp/logs/agent/config/config_test.go b/comp/logs/agent/config/config_test.go index 35c6348278f1f..c0533b07131c9 100644 --- a/comp/logs/agent/config/config_test.go +++ b/comp/logs/agent/config/config_test.go @@ -12,21 +12,17 @@ import ( "github.com/DataDog/datadog-agent/comp/core/config" pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "go.uber.org/fx" ) type ConfigTestSuite struct { suite.Suite - config config.Mock + config config.Component } func (suite *ConfigTestSuite) SetupTest() { - suite.config = fxutil.Test[config.Component](suite.T(), fx.Options( - config.MockModule(), - )).(config.Mock) + suite.config = config.NewMock(suite.T()) } func (suite *ConfigTestSuite) TestDefaultDatadogConfig() { diff --git a/comp/logs/agent/config/endpoints_test.go b/comp/logs/agent/config/endpoints_test.go index ada452257d015..78c223b4f2f4b 100644 --- a/comp/logs/agent/config/endpoints_test.go +++ b/comp/logs/agent/config/endpoints_test.go @@ -10,23 +10,19 @@ import ( "time" "github.com/stretchr/testify/suite" - "go.uber.org/fx" "github.com/DataDog/datadog-agent/comp/core/config" pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" pkgconfigutils "github.com/DataDog/datadog-agent/pkg/config/utils" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) type EndpointsTestSuite struct { suite.Suite - config config.Mock + config config.Component } func (suite *EndpointsTestSuite) SetupTest() { - suite.config = fxutil.Test[config.Component](suite.T(), fx.Options( - config.MockModule(), - )).(config.Mock) + suite.config = config.NewMock(suite.T()) } func (suite *EndpointsTestSuite) TestLogsEndpointConfig() { diff --git a/comp/logs/agent/config/go.mod b/comp/logs/agent/config/go.mod index 03437e37d28ee..ee7c4157195db 100644 --- a/comp/logs/agent/config/go.mod +++ b/comp/logs/agent/config/go.mod @@ -13,6 +13,7 @@ replace ( github.com/DataDog/datadog-agent/comp/def => ../../../def github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../../pkg/config/env/ + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../../pkg/config/model/ github.com/DataDog/datadog-agent/pkg/config/setup => ../../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../../../pkg/config/utils @@ -42,7 +43,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/pointer v0.56.0-rc.3 github.com/DataDog/viper v1.13.5 github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.18.2 + go.uber.org/fx v1.22.2 ) require ( @@ -52,6 +53,7 @@ require ( github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel // indirect github.com/DataDog/datadog-agent/pkg/util/executable v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/filesystem v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/hostname/validate v0.56.0-rc.3 // indirect @@ -88,15 +90,15 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/comp/logs/agent/config/go.sum b/comp/logs/agent/config/go.sum index 7d9bb18a9b376..c0f06ba5f32fa 100644 --- a/comp/logs/agent/config/go.sum +++ b/comp/logs/agent/config/go.sum @@ -12,8 +12,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -238,27 +236,27 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -301,11 +299,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -318,8 +316,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/comp/logs/agent/config/integration_config_test.go b/comp/logs/agent/config/integration_config_test.go index 7318c5a1113ab..ca063afde161f 100644 --- a/comp/logs/agent/config/integration_config_test.go +++ b/comp/logs/agent/config/integration_config_test.go @@ -12,10 +12,8 @@ import ( "testing" "github.com/stretchr/testify/assert" - "go.uber.org/fx" "github.com/DataDog/datadog-agent/comp/core/config" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) func TestValidateShouldSucceedWithValidConfigs(t *testing.T) { @@ -55,17 +53,13 @@ func TestValidateShouldFailWithInvalidConfigs(t *testing.T) { } func TestAutoMultilineEnabled(t *testing.T) { - - mockConfig := fxutil.Test[config.Component](t, fx.Options( - config.MockModule(), - )).(config.Mock) - decode := func(cfg string) *LogsConfig { lc := LogsConfig{} json.Unmarshal([]byte(cfg), &lc) return &lc } + mockConfig := config.NewMock(t) mockConfig.SetWithoutSource("logs_config.auto_multi_line_detection", false) assert.False(t, decode(`{"auto_multi_line_detection":false}`).AutoMultiLineEnabled(mockConfig)) diff --git a/comp/logs/bundle.go b/comp/logs/bundle.go index 89e0f61a1dc3d..007b75f2dbe79 100644 --- a/comp/logs/bundle.go +++ b/comp/logs/bundle.go @@ -7,7 +7,6 @@ package logs //nolint:revive // TODO(AML) Fix revive linter import ( "github.com/DataDog/datadog-agent/comp/logs/agent/agentimpl" - logsIntegrationFx "github.com/DataDog/datadog-agent/comp/logs/integrations/fx" "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) @@ -17,6 +16,5 @@ import ( func Bundle() fxutil.BundleOptions { return fxutil.Bundle( agentimpl.Module(), - logsIntegrationFx.Module(), ) } diff --git a/comp/logs/bundle_mock.go b/comp/logs/bundle_mock.go index 8bbcb006bac07..d19ce030464da 100644 --- a/comp/logs/bundle_mock.go +++ b/comp/logs/bundle_mock.go @@ -9,7 +9,6 @@ package logs //nolint:revive // TODO(AML) Fix revive linter import ( "github.com/DataDog/datadog-agent/comp/logs/agent/agentimpl" - logsIntegrationFx "github.com/DataDog/datadog-agent/comp/logs/integrations/fx" "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) @@ -17,5 +16,5 @@ import ( func MockBundle() fxutil.BundleOptions { return fxutil.Bundle( agentimpl.MockModule(), - logsIntegrationFx.MockModule()) + ) } diff --git a/comp/logs/integrations/def/component.go b/comp/logs/integrations/def/component.go index b5b4e0afce1a3..52cae199cab7a 100644 --- a/comp/logs/integrations/def/component.go +++ b/comp/logs/integrations/def/component.go @@ -3,18 +3,28 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package integrations adds a go interface for integrations to send logs. +// Package integrations adds a go interface for integrations to register and +// send logs. // // The integrations component is a basic interface for integrations to send logs -// from one place to another. It has two faces: integrations can use the -// SendLog() function to send logs, and consumers can use the Subscribe() -// function to receive a channel that receives all the logs integrations send. +// from one place to another. Integrations and their configs can be registered +// using the RegisterIntegrations function and then use the SendLog function to +// send logs to consumers, who will use the SubscribeIntegration and Subscribe +// functions to receive integration configs and logs. package integrations +import "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" + // team: agent-metrics-logs // Component is the component type. type Component interface { + // RegisterIntegration registers an integration with the component. + RegisterIntegration(id string, config integration.Config) + + // SubscribeIntegration returns a channel for a subscriber to receive integration configurations. + SubscribeIntegration() chan IntegrationConfig + // Subscribe subscribes returns a channel for a subscriber to receive logs from integrations. Subscribe() chan IntegrationLog diff --git a/comp/logs/integrations/def/types.go b/comp/logs/integrations/def/types.go index 2aa6ea018407b..add6c8bf56b18 100644 --- a/comp/logs/integrations/def/types.go +++ b/comp/logs/integrations/def/types.go @@ -5,9 +5,17 @@ package integrations +import "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" + // IntegrationLog represents the combined Log and IntegrationID for the // integration sending the log type IntegrationLog struct { Log string IntegrationID string } + +// IntegrationConfig represents the combined ID and Config for an integration +type IntegrationConfig struct { + IntegrationID string + Config integration.Config +} diff --git a/comp/logs/integrations/impl/integrations.go b/comp/logs/integrations/impl/integrations.go index 87f5bb51d95fc..7f286becf1184 100644 --- a/comp/logs/integrations/impl/integrations.go +++ b/comp/logs/integrations/impl/integrations.go @@ -7,22 +7,36 @@ package integrationsimpl import ( + "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/def" ) -type logsintegration struct { - logChan chan integrations.IntegrationLog +// Logsintegration is the integrations component implementation +type Logsintegration struct { + logChan chan integrations.IntegrationLog + integrationChan chan integrations.IntegrationConfig } -// NewComponent creates a new integrations component -func NewComponent() integrations.Component { - return &logsintegration{ - logChan: make(chan integrations.IntegrationLog), +// NewLogsIntegration creates a new integrations instance +func NewLogsIntegration() *Logsintegration { + return &Logsintegration{ + logChan: make(chan integrations.IntegrationLog), + integrationChan: make(chan integrations.IntegrationConfig), } } +// RegisterIntegration registers an integration with the integrations component +func (li *Logsintegration) RegisterIntegration(id string, config integration.Config) { + integrationConfig := integrations.IntegrationConfig{ + IntegrationID: id, + Config: config, + } + + li.integrationChan <- integrationConfig +} + // SendLog sends a log to any subscribers -func (li *logsintegration) SendLog(log, integrationID string) { +func (li *Logsintegration) SendLog(log, integrationID string) { integrationLog := integrations.IntegrationLog{ Log: log, IntegrationID: integrationID, @@ -34,6 +48,11 @@ func (li *logsintegration) SendLog(log, integrationID string) { // Subscribe returns the channel that receives logs from integrations. Currently // the integrations component only supports one subscriber, but can be extended // later by making a new channel for any number of subscribers. -func (li *logsintegration) Subscribe() chan integrations.IntegrationLog { +func (li *Logsintegration) Subscribe() chan integrations.IntegrationLog { return li.logChan } + +// SubscribeIntegration returns the channel that receives integration configurations +func (li *Logsintegration) SubscribeIntegration() chan integrations.IntegrationConfig { + return li.integrationChan +} diff --git a/comp/logs/integrations/impl/integrations_test.go b/comp/logs/integrations/impl/integrations_test.go index 20ea0e6b8d184..52146c58961c8 100644 --- a/comp/logs/integrations/impl/integrations_test.go +++ b/comp/logs/integrations/impl/integrations_test.go @@ -12,14 +12,14 @@ import ( ) func TestNewComponent(t *testing.T) { - comp := NewComponent() + comp := NewLogsIntegration() assert.NotNil(t, comp, "Integrations component nil.") } // TestSendandSubscribe tests sending a log through the integrations component. func TestSendandSubscribe(t *testing.T) { - comp := NewComponent() + comp := NewLogsIntegration() go func() { comp.SendLog("test log", "integration1") diff --git a/comp/logs/integrations/mock/mock.go b/comp/logs/integrations/mock/mock.go index 1c3be50a32585..e06bc08914f50 100644 --- a/comp/logs/integrations/mock/mock.go +++ b/comp/logs/integrations/mock/mock.go @@ -8,30 +8,16 @@ package mock import ( integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/def" + integrationsimpl "github.com/DataDog/datadog-agent/comp/logs/integrations/impl" ) type mockIntegrations struct { - logChan chan integrations.IntegrationLog -} - -// Subscribe returns an integrationLog channel -func (l *mockIntegrations) Subscribe() chan integrations.IntegrationLog { - return l.logChan -} - -// SendLog sends a log to the log channel -func (l *mockIntegrations) SendLog(log, integrationID string) { - integrationLog := integrations.IntegrationLog{ - Log: log, - IntegrationID: integrationID, - } - - l.logChan <- integrationLog + *integrationsimpl.Logsintegration } // Mock returns a mock for integrations component. func Mock() integrations.Component { return &mockIntegrations{ - logChan: make(chan integrations.IntegrationLog), + Logsintegration: integrationsimpl.NewLogsIntegration(), } } diff --git a/comp/metadata/host/hostimpl/host.go b/comp/metadata/host/hostimpl/host.go index 3404b98724ff8..f3da89f29bae1 100644 --- a/comp/metadata/host/hostimpl/host.go +++ b/comp/metadata/host/hostimpl/host.go @@ -23,7 +23,7 @@ import ( hostComp "github.com/DataDog/datadog-agent/comp/metadata/host" "github.com/DataDog/datadog-agent/comp/metadata/resources" "github.com/DataDog/datadog-agent/comp/metadata/runner/runnerimpl" - pkgconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" configUtils "github.com/DataDog/datadog-agent/pkg/config/utils" "github.com/DataDog/datadog-agent/pkg/gohai" "github.com/DataDog/datadog-agent/pkg/serializer" @@ -152,7 +152,7 @@ func (h *host) writePayloadAsJSON(w http.ResponseWriter, _ *http.Request) { } func (h *host) writeGohaiPayload(w http.ResponseWriter, _ *http.Request) { - payload := gohai.GetPayloadWithProcesses(pkgconfig.IsContainerized()) + payload := gohai.GetPayloadWithProcesses(env.IsContainerized()) jsonPayload, err := json.MarshalIndent(payload, "", " ") if err != nil { httputils.SetJSONError(w, h.log.Errorf("Unable to marshal gohai metadata payload: %s", err), 500) diff --git a/comp/metadata/host/hostimpl/hosttags/tags.go b/comp/metadata/host/hostimpl/hosttags/tags.go index ef5f783ac571f..9215071ea4b33 100644 --- a/comp/metadata/host/hostimpl/hosttags/tags.go +++ b/comp/metadata/host/hostimpl/hosttags/tags.go @@ -13,6 +13,7 @@ import ( "time" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" configUtils "github.com/DataDog/datadog-agent/pkg/config/utils" "github.com/DataDog/datadog-agent/pkg/util" "github.com/DataDog/datadog-agent/pkg/util/cache" @@ -56,11 +57,11 @@ func getProvidersDefinitions(conf config.Reader) map[string]*providerDef { providers["ec2"] = &providerDef{10, ec2.GetTags} } - if config.IsFeaturePresent(config.Kubernetes) { - providers["kubernetes"] = &providerDef{10, k8s.GetTags} + if env.IsFeaturePresent(env.Kubernetes) { + providers["kubernetes"] = &providerDef{10, k8s.NewKubeNodeTagsProvider(conf).GetTags} } - if config.IsFeaturePresent(config.Docker) { + if env.IsFeaturePresent(env.Docker) { providers["docker"] = &providerDef{1, docker.GetTags} } return providers diff --git a/comp/metadata/host/hostimpl/payload.go b/comp/metadata/host/hostimpl/payload.go index ef5c2ae77620a..3a720d4888ba3 100644 --- a/comp/metadata/host/hostimpl/payload.go +++ b/comp/metadata/host/hostimpl/payload.go @@ -13,7 +13,7 @@ import ( "fmt" "github.com/DataDog/datadog-agent/comp/metadata/host/hostimpl/utils" - pkgconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/gohai" "github.com/DataDog/datadog-agent/pkg/serializer/marshaler" ) @@ -53,7 +53,7 @@ func (h *host) getPayload(ctx context.Context) *Payload { } if h.config.GetBool("enable_gohai") { - gohaiPayload, err := gohai.GetPayloadAsString(pkgconfig.IsContainerized()) + gohaiPayload, err := gohai.GetPayloadAsString(env.IsContainerized()) if err != nil { h.log.Errorf("Could not serialize gohai payload: %s", err) } else { diff --git a/comp/metadata/host/hostimpl/utils/meta_test.go b/comp/metadata/host/hostimpl/utils/meta_test.go index 5ea869b743d54..6bca2107e9eb4 100644 --- a/comp/metadata/host/hostimpl/utils/meta_test.go +++ b/comp/metadata/host/hostimpl/utils/meta_test.go @@ -11,13 +11,12 @@ import ( "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/pkg/util/cache" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/stretchr/testify/assert" ) func TestGetMeta(t *testing.T) { ctx := context.Background() - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) meta := GetMeta(ctx, cfg) assert.NotEmpty(t, meta.SocketHostname) @@ -27,7 +26,7 @@ func TestGetMeta(t *testing.T) { func TestGetMetaFromCache(t *testing.T) { ctx := context.Background() - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) cache.Cache.Set(metaCacheKey, &Meta{ SocketHostname: "socket_test", diff --git a/comp/metadata/inventoryagent/README.md b/comp/metadata/inventoryagent/README.md index 63c17e36bc9cb..07afed9f121b7 100644 --- a/comp/metadata/inventoryagent/README.md +++ b/comp/metadata/inventoryagent/README.md @@ -125,6 +125,7 @@ The payload is a JSON dict with the following fields - `source_local_configuration` - **string**: the Agent configuration synchronized from the local Agent process, as a YAML string. - `ecs_fargate_task_arn` - **string**: if the Agent runs in ECS Fargate, contains the Agent's Task ARN. Else, is empty. - `ecs_fargate_cluster_name` - **string**: if the Agent runs in ECS Fargate, contains the Agent's cluster name. Else, is empty. + - `fleet_policies_applied` -- **array of string**: The Fleet Policies that have been applied to the agent, if any. Is empty if no policy is applied. ("scrubbed" indicates that secrets are removed from the field value just as they are in logs) @@ -162,8 +163,8 @@ Here an example of an inventory payload: "install_method_tool_version": "", "logs_transport": "HTTP", "full_configuration": "", - "provided_configuration": "api_key: \"***************************aaaaa\"\ncheck_runners: 4\ncmd.check.fullsketches: false\ncontainerd_namespace: []\ncontainerd_namespaces: []\npython_version: \"3\"\ntracemalloc_debug: false\nlog_level: \"warn\"", - "file_configuration": "check_runners: 4\ncmd.check.fullsketches: false\ncontainerd_namespace: []\ncontainerd_namespaces: []\npython_version: \"3\"\ntracemalloc_debug: false", + "provided_configuration": "api_key: \"***************************aaaaa\"\ncheck_runners: 4\ncontainerd_namespace: []\ncontainerd_namespaces: []\npython_version: \"3\"\ntracemalloc_debug: false\nlog_level: \"warn\"", + "file_configuration": "check_runners: 4\ncontainerd_namespace: []\ncontainerd_namespaces: []\npython_version: \"3\"\ntracemalloc_debug: false", "agent_runtime_configuration": "runtime_block_profile_rate: 5000", "environment_variable_configuration": "api_key: \"***************************aaaaa\"", "remote_configuration": "log_level: \"debug\"", diff --git a/comp/metadata/inventoryagent/inventoryagentimpl/inventoryagent.go b/comp/metadata/inventoryagent/inventoryagentimpl/inventoryagent.go index 51adab5ea734e..c1ecb0a63d55b 100644 --- a/comp/metadata/inventoryagent/inventoryagentimpl/inventoryagent.go +++ b/comp/metadata/inventoryagent/inventoryagentimpl/inventoryagent.go @@ -240,6 +240,11 @@ func (ia *inventoryagent) fetchCoreAgentMetadata() { ia.data["feature_csm_vm_containers_enabled"] = ia.conf.GetBool("sbom.enabled") && ia.conf.GetBool("container_image.enabled") && ia.conf.GetBool("sbom.container_image.enabled") ia.data["feature_csm_vm_hosts_enabled"] = ia.conf.GetBool("sbom.enabled") && ia.conf.GetBool("sbom.host.enabled") + + ia.data["fleet_policies_applied"] = ia.conf.GetStringSlice("fleet_layers") + + // ECS Fargate + ia.fetchECSFargateAgentMetadata() } func (ia *inventoryagent) fetchSecurityAgentMetadata() { @@ -325,9 +330,6 @@ func (ia *inventoryagent) fetchSystemProbeMetadata() { ia.data["system_probe_root_namespace_enabled"] = sysProbeConf.GetBool("network_config.enable_root_netns") ia.data["feature_dynamic_instrumentation_enabled"] = sysProbeConf.GetBool("dynamic_instrumentation.enabled") - - // ECS Fargate - ia.fetchECSFargateAgentMetadata() } // fetchECSFargateAgentMetadata fetches ECS Fargate agent metadata from the ECS metadata V2 service. diff --git a/comp/metadata/inventorychecks/inventorychecksimpl/inventorychecks_test.go b/comp/metadata/inventorychecks/inventorychecksimpl/inventorychecks_test.go index 3a75944f50d49..aa3ca8c2baff3 100644 --- a/comp/metadata/inventorychecks/inventorychecksimpl/inventorychecks_test.go +++ b/comp/metadata/inventorychecks/inventorychecksimpl/inventorychecks_test.go @@ -134,8 +134,7 @@ func TestGetPayload(t *testing.T) { }), collectorimpl.MockModule(), core.MockBundle(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), ) // Setup log sources @@ -152,7 +151,7 @@ func TestGetPayload(t *testing.T) { src.Status.Error(fmt.Errorf("No such file or directory")) logSources.AddSource(src) mockLogAgent := fxutil.Test[optional.Option[logagent.Mock]]( - t, logsBundle.MockBundle(), core.MockBundle(), inventoryagentimpl.MockModule(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams()), + t, logsBundle.MockBundle(), core.MockBundle(), inventoryagentimpl.MockModule(), workloadmetafxmock.MockModule(workloadmeta.NewParams()), ) logsAgent, _ := mockLogAgent.Get() logsAgent.SetSources(logSources) diff --git a/comp/metadata/securityagent/impl/security_agent_test.go b/comp/metadata/securityagent/impl/security_agent_test.go index 5d7d399689790..cd41cee82a0fc 100644 --- a/comp/metadata/securityagent/impl/security_agent_test.go +++ b/comp/metadata/securityagent/impl/security_agent_test.go @@ -53,7 +53,7 @@ func setupFetcher(t *testing.T) { func getSecurityAgentComp(t *testing.T, enableConfig bool) *secagent { l := logmock.New(t) - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) cfg.Set("inventories_configuration_enabled", enableConfig, model.SourceUnknown) r := Requires{ diff --git a/comp/metadata/systemprobe/impl/system_probe_test.go b/comp/metadata/systemprobe/impl/system_probe_test.go index 99a5a15b95e6b..edc18b5e79dbf 100644 --- a/comp/metadata/systemprobe/impl/system_probe_test.go +++ b/comp/metadata/systemprobe/impl/system_probe_test.go @@ -56,7 +56,7 @@ func setupFetcher(t *testing.T) { func getSystemProbeComp(t *testing.T, enableConfig bool) *systemprobe { l := logmock.New(t) - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) cfg.Set("inventories_configuration_enabled", enableConfig, model.SourceUnknown) r := Requires{ diff --git a/comp/netflow/flowaggregator/aggregator.go b/comp/netflow/flowaggregator/aggregator.go index 2f41e2ed85716..93afc304748b8 100644 --- a/comp/netflow/flowaggregator/aggregator.go +++ b/comp/netflow/flowaggregator/aggregator.go @@ -212,12 +212,16 @@ func (agg *FlowAggregator) flushLoop() { var flushFlowsToSendTicker <-chan time.Time if agg.FlushFlowsToSendInterval > 0 { - flushFlowsToSendTicker = time.NewTicker(agg.FlushFlowsToSendInterval).C + flushTicker := time.NewTicker(agg.FlushFlowsToSendInterval) + flushFlowsToSendTicker = flushTicker.C + defer flushTicker.Stop() } else { agg.logger.Debug("flushFlowsToSendInterval set to 0: will never flush automatically") } - rollupTrackersRefresh := time.NewTicker(agg.rollupTrackerRefreshInterval).C + rollupTicker := time.NewTicker(agg.rollupTrackerRefreshInterval) + defer rollupTicker.Stop() + rollupTrackersRefresh := rollupTicker.C // TODO: move rollup tracker refresh to a separate loop (separate PR) to avoid rollup tracker and flush flows impacting each other var lastFlushTime time.Time diff --git a/comp/networkpath/npcollector/npcollectorimpl/npcollector.go b/comp/networkpath/npcollector/npcollectorimpl/npcollector.go index 7f90b19a70c80..e35cdc9d05c51 100644 --- a/comp/networkpath/npcollector/npcollectorimpl/npcollector.go +++ b/comp/networkpath/npcollector/npcollectorimpl/npcollector.go @@ -222,6 +222,7 @@ func (s *npCollectorImpl) runTracerouteForPath(ptest *pathteststore.PathtestCont } path.Source.ContainerID = ptest.Pathtest.SourceContainerID path.Namespace = s.networkDevicesNamespace + path.Origin = payload.PathOriginNetworkTraffic s.sendTelemetry(path, startTime, ptest) @@ -267,6 +268,7 @@ func (s *npCollectorImpl) flushLoop() { // automatic flush sequence case flushTime := <-flushTicker.C: s.flushWrapper(flushTime, lastFlushTime) + lastFlushTime = flushTime } } } @@ -277,7 +279,6 @@ func (s *npCollectorImpl) flushWrapper(flushTime time.Time, lastFlushTime time.T flushInterval := flushTime.Sub(lastFlushTime) s.statsdClient.Gauge("datadog.network_path.collector.flush_interval", flushInterval.Seconds(), []string{}, 1) //nolint:errcheck } - lastFlushTime = flushTime s.flush() s.statsdClient.Gauge("datadog.network_path.collector.flush_duration", s.TimeNowFn().Sub(flushTime).Seconds(), []string{}, 1) //nolint:errcheck @@ -307,7 +308,6 @@ func (s *npCollectorImpl) sendTelemetry(path payload.NetworkPath, startTime time telemetry.SubmitNetworkPathTelemetry( s.metricSender, path, - telemetry.CollectorTypeNetworkPathCollector, checkDuration, checkInterval, []string{}, diff --git a/comp/networkpath/npcollector/npcollectorimpl/npcollector_test.go b/comp/networkpath/npcollector/npcollectorimpl/npcollector_test.go index 129d6b879202c..9fe8542ab59d2 100644 --- a/comp/networkpath/npcollector/npcollectorimpl/npcollector_test.go +++ b/comp/networkpath/npcollector/npcollectorimpl/npcollector_test.go @@ -103,6 +103,7 @@ func Test_NpCollector_runningAndProcessing(t *testing.T) { var p payload.NetworkPath if cfg.DestHostname == "10.0.0.2" { p = payload.NetworkPath{ + PathtraceID: "pathtrace-id-111", Protocol: payload.ProtocolUDP, Source: payload.NetworkPathSource{Hostname: "abc"}, Destination: payload.NetworkPathDestination{Hostname: "abc", IPAddress: "10.0.0.2", Port: 80}, @@ -114,6 +115,7 @@ func Test_NpCollector_runningAndProcessing(t *testing.T) { } if cfg.DestHostname == "10.0.0.4" { p = payload.NetworkPath{ + PathtraceID: "pathtrace-id-222", Protocol: payload.ProtocolUDP, Source: payload.NetworkPathSource{Hostname: "abc"}, Destination: payload.NetworkPathDestination{Hostname: "abc", IPAddress: "10.0.0.4", Port: 80}, @@ -132,7 +134,8 @@ func Test_NpCollector_runningAndProcessing(t *testing.T) { { "timestamp": 0, "namespace": "my-ns1", - "path_id": "", + "pathtrace_id": "pathtrace-id-111", + "origin":"network_traffic", "protocol": "UDP", "source": { "hostname": "abc", @@ -164,7 +167,8 @@ func Test_NpCollector_runningAndProcessing(t *testing.T) { { "timestamp": 0, "namespace": "my-ns1", - "path_id": "", + "pathtrace_id": "pathtrace-id-222", + "origin":"network_traffic", "protocol": "UDP", "source": { "hostname": "abc", @@ -225,7 +229,9 @@ func Test_NpCollector_runningAndProcessing(t *testing.T) { tags := []string{ "collector:network_path_collector", "destination_hostname:abc", + "destination_ip:10.0.0.4", "destination_port:80", + "origin:network_traffic", "protocol:UDP", } assert.Contains(t, calls, teststatsd.MetricsArgs{Name: "datadog.network_path.path.monitored", Value: 1, Tags: tags, Rate: 1}) @@ -641,6 +647,37 @@ func Test_npCollectorImpl_flush(t *testing.T) { assert.Equal(t, 2, len(npCollector.pathtestProcessingChan)) } +func Test_npCollectorImpl_flushLoop(t *testing.T) { + // GIVEN + agentConfigs := map[string]any{ + "network_path.connections_monitoring.enabled": true, + "network_path.collector.workers": 6, + "network_path.collector.flush_interval": "100ms", + } + _, npCollector := newTestNpCollector(t, agentConfigs) + defer npCollector.stop() + + stats := &teststatsd.Client{} + npCollector.statsdClient = stats + npCollector.pathtestStore.Add(&common.Pathtest{Hostname: "host1", Port: 53}) + npCollector.pathtestStore.Add(&common.Pathtest{Hostname: "host2", Port: 53}) + + // WHEN + go npCollector.flushLoop() + + // THEN + assert.Eventually(t, func() bool { + calls := stats.GetGaugeSummaries()["datadog.network_path.collector.flush_interval"] + if calls == nil { + return false + } + for _, call := range calls.Calls { + assert.Less(t, call.Value, (200 * time.Millisecond).Seconds()) + } + return len(calls.Calls) >= 3 + }, 3*time.Second, 10*time.Millisecond) +} + func Test_npCollectorImpl_sendTelemetry(t *testing.T) { // GIVEN agentConfigs := map[string]any{ @@ -653,6 +690,7 @@ func Test_npCollectorImpl_sendTelemetry(t *testing.T) { npCollector.statsdClient = stats npCollector.metricSender = metricsender.NewMetricSenderStatsd(stats) path := payload.NetworkPath{ + Origin: payload.PathOriginNetworkTraffic, Source: payload.NetworkPathSource{Hostname: "abc"}, Destination: payload.NetworkPathDestination{Hostname: "abc", IPAddress: "10.0.0.2", Port: 80}, Protocol: payload.ProtocolUDP, @@ -676,7 +714,9 @@ func Test_npCollectorImpl_sendTelemetry(t *testing.T) { tags := []string{ "collector:network_path_collector", "destination_hostname:abc", + "destination_ip:10.0.0.2", "destination_port:80", + "origin:network_traffic", "protocol:UDP", } assert.Contains(t, calls, teststatsd.MetricsArgs{Name: "datadog.network_path.check_duration", Value: 3, Tags: tags, Rate: 1}) diff --git a/comp/otelcol/collector-contrib/def/go.mod b/comp/otelcol/collector-contrib/def/go.mod index 6f2653f77e7a4..3cd0bf6b22fdd 100644 --- a/comp/otelcol/collector-contrib/def/go.mod +++ b/comp/otelcol/collector-contrib/def/go.mod @@ -73,10 +73,10 @@ require ( go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.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 diff --git a/comp/otelcol/collector-contrib/def/go.sum b/comp/otelcol/collector-contrib/def/go.sum index 6b0e04985f3cc..4c8662c4b1dfa 100644 --- a/comp/otelcol/collector-contrib/def/go.sum +++ b/comp/otelcol/collector-contrib/def/go.sum @@ -239,8 +239,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -255,8 +255,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL 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.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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= @@ -271,12 +271,12 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w 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.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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= diff --git a/comp/otelcol/collector-contrib/impl/go.mod b/comp/otelcol/collector-contrib/impl/go.mod index b86340f2a2c98..96fb8ef3d6823 100644 --- a/comp/otelcol/collector-contrib/impl/go.mod +++ b/comp/otelcol/collector-contrib/impl/go.mod @@ -268,17 +268,17 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/api v0.169.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect diff --git a/comp/otelcol/collector-contrib/impl/go.sum b/comp/otelcol/collector-contrib/impl/go.sum index 810f91a47c85e..b4814e7aa6f0c 100644 --- a/comp/otelcol/collector-contrib/impl/go.sum +++ b/comp/otelcol/collector-contrib/impl/go.sum @@ -1035,8 +1035,8 @@ golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1047,8 +1047,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1133,8 +1133,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1234,8 +1234,8 @@ 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.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1249,8 +1249,8 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1266,8 +1266,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1329,8 +1329,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/comp/otelcol/collector/impl-pipeline/flare_filler.go b/comp/otelcol/collector/impl-pipeline/flare_filler.go index faee05d972332..bc2151c9a68e2 100644 --- a/comp/otelcol/collector/impl-pipeline/flare_filler.go +++ b/comp/otelcol/collector/impl-pipeline/flare_filler.go @@ -12,6 +12,7 @@ import ( "context" "crypto/tls" "encoding/json" + "errors" "fmt" "io" "net/http" @@ -19,10 +20,11 @@ import ( "strings" "time" + "github.com/gocolly/colly/v2" + flaretypes "github.com/DataDog/datadog-agent/comp/core/flare/types" - extension "github.com/DataDog/datadog-agent/comp/otelcol/extension/def" + extension "github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/gocolly/colly/v2" ) func (c *collectorImpl) fillFlare(fb flaretypes.FlareBuilder) error { @@ -160,7 +162,7 @@ func (c *collectorImpl) requestOtelConfigInfo(endpointURL string) ([]byte, error return nil, err } if res.StatusCode >= 400 { - return nil, fmt.Errorf("%s", body) + return nil, errors.New(string(body)) } return body, nil } diff --git a/comp/otelcol/collector/impl-pipeline/flare_filler_test.go b/comp/otelcol/collector/impl-pipeline/flare_filler_test.go index 546ed0bf7419d..0f7712f4fd3b7 100644 --- a/comp/otelcol/collector/impl-pipeline/flare_filler_test.go +++ b/comp/otelcol/collector/impl-pipeline/flare_filler_test.go @@ -21,13 +21,11 @@ import ( "text/template" "github.com/stretchr/testify/require" - "go.uber.org/fx" "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/comp/core/flare/helpers" compdef "github.com/DataDog/datadog-agent/comp/def" pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) func createFakeOTelExtensionHTTPServer() (string, func()) { @@ -123,11 +121,7 @@ func TestOTelExtFlareBuilder(t *testing.T) { overrideConfigResponse = b.String() defer func() { overrideConfigResponse = "" }() - cfg := fxutil.Test[config.Component](t, - fx.Options( - config.MockModule(), - ), - ) + cfg := config.NewMock(t) cfg.Set("otelcollector.enabled", true, pkgconfigmodel.SourceAgentRuntime) cfg.Set("otelcollector.extension_url", 7777, pkgconfigmodel.SourceAgentRuntime) diff --git a/comp/otelcol/collector/impl/collector.go b/comp/otelcol/collector/impl/collector.go index 7805b96f31275..87fcbae39ce63 100644 --- a/comp/otelcol/collector/impl/collector.go +++ b/comp/otelcol/collector/impl/collector.go @@ -21,13 +21,14 @@ import ( "go.opentelemetry.io/collector/confmap/provider/yamlprovider" "go.opentelemetry.io/collector/otelcol" + "github.com/DataDog/datadog-agent/comp/core/config" log "github.com/DataDog/datadog-agent/comp/core/log/def" "github.com/DataDog/datadog-agent/comp/core/tagger" compdef "github.com/DataDog/datadog-agent/comp/def" collectorcontrib "github.com/DataDog/datadog-agent/comp/otelcol/collector-contrib/def" collector "github.com/DataDog/datadog-agent/comp/otelcol/collector/def" configstore "github.com/DataDog/datadog-agent/comp/otelcol/configstore/def" - ddextension "github.com/DataDog/datadog-agent/comp/otelcol/extension/impl" + ddextension "github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl" "github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline" "github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/exporter/datadogexporter" "github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/exporter/serializerexporter" @@ -59,6 +60,7 @@ type Requires struct { Log log.Component Provider confmap.Converter ConfigStore configstore.Component + Config config.Component CollectorContrib collectorcontrib.Component Serializer serializer.MetricSerializer TraceAgent traceagent.Component @@ -127,7 +129,8 @@ func NewComponent(reqs Requires) (Provides, error) { } addFactories(reqs, factories) - err = reqs.ConfigStore.AddConfigs(newConfigProviderSettings(reqs, false), newConfigProviderSettings(reqs, true), factories) + converterEnabled := reqs.Config.GetBool("otelcollector.converter.enabled") + err = reqs.ConfigStore.AddConfigs(newConfigProviderSettings(reqs, false), newConfigProviderSettings(reqs, converterEnabled), factories) if err != nil { return Provides{}, err } @@ -148,7 +151,7 @@ func NewComponent(reqs Requires) (Provides, error) { Factories: func() (otelcol.Factories, error) { return factories, nil }, - ConfigProviderSettings: newConfigProviderSettings(reqs, true), + ConfigProviderSettings: newConfigProviderSettings(reqs, converterEnabled), } col, err := otelcol.NewCollector(set) if err != nil { diff --git a/comp/otelcol/collector/impl/collector_test.go b/comp/otelcol/collector/impl/collector_test.go index e9bd6bc6b3cf3..328a40e245a07 100644 --- a/comp/otelcol/collector/impl/collector_test.go +++ b/comp/otelcol/collector/impl/collector_test.go @@ -17,6 +17,7 @@ import ( collectorcontribimpl "github.com/DataDog/datadog-agent/comp/otelcol/collector-contrib/impl" configstore "github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl" converter "github.com/DataDog/datadog-agent/comp/otelcol/converter/impl" + "github.com/DataDog/datadog-agent/pkg/config/setup" "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/confmap/confmaptest" "gopkg.in/yaml.v3" @@ -46,8 +47,11 @@ func TestGetConfDump(t *testing.T) { provider, err := converter.NewConverter() assert.NoError(t, err) + conf := setup.Datadog() + reqs := Requires{ CollectorContrib: collectorcontribimpl.NewComponent(), + Config: conf, URIs: uriFromFile("simple-dd/config.yaml"), ConfigStore: configstore, Lc: &lifecycle{}, @@ -112,3 +116,81 @@ func TestGetConfDump(t *testing.T) { assert.Equal(t, expectedStringMap, actualStringMap) }) } + +func TestGetConfDumpConverterDisabled(t *testing.T) { + configstore, err := configstore.NewConfigStore() + assert.NoError(t, err) + + provider, err := converter.NewConverter() + assert.NoError(t, err) + + conf := setup.Datadog() + conf.SetWithoutSource("otelcollector.converter.enabled", false) + + reqs := Requires{ + CollectorContrib: collectorcontribimpl.NewComponent(), + Config: conf, + URIs: uriFromFile("simple-dd/config.yaml"), + ConfigStore: configstore, + Lc: &lifecycle{}, + Provider: provider, + } + _, err = NewComponent(reqs) + assert.NoError(t, err) + + t.Run("provided-string", func(t *testing.T) { + actualString, _ := configstore.GetProvidedConfAsString() + actualStringMap, err := yamlBytesToMap([]byte(actualString)) + assert.NoError(t, err) + + expectedBytes, err := os.ReadFile(filepath.Join("testdata", "simple-dd", "config-provided-result.yaml")) + assert.NoError(t, err) + expectedMap, err := yamlBytesToMap(expectedBytes) + assert.NoError(t, err) + + assert.Equal(t, expectedMap, actualStringMap) + }) + + t.Run("provided-confmap", func(t *testing.T) { + actualConfmap, _ := configstore.GetProvidedConf() + // marshal to yaml and then to map to drop the types for comparison + bytesConf, err := yaml.Marshal(actualConfmap.ToStringMap()) + assert.NoError(t, err) + actualStringMap, err := yamlBytesToMap(bytesConf) + assert.NoError(t, err) + + expectedMap, err := confmaptest.LoadConf("testdata/simple-dd/config-provided-result.yaml") + expectedStringMap := expectedMap.ToStringMap() + assert.NoError(t, err) + + assert.Equal(t, expectedStringMap, actualStringMap) + }) + + t.Run("enhanced-string", func(t *testing.T) { + actualString, _ := configstore.GetEnhancedConfAsString() + actualStringMap, err := yamlBytesToMap([]byte(actualString)) + assert.NoError(t, err) + + expectedBytes, err := os.ReadFile(filepath.Join("testdata", "simple-dd", "config-provided-result.yaml")) + assert.NoError(t, err) + expectedMap, err := yamlBytesToMap(expectedBytes) + assert.NoError(t, err) + + assert.Equal(t, expectedMap, actualStringMap) + }) + + t.Run("enhance-confmap", func(t *testing.T) { + actualConfmap, _ := configstore.GetEnhancedConf() + // marshal to yaml and then to map to drop the types for comparison + bytesConf, err := yaml.Marshal(actualConfmap.ToStringMap()) + assert.NoError(t, err) + actualStringMap, err := yamlBytesToMap(bytesConf) + assert.NoError(t, err) + + expectedMap, err := confmaptest.LoadConf("testdata/simple-dd/config-provided-result.yaml") + expectedStringMap := expectedMap.ToStringMap() + assert.NoError(t, err) + + assert.Equal(t, expectedStringMap, actualStringMap) + }) +} diff --git a/comp/otelcol/collector/impl/testdata/simple-dd/config-enhanced-result.yaml b/comp/otelcol/collector/impl/testdata/simple-dd/config-enhanced-result.yaml index ec57f953248db..3fcc48e71a6af 100644 --- a/comp/otelcol/collector/impl/testdata/simple-dd/config-enhanced-result.yaml +++ b/comp/otelcol/collector/impl/testdata/simple-dd/config-enhanced-result.yaml @@ -3,7 +3,7 @@ exporters: datadog: api: fail_on_invalid_key: false - key: '[REDACTED]' + key: "[REDACTED]" site: datadoghq.com auth: null compression: "" @@ -69,15 +69,15 @@ exporters: timeout: 15s tls: ca_file: "" - ca_pem: '[REDACTED]' + ca_pem: "[REDACTED]" cert_file: "" - cert_pem: '[REDACTED]' + cert_pem: "[REDACTED]" cipher_suites: [] include_system_ca_certs_pool: false insecure: false insecure_skip_verify: false key_file: "" - key_pem: '[REDACTED]' + key_pem: "[REDACTED]" max_version: "" min_version: "" reload_interval: 0s @@ -93,7 +93,7 @@ exporters: trace_buffer: 0 write_buffer_size: 0 extensions: - datadog/dd-autoconfigured: + ddflare/dd-autoconfigured: auth: null compression_algorithms: [] configstore: {} @@ -154,28 +154,28 @@ receivers: evaluation_interval: 1m scrape_interval: 1m scrape_protocols: - - OpenMetricsText1.0.0 - - OpenMetricsText0.0.1 - - PrometheusText0.0.4 + - OpenMetricsText1.0.0 + - OpenMetricsText0.0.1 + - PrometheusText0.0.4 scrape_timeout: 10s scrape_configs: - - enable_compression: true - enable_http2: true - follow_redirects: true - honor_timestamps: true - job_name: datadog-agent - metrics_path: /metrics - scheme: http - scrape_interval: 5s - scrape_protocols: - - OpenMetricsText1.0.0 - - OpenMetricsText0.0.1 - - PrometheusText0.0.4 - scrape_timeout: 5s - static_configs: - - targets: - - 0.0.0.0:8888 - track_timestamps_staleness: false + - enable_compression: true + enable_http2: true + follow_redirects: true + honor_timestamps: true + job_name: datadog-agent + metrics_path: /metrics + scheme: http + scrape_interval: 5s + scrape_protocols: + - OpenMetricsText1.0.0 + - OpenMetricsText0.0.1 + - PrometheusText0.0.4 + scrape_timeout: 5s + static_configs: + - targets: + - 0.0.0.0:8888 + track_timestamps_staleness: false report_extra_scrape_metrics: false start_time_metric_regex: "" target_allocator: null @@ -183,33 +183,33 @@ receivers: use_start_time_metric: false service: extensions: - - pprof/dd-autoconfigured - - zpages/dd-autoconfigured - - health_check/dd-autoconfigured - - datadog/dd-autoconfigured + - pprof/dd-autoconfigured + - zpages/dd-autoconfigured + - health_check/dd-autoconfigured + - ddflare/dd-autoconfigured pipelines: logs: exporters: - - datadog + - datadog processors: - - infraattributes/dd-autoconfigured + - infraattributes/dd-autoconfigured receivers: - - otlp + - otlp metrics: exporters: - - datadog + - datadog processors: - - infraattributes/dd-autoconfigured + - infraattributes/dd-autoconfigured receivers: - - otlp - - prometheus + - otlp + - prometheus traces: exporters: - - datadog + - datadog processors: - - infraattributes/dd-autoconfigured + - infraattributes/dd-autoconfigured receivers: - - otlp + - otlp telemetry: logs: development: false @@ -217,11 +217,11 @@ service: disable_stacktrace: false encoding: console error_output_paths: - - stderr + - stderr initial_fields: {} level: info output_paths: - - stderr + - stderr sampling: enabled: true initial: 10 diff --git a/comp/otelcol/configstore/def/go.mod b/comp/otelcol/configstore/def/go.mod index d76a433fdca26..b8b63f40b0278 100644 --- a/comp/otelcol/configstore/def/go.mod +++ b/comp/otelcol/configstore/def/go.mod @@ -75,10 +75,10 @@ require ( go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.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 diff --git a/comp/otelcol/configstore/def/go.sum b/comp/otelcol/configstore/def/go.sum index 6b0e04985f3cc..4c8662c4b1dfa 100644 --- a/comp/otelcol/configstore/def/go.sum +++ b/comp/otelcol/configstore/def/go.sum @@ -239,8 +239,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -255,8 +255,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL 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.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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= @@ -271,12 +271,12 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w 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.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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= diff --git a/comp/otelcol/configstore/impl/go.mod b/comp/otelcol/configstore/impl/go.mod index 7384795f8dc1f..8b263d73c0d03 100644 --- a/comp/otelcol/configstore/impl/go.mod +++ b/comp/otelcol/configstore/impl/go.mod @@ -81,10 +81,10 @@ require ( go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.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-20240624140628-dc46fd24d27d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // indirect diff --git a/comp/otelcol/configstore/impl/go.sum b/comp/otelcol/configstore/impl/go.sum index 75c601a6ee36e..d3cae0a850882 100644 --- a/comp/otelcol/configstore/impl/go.sum +++ b/comp/otelcol/configstore/impl/go.sum @@ -419,8 +419,8 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3 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-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -447,8 +447,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -495,8 +495,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -504,8 +504,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= diff --git a/comp/otelcol/converter/impl/autoconfigure.go b/comp/otelcol/converter/impl/autoconfigure.go index 40bb2f55ef7e8..4c1023ad2ae05 100644 --- a/comp/otelcol/converter/impl/autoconfigure.go +++ b/comp/otelcol/converter/impl/autoconfigure.go @@ -36,6 +36,9 @@ func enhanceConfig(conf *confmap.Conf) { // prometheus receiver addPrometheusReceiver(conf, prometheusReceiver) + + // datadog connector + changeDefaultConfigsForDatadogConnector(conf) } func componentName(fullName string) string { diff --git a/comp/otelcol/converter/impl/converter_test.go b/comp/otelcol/converter/impl/converter_test.go index 912186d7f76ee..7b07dd1de1a35 100644 --- a/comp/otelcol/converter/impl/converter_test.go +++ b/comp/otelcol/converter/impl/converter_test.go @@ -51,6 +51,21 @@ func TestConvert(t *testing.T) { provided string expectedResult string }{ + { + name: "connectors/no-dd-connector", + provided: "connectors/no-dd-connector/config.yaml", + expectedResult: "connectors/no-dd-connector/config.yaml", + }, + { + name: "connectors/already-set", + provided: "connectors/already-set/config.yaml", + expectedResult: "connectors/already-set/config.yaml", + }, + { + name: "connectors/set-default", + provided: "connectors/set-default/config.yaml", + expectedResult: "connectors/set-default/config-result.yaml", + }, { name: "extensions/no-extensions", provided: "extensions/no-extensions/config.yaml", @@ -121,6 +136,16 @@ func TestConvert(t *testing.T) { provided: "receivers/no-receivers-defined/config.yaml", expectedResult: "receivers/no-receivers-defined/config-result.yaml", }, + { + name: "processors/dd-connector", + provided: "processors/dd-connector/config.yaml", + expectedResult: "processors/dd-connector/config-result.yaml", + }, + { + name: "processors/dd-connector-multi-pipelines", + provided: "processors/dd-connector-multi-pipelines/config.yaml", + expectedResult: "processors/dd-connector-multi-pipelines/config-result.yaml", + }, } for _, tc := range tests { diff --git a/comp/otelcol/converter/impl/datadogconnector.go b/comp/otelcol/converter/impl/datadogconnector.go new file mode 100644 index 0000000000000..75c023237bc82 --- /dev/null +++ b/comp/otelcol/converter/impl/datadogconnector.go @@ -0,0 +1,58 @@ +// 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 2024-present Datadog, Inc. + +// Package converterimpl provides the implementation of the otel-agent converter. +package converterimpl + +import ( + "go.opentelemetry.io/collector/confmap" +) + +func changeDefaultConfigsForDatadogConnector(conf *confmap.Conf) { + stringMapConf := conf.ToStringMap() + connectors, ok := stringMapConf["connectors"] + if !ok { + return + } + connectorMap, ok := connectors.(map[string]any) + if !ok { + return + } + changed := false + for name, ccfg := range connectorMap { + if componentName(name) != "datadog" { + continue + } + if ccfg == nil { + connectorMap[name] = map[string]any{ + "traces": map[string]any{"span_name_as_resource_name": true}, + } + changed = true + continue + } + ddconnectorCfg, ok := ccfg.(map[string]any) + if !ok { + continue + } + tcfg, ok := ddconnectorCfg["traces"] + if !ok || tcfg == nil { + ddconnectorCfg["traces"] = map[string]any{"span_name_as_resource_name": true} + changed = true + continue + } + tcfgMap, ok := tcfg.(map[string]any) + if !ok { + continue + } + _, isSet := tcfgMap["span_name_as_resource_name"] + if !isSet { + tcfgMap["span_name_as_resource_name"] = true + changed = true + } + } + if changed { + *conf = *confmap.NewFromStringMap(stringMapConf) + } +} diff --git a/comp/otelcol/converter/impl/extensions.go b/comp/otelcol/converter/impl/extensions.go index 75db82e3ae062..1d3911210bf62 100644 --- a/comp/otelcol/converter/impl/extensions.go +++ b/comp/otelcol/converter/impl/extensions.go @@ -6,7 +6,10 @@ // Package converterimpl provides the implementation of the otel-agent converter. package converterimpl -import "go.opentelemetry.io/collector/confmap" +import ( + ddextension "github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl" + "go.opentelemetry.io/collector/confmap" +) var ( // pprof @@ -27,7 +30,7 @@ var ( healthCheckConfig any // datadog - datadogName = "datadog" + datadogName = ddextension.Type.String() datadogEnhancedName = datadogName + "/" + ddAutoconfiguredSuffix datadogConfig any diff --git a/comp/otelcol/converter/impl/go.mod b/comp/otelcol/converter/impl/go.mod index 4e493103c30d2..b22320bfac371 100644 --- a/comp/otelcol/converter/impl/go.mod +++ b/comp/otelcol/converter/impl/go.mod @@ -2,10 +2,17 @@ module github.com/DataDog/datadog-agent/comp/otelcol/converter/impl go 1.22.0 -replace github.com/DataDog/datadog-agent/comp/otelcol/converter/def => ../def +replace ( + github.com/DataDog/datadog-agent/comp/otelcol/configstore/def => ../../configstore/def/ + github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl => ../../configstore/impl/ + github.com/DataDog/datadog-agent/comp/otelcol/converter/def => ../def + github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def => ../../ddflareextension/def/ + github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl => ../../ddflareextension/impl/ +) require ( - github.com/DataDog/datadog-agent/comp/otelcol/converter/def v0.56.0-rc.3 + github.com/DataDog/datadog-agent/comp/otelcol/converter/def v0.0.0-00010101000000-000000000000 + github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl v0.0.0-00010101000000-000000000000 github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/confmap v0.104.0 go.opentelemetry.io/collector/confmap/converter/expandconverter v0.104.0 @@ -14,22 +21,103 @@ require ( go.opentelemetry.io/collector/confmap/provider/httpprovider v0.104.0 go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.104.0 go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.104.0 + ) require ( + github.com/DataDog/datadog-agent/comp/otelcol/configstore/def v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def v0.0.0-00010101000000-000000000000 // indirect + 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.3.0 // 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-20220913051719-115f729f3c8c // 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // 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.1 // indirect + github.com/rs/cors v1.11.0 // 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.14 // indirect + github.com/tklauser/numcpus v0.8.0 // 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/component 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/confighttp v0.104.0 // indirect + go.opentelemetry.io/collector/config/configopaque 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/connector v0.104.0 // indirect + go.opentelemetry.io/collector/consumer v0.104.0 // indirect + go.opentelemetry.io/collector/exporter v0.104.0 // indirect + go.opentelemetry.io/collector/extension 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/otelcol v0.104.0 // indirect + go.opentelemetry.io/collector/pdata v1.11.0 // indirect + go.opentelemetry.io/collector/processor v0.104.0 // indirect + go.opentelemetry.io/collector/receiver v0.104.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/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 go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.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-20240624140628-dc46fd24d27d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // 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/comp/otelcol/converter/impl/go.sum b/comp/otelcol/converter/impl/go.sum index 7950c5f2cde43..1bae4479c3628 100644 --- a/comp/otelcol/converter/impl/go.sum +++ b/comp/otelcol/converter/impl/go.sum @@ -1,9 +1,90 @@ +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/alecthomas/participle/v2 v2.1.1 h1:hrjKESvSqGHzRb4yW1ciisFJ4p3MGYih6icjJvbsmV8= +github.com/alecthomas/participle/v2 v2.1.1/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c= +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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/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.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/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/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= 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/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= +github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +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= @@ -14,18 +95,115 @@ 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/lightstep/go-expohisto v1.0.0 h1:UPtTS1rGdtehbbAF7o/dhkWLTDI73UifG8LbfQI7cA4= +github.com/lightstep/go-expohisto v1.0.0/go.mod h1:xDXD0++Mu2FOaItXtdDfksfgxfV0z1TMPa+e/EUd0cs= +github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY= +github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= 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/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.104.0 h1:6dvpPt8pCcV+TfMnnanFk2NQYf9HN1voSS9iIHdW+L8= +github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.104.0/go.mod h1:MfSM6mt9qH3vHCaj2rlX6IY/7fN+zCLzNJC25XG9rNU= +github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.104.0 h1:SveJtKEP2pXyCbucjrDzbBGQUUgrU+vBMTyUgy0tplc= +github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.104.0/go.mod h1:HdVNjnRruSyRiqXvPBy/ZVumw7zjegmoJmFRgtBnaQU= +github.com/open-telemetry/opentelemetry-collector-contrib/extension/pprofextension v0.104.0 h1:dcs3PHXBShL5+DWmDrNXnESlehQjRjIaVE84GPyZL5E= +github.com/open-telemetry/opentelemetry-collector-contrib/extension/pprofextension v0.104.0/go.mod h1:Vh707OU/o72qqlDGS+8WVkMCTIlmiTfy3k6PQeq/tgY= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.104.0 h1:4ke4j/y7AQnRAyYveB+KGcdjVYEKVrwTxc3BDHagdd0= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.104.0/go.mod h1:I2zX9YBggIum9LAHXN1DqqbYOENrHXbXdkXouhwVCHw= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.104.0 h1:/koTWTWCFF7tBYkDX5UzCaEc/ceTU8jij/Yzuj0So3M= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.104.0/go.mod h1:KWVekIHTPScOrLKVYOiijxfEdGK5OBhD4EFNBh96ESg= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.104.0 h1:4dU16tXhXWUfOYHoDtpEJHYze1ltgMFWvD1jWVeARRI= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.104.0/go.mod h1:poM/ch3rxaWlkiGV3ohdEDALhfwx6jaKd1z7xk6iY0o= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/pdatautil v0.104.0 h1:dOPRk39L5bwQNbxJ7mSUyHan0un/r9DV9X7G+YrktGk= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/pdatautil v0.104.0/go.mod h1:nyUlZ88VgBDoA9SfmUs0RcsVzqts9z0PpLxjFZPjD3w= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.104.0 h1:4ES79GC+1fyDlLmC2ASM7MpKGLx1LIBpL8wE7G3zzSA= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.104.0/go.mod h1:h5v/Xn0jreStYi9nyPHjwfYseH8Xe3DznsUNS5R4Oqg= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.104.0 h1:Pl4rXXpRG/xJuNWUS3I/w1jViHcrssMf47bGX/Ug/KY= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.104.0/go.mod h1:tP4dyc5+g/qoXYb8lmNj+y+Nhphn4MkL23/np0Zhx2g= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.104.0 h1:Vwkk+0+cppH+TrmdiVFWcshhdvh2g2IZEj16V8SLjLw= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.104.0/go.mod h1:QmV2JbLC0lzzi0hMUKv5hJ824wdzvYInjVJsphQQ5Uo= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/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.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= 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.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= +github.com/rs/cors v1.11.0/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 v1.7.1 h1:UJcjSAI3aUKx52kfcfhblgyhZceouhvvs3OYdWgn+PY= +github.com/shoenig/test v1.7.1/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI= +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/tilinna/clock v1.1.0 h1:6IQQQCo6KoBxVudv6gwtY8o4eDfhHo8ojA5dP0MfhSs= +github.com/tilinna/clock v1.1.0/go.mod h1:ZsP7BcY7sEEz7ktc0IVy8Us6boDrK8VradlKRUGfOao= +github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= +github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= +github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= +github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= +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/confmap/converter/expandconverter v0.104.0 h1:7BhJk71V8xhm8wUpuHG4CVRAPu8JajKj8VmGZ6zS7SA= @@ -40,16 +218,181 @@ go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.104.0 h1:y07I19l go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.104.0/go.mod h1:WV1HOa0z3Ln5ZkwEW7Cm2pCHkfzYY9kBe0dLy8DqeYA= go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.104.0 h1:itBGhyEbX+iz8kz3nc4PYxQx4bL7y87xXNUcGnbKPuY= go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.104.0/go.mod h1:iPVsTBkRFHZ21UEfSGWk8c4maOzTp6BWWpTk+l6PjJI= +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/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/processor/batchprocessor v0.104.0 h1:6xXvHYkPjwM1zdzliDM2H/omTGgIOkY96JTCln7CFZQ= +go.opentelemetry.io/collector/processor/batchprocessor v0.104.0/go.mod h1:f1VfVdiOlqtJDAvQy8YONEee19nJ3haxNeiMPy59w8M= +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/receiver/nopreceiver v0.104.0 h1:xkfiTIGEXMXosYbZe8C8tIEZiw+gEL8QhCxz8slSYcM= +go.opentelemetry.io/collector/receiver/nopreceiver v0.104.0/go.mod h1:9vZPqdvOBDh9fKugWiv8WIINkF+TFpOw7RhvZxctZ9w= +go.opentelemetry.io/collector/receiver/otlpreceiver v0.104.0 h1:t9cACuSc7kY09guws7VyB/z9QnG7/zWLC1NQ29WH4+o= +go.opentelemetry.io/collector/receiver/otlpreceiver v0.104.0/go.mod h1:sPIIO4F6uit1i/XQgfe2WryvdO5Hr16bQgZTaXcR8mM= +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.1.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-20240624140628-dc46fd24d27d h1:Aqf0fiIdUQEj0Gn9mKFFXoQfTTEaNopWpfVyYADxiSg= +google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Od4k8V1LQSizPRUK4OzZ7TBE/20k+jPczUDAEyvn69Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +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.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +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/comp/otelcol/converter/impl/infraattributes.go b/comp/otelcol/converter/impl/infraattributes.go index 07da344099f8d..ad6cb0474e687 100644 --- a/comp/otelcol/converter/impl/infraattributes.go +++ b/comp/otelcol/converter/impl/infraattributes.go @@ -55,45 +55,51 @@ func addProcessorToPipelinesWithDDExporter(conf *confmap.Conf, comp component) { if !ok { return } + infraAttrsInPipeline := false + ddExporterInPipeline := false for _, exporter := range exportersSlice { exporterString, ok := exporter.(string) if !ok { return } - if componentName(exporterString) == "datadog" { - // datadog component is an exporter in this pipeline. Need to make sure that processor is also configured. - _, ok := componentsMap[comp.Type] - if !ok { - componentsMap[comp.Type] = []any{} - } + if infraAttrsInPipeline { + break + } + if componentName(exporterString) != "datadog" { + continue + } + ddExporterInPipeline = true + // datadog component is an exporter in this pipeline. Need to make sure that processor is also configured. + _, ok = componentsMap[comp.Type] + if !ok { + componentsMap[comp.Type] = []any{} + } - infraAttrsInPipeline := false - processorsSlice, ok := componentsMap[comp.Type].([]any) + processorsSlice, ok := componentsMap[comp.Type].([]any) + if !ok { + return + } + for _, processor := range processorsSlice { + processorString, ok := processor.(string) if !ok { return } - for _, processor := range processorsSlice { - processorString, ok := processor.(string) - if !ok { - return - } - if componentName(processorString) == comp.Name { - infraAttrsInPipeline = true - } - - } - if !infraAttrsInPipeline { - // no processors are defined - if !componentAddedToConfig { - addComponentToConfig(conf, comp) - componentAddedToConfig = true - } - addComponentToPipeline(conf, comp, pipelineName) + if componentName(processorString) == comp.Name { + infraAttrsInPipeline = true } + } } - } + if !infraAttrsInPipeline && ddExporterInPipeline { + // no processors are defined + if !componentAddedToConfig { + addComponentToConfig(conf, comp) + componentAddedToConfig = true + } + addComponentToPipeline(conf, comp, pipelineName) + } + } } diff --git a/comp/otelcol/converter/impl/testdata/connectors/already-set/config.yaml b/comp/otelcol/converter/impl/testdata/connectors/already-set/config.yaml new file mode 100644 index 0000000000000..143029b8cef5b --- /dev/null +++ b/comp/otelcol/converter/impl/testdata/connectors/already-set/config.yaml @@ -0,0 +1,45 @@ +receivers: + otlp: + prometheus/user-defined: + config: + scrape_configs: + - job_name: 'datadog-agent' + scrape_interval: 10s + static_configs: + - targets: ['0.0.0.0:8888'] + +exporters: + datadog: + api: + key: 12345 + +extensions: + pprof/user-defined: + health_check/user-defined: + zpages/user-defined: + endpoint: "localhost:55679" + ddflare/user-defined: + +processors: + infraattributes/user-defined: + +connectors: + datadog/conn: + traces: + span_name_as_resource_name: false + +service: + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] + pipelines: + traces: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog, datadog/conn] + metrics: + receivers: [nop, prometheus/user-defined, datadog/conn] + processors: [infraattributes/user-defined] + exporters: [datadog] + logs: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog] diff --git a/comp/otelcol/converter/impl/testdata/connectors/no-dd-connector/config.yaml b/comp/otelcol/converter/impl/testdata/connectors/no-dd-connector/config.yaml new file mode 100644 index 0000000000000..2a72d6336d491 --- /dev/null +++ b/comp/otelcol/converter/impl/testdata/connectors/no-dd-connector/config.yaml @@ -0,0 +1,43 @@ +receivers: + otlp: + prometheus/user-defined: + config: + scrape_configs: + - job_name: 'datadog-agent' + scrape_interval: 10s + static_configs: + - targets: ['0.0.0.0:8888'] + +exporters: + datadog: + api: + key: 12345 + +extensions: + pprof/user-defined: + health_check/user-defined: + zpages/user-defined: + endpoint: "localhost:55679" + ddflare/user-defined: + +processors: + infraattributes/user-defined: + +connectors: + nop/conn: + +service: + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] + pipelines: + traces: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog, nop/conn] + metrics: + receivers: [nop, prometheus/user-defined] + processors: [infraattributes/user-defined] + exporters: [datadog] + logs: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog] diff --git a/comp/otelcol/converter/impl/testdata/connectors/set-default/config-result.yaml b/comp/otelcol/converter/impl/testdata/connectors/set-default/config-result.yaml new file mode 100644 index 0000000000000..9c87aac4819d8 --- /dev/null +++ b/comp/otelcol/converter/impl/testdata/connectors/set-default/config-result.yaml @@ -0,0 +1,53 @@ +receivers: + otlp: + prometheus/user-defined: + config: + scrape_configs: + - job_name: 'datadog-agent' + scrape_interval: 10s + static_configs: + - targets: ['0.0.0.0:8888'] + +exporters: + datadog: + api: + key: 12345 + +extensions: + pprof/user-defined: + health_check/user-defined: + zpages/user-defined: + endpoint: "localhost:55679" + ddflare/user-defined: + +processors: + infraattributes/user-defined: + +connectors: + datadog/conn: + traces: + span_name_as_resource_name: true + datadog/conn-2: + traces: + span_name_as_resource_name: true + datadog/conn-3: + traces: + span_name_as_resource_name: true + span_name_remappings: + instrumentation:express.server: express + +service: + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] + pipelines: + traces: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog, datadog/conn] + metrics: + receivers: [nop, prometheus/user-defined, datadog/conn] + processors: [infraattributes/user-defined] + exporters: [datadog] + logs: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog] diff --git a/comp/otelcol/converter/impl/testdata/connectors/set-default/config.yaml b/comp/otelcol/converter/impl/testdata/connectors/set-default/config.yaml new file mode 100644 index 0000000000000..61e1a2a871c6a --- /dev/null +++ b/comp/otelcol/converter/impl/testdata/connectors/set-default/config.yaml @@ -0,0 +1,49 @@ +receivers: + otlp: + prometheus/user-defined: + config: + scrape_configs: + - job_name: 'datadog-agent' + scrape_interval: 10s + static_configs: + - targets: ['0.0.0.0:8888'] + +exporters: + datadog: + api: + key: 12345 + +extensions: + pprof/user-defined: + health_check/user-defined: + zpages/user-defined: + endpoint: "localhost:55679" + ddflare/user-defined: + +processors: + infraattributes/user-defined: + +connectors: + datadog/conn: + datadog/conn-2: + traces: + datadog/conn-3: + traces: + span_name_remappings: + instrumentation:express.server: express + +service: + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] + pipelines: + traces: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog, datadog/conn] + metrics: + receivers: [nop, prometheus/user-defined, datadog/conn] + processors: [infraattributes/user-defined] + exporters: [datadog] + logs: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog] diff --git a/comp/otelcol/converter/impl/testdata/extensions/no-changes/config.yaml b/comp/otelcol/converter/impl/testdata/extensions/no-changes/config.yaml index ee0f1ae690126..0e91a1c2c0bc3 100644 --- a/comp/otelcol/converter/impl/testdata/extensions/no-changes/config.yaml +++ b/comp/otelcol/converter/impl/testdata/extensions/no-changes/config.yaml @@ -1,26 +1,32 @@ receivers: - otlp: + otlp: exporters: - nop: + nop: extensions: pprof/user-defined: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: - + ddflare/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] - pipelines: - traces: - receivers: [nop] - exporters: [nop] - metrics: - receivers: [nop] - exporters: [nop] - logs: - receivers: [nop] - exporters: [nop] \ No newline at end of file + extensions: + [ + pprof/user-defined, + zpages/user-defined, + health_check/user-defined, + ddflare/user-defined, + ] + pipelines: + traces: + receivers: [nop] + exporters: [nop] + metrics: + receivers: [nop] + exporters: [nop] + logs: + receivers: [nop] + exporters: [nop] + diff --git a/comp/otelcol/converter/impl/testdata/extensions/no-extensions/config-result.yaml b/comp/otelcol/converter/impl/testdata/extensions/no-extensions/config-result.yaml index 3bbae4b0cc7b7..83095559c9dda 100644 --- a/comp/otelcol/converter/impl/testdata/extensions/no-extensions/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/extensions/no-extensions/config-result.yaml @@ -1,25 +1,32 @@ receivers: - otlp: + otlp: exporters: - nop: + nop: extensions: pprof/dd-autoconfigured: health_check/dd-autoconfigured: zpages/dd-autoconfigured: endpoint: "localhost:55679" - datadog/dd-autoconfigured: + ddflare/dd-autoconfigured: service: - extensions: [pprof/dd-autoconfigured, zpages/dd-autoconfigured, health_check/dd-autoconfigured, datadog/dd-autoconfigured] - pipelines: - traces: - receivers: [nop] - exporters: [nop] - metrics: - receivers: [nop] - exporters: [nop] - logs: - receivers: [nop] - exporters: [nop] \ No newline at end of file + extensions: + [ + pprof/dd-autoconfigured, + zpages/dd-autoconfigured, + health_check/dd-autoconfigured, + ddflare/dd-autoconfigured, + ] + pipelines: + traces: + receivers: [nop] + exporters: [nop] + metrics: + receivers: [nop] + exporters: [nop] + logs: + receivers: [nop] + exporters: [nop] + diff --git a/comp/otelcol/converter/impl/testdata/extensions/other-extensions/config-result.yaml b/comp/otelcol/converter/impl/testdata/extensions/other-extensions/config-result.yaml index 9bbce0b61f9ea..1fd7ea250ade1 100644 --- a/comp/otelcol/converter/impl/testdata/extensions/other-extensions/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/extensions/other-extensions/config-result.yaml @@ -1,8 +1,8 @@ receivers: - otlp: + otlp: exporters: - nop: + nop: extensions: otlp_encoding/user-defined: @@ -11,18 +11,25 @@ extensions: health_check/dd-autoconfigured: zpages/dd-autoconfigured: endpoint: "localhost:55679" - datadog/dd-autoconfigured: - + ddflare/dd-autoconfigured: service: - extensions: [otlp_encoding/user-defined, pprof/dd-autoconfigured, zpages/dd-autoconfigured, health_check/dd-autoconfigured, datadog/dd-autoconfigured] - pipelines: - traces: - receivers: [nop] - exporters: [nop] - metrics: - receivers: [nop] - exporters: [nop] - logs: - receivers: [nop] - exporters: [nop] \ No newline at end of file + extensions: + [ + otlp_encoding/user-defined, + pprof/dd-autoconfigured, + zpages/dd-autoconfigured, + health_check/dd-autoconfigured, + ddflare/dd-autoconfigured, + ] + pipelines: + traces: + receivers: [nop] + exporters: [nop] + metrics: + receivers: [nop] + exporters: [nop] + logs: + receivers: [nop] + exporters: [nop] + diff --git a/comp/otelcol/converter/impl/testdata/processors/dd-connector-multi-pipelines/config-result.yaml b/comp/otelcol/converter/impl/testdata/processors/dd-connector-multi-pipelines/config-result.yaml new file mode 100644 index 0000000000000..0a2999ceee9da --- /dev/null +++ b/comp/otelcol/converter/impl/testdata/processors/dd-connector-multi-pipelines/config-result.yaml @@ -0,0 +1,63 @@ +receivers: + prometheus: + config: + scrape_configs: + - job_name: "datadog-agent" + scrape_interval: 10s + static_configs: + - targets: ["0.0.0.0:8888"] + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 +exporters: + debug: + verbosity: detailed + datadog: + api: + key: "0000" +processors: + infraattributes/dd-autoconfigured: + batch: + timeout: 10s +connectors: + datadog/connector: + traces: + span_name_as_resource_name: true + compute_top_level_by_span_kind: true + peer_tags_aggregation: true + compute_stats_by_span_kind: true +extensions: + pprof/user-defined: + health_check/user-defined: + zpages/user-defined: + endpoint: "localhost:55679" + ddflare/user-defined: + +service: + extensions: + [ + pprof/user-defined, + zpages/user-defined, + health_check/user-defined, + ddflare/user-defined, + ] + pipelines: + traces: + receivers: [otlp] + processors: [batch, infraattributes/dd-autoconfigured] + exporters: [datadog] + traces/2: + receivers: [otlp] + processors: [batch, infraattributes/dd-autoconfigured] + exporters: [datadog/connector] + metrics: + receivers: [otlp, datadog/connector, prometheus] + processors: [batch, infraattributes/dd-autoconfigured] + exporters: [datadog] + logs: + receivers: [otlp] + processors: [batch, infraattributes/dd-autoconfigured] + exporters: [datadog] diff --git a/comp/otelcol/converter/impl/testdata/processors/dd-connector-multi-pipelines/config.yaml b/comp/otelcol/converter/impl/testdata/processors/dd-connector-multi-pipelines/config.yaml new file mode 100644 index 0000000000000..1ca43bb788867 --- /dev/null +++ b/comp/otelcol/converter/impl/testdata/processors/dd-connector-multi-pipelines/config.yaml @@ -0,0 +1,61 @@ +receivers: + prometheus: + config: + scrape_configs: + - job_name: "otelcol" + scrape_interval: 10s + static_configs: + - targets: ["0.0.0.0:8888"] + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 +exporters: + debug: + verbosity: detailed + datadog: + api: + key: "0000" +processors: + batch: + timeout: 10s +connectors: + datadog/connector: + traces: + compute_top_level_by_span_kind: true + peer_tags_aggregation: true + compute_stats_by_span_kind: true +extensions: + pprof/user-defined: + health_check/user-defined: + zpages/user-defined: + endpoint: "localhost:55679" + ddflare/user-defined: + +service: + extensions: + [ + pprof/user-defined, + zpages/user-defined, + health_check/user-defined, + ddflare/user-defined, + ] + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [datadog] + traces/2: + receivers: [otlp] + processors: [batch] + exporters: [datadog/connector] + metrics: + receivers: [otlp, datadog/connector, prometheus] + processors: [batch] + exporters: [datadog] + logs: + receivers: [otlp] + processors: [batch] + exporters: [datadog] diff --git a/comp/otelcol/converter/impl/testdata/processors/dd-connector/config-result.yaml b/comp/otelcol/converter/impl/testdata/processors/dd-connector/config-result.yaml new file mode 100644 index 0000000000000..f540128881e75 --- /dev/null +++ b/comp/otelcol/converter/impl/testdata/processors/dd-connector/config-result.yaml @@ -0,0 +1,59 @@ +receivers: + prometheus: + config: + scrape_configs: + - job_name: "datadog-agent" + scrape_interval: 10s + static_configs: + - targets: ["0.0.0.0:8888"] + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 +exporters: + debug: + verbosity: detailed + datadog: + api: + key: "0000" +processors: + infraattributes/dd-autoconfigured: + batch: + timeout: 10s +connectors: + datadog/connector: + traces: + span_name_as_resource_name: true + compute_top_level_by_span_kind: true + peer_tags_aggregation: true + compute_stats_by_span_kind: true +extensions: + pprof/user-defined: + health_check/user-defined: + zpages/user-defined: + endpoint: "localhost:55679" + ddflare/user-defined: + +service: + extensions: + [ + pprof/user-defined, + zpages/user-defined, + health_check/user-defined, + ddflare/user-defined, + ] + pipelines: + traces: + receivers: [otlp] + processors: [batch, infraattributes/dd-autoconfigured] + exporters: [datadog/connector, datadog] + metrics: + receivers: [otlp, datadog/connector, prometheus] + processors: [batch, infraattributes/dd-autoconfigured] + exporters: [datadog] + logs: + receivers: [otlp] + processors: [batch, infraattributes/dd-autoconfigured] + exporters: [datadog] diff --git a/comp/otelcol/converter/impl/testdata/processors/dd-connector/config.yaml b/comp/otelcol/converter/impl/testdata/processors/dd-connector/config.yaml new file mode 100644 index 0000000000000..70d4ee4f34c52 --- /dev/null +++ b/comp/otelcol/converter/impl/testdata/processors/dd-connector/config.yaml @@ -0,0 +1,57 @@ +receivers: + prometheus: + config: + scrape_configs: + - job_name: "otelcol" + scrape_interval: 10s + static_configs: + - targets: ["0.0.0.0:8888"] + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 +exporters: + debug: + verbosity: detailed + datadog: + api: + key: "0000" +processors: + batch: + timeout: 10s +connectors: + datadog/connector: + traces: + compute_top_level_by_span_kind: true + peer_tags_aggregation: true + compute_stats_by_span_kind: true +extensions: + pprof/user-defined: + health_check/user-defined: + zpages/user-defined: + endpoint: "localhost:55679" + ddflare/user-defined: + +service: + extensions: + [ + pprof/user-defined, + zpages/user-defined, + health_check/user-defined, + ddflare/user-defined, + ] + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [datadog/connector, datadog] + metrics: + receivers: [otlp, datadog/connector, prometheus] + processors: [batch] + exporters: [datadog] + logs: + receivers: [otlp] + processors: [batch] + exporters: [datadog] diff --git a/comp/otelcol/converter/impl/testdata/processors/no-changes/config.yaml b/comp/otelcol/converter/impl/testdata/processors/no-changes/config.yaml index 5bbfe3beb7fca..756f84e487050 100644 --- a/comp/otelcol/converter/impl/testdata/processors/no-changes/config.yaml +++ b/comp/otelcol/converter/impl/testdata/processors/no-changes/config.yaml @@ -18,13 +18,13 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/processors/no-processor-partial/config-result.yaml b/comp/otelcol/converter/impl/testdata/processors/no-processor-partial/config-result.yaml index bb6a071a5057e..697c77659af90 100644 --- a/comp/otelcol/converter/impl/testdata/processors/no-processor-partial/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/processors/no-processor-partial/config-result.yaml @@ -23,10 +23,10 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/processors/no-processor-partial/config.yaml b/comp/otelcol/converter/impl/testdata/processors/no-processor-partial/config.yaml index c101e0de68ab0..4e82649cac147 100644 --- a/comp/otelcol/converter/impl/testdata/processors/no-processor-partial/config.yaml +++ b/comp/otelcol/converter/impl/testdata/processors/no-processor-partial/config.yaml @@ -22,10 +22,10 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/processors/no-processors/config-result.yaml b/comp/otelcol/converter/impl/testdata/processors/no-processors/config-result.yaml index 456b767205842..6da189e4a2256 100644 --- a/comp/otelcol/converter/impl/testdata/processors/no-processors/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/processors/no-processors/config-result.yaml @@ -18,13 +18,13 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/dd-autoconfigured: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/processors/no-processors/config.yaml b/comp/otelcol/converter/impl/testdata/processors/no-processors/config.yaml index bc52407015b1c..e024121c05626 100644 --- a/comp/otelcol/converter/impl/testdata/processors/no-processors/config.yaml +++ b/comp/otelcol/converter/impl/testdata/processors/no-processors/config.yaml @@ -18,10 +18,10 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/processors/other-processors/config-result.yaml b/comp/otelcol/converter/impl/testdata/processors/other-processors/config-result.yaml index ccf2c06ed1bc7..e84cc09f734ce 100644 --- a/comp/otelcol/converter/impl/testdata/processors/other-processors/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/processors/other-processors/config-result.yaml @@ -18,14 +18,14 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/dd-autoconfigured: k8sattributes: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/processors/other-processors/config.yaml b/comp/otelcol/converter/impl/testdata/processors/other-processors/config.yaml index 03e8e147b6aef..de77e594c7f8f 100644 --- a/comp/otelcol/converter/impl/testdata/processors/other-processors/config.yaml +++ b/comp/otelcol/converter/impl/testdata/processors/other-processors/config.yaml @@ -21,10 +21,10 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/receivers/job-name-change/config-result.yaml b/comp/otelcol/converter/impl/testdata/receivers/job-name-change/config-result.yaml index 9b2beefe39020..3fff816644e2d 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/job-name-change/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/job-name-change/config-result.yaml @@ -1,40 +1,46 @@ receivers: - otlp: - prometheus/user-defined: - config: - scrape_configs: - - job_name: 'datadog-agent' - scrape_interval: 10s - static_configs: - - targets: ['0.0.0.0:8888'] + otlp: + prometheus/user-defined: + config: + scrape_configs: + - job_name: "datadog-agent" + scrape_interval: 10s + static_configs: + - targets: ["0.0.0.0:8888"] exporters: - datadog: - api: - key: 12345 + datadog: + api: + key: 12345 extensions: pprof/user-defined: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: - + ddflare/user-defined: + processors: infraattributes/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] - pipelines: - traces: - receivers: [nop] - processors: [infraattributes/user-defined] - exporters: [datadog] - metrics: - receivers: [nop, prometheus/user-defined] - processors: [infraattributes/user-defined] - exporters: [datadog] - logs: - receivers: [nop] - processors: [infraattributes/user-defined] - exporters: [datadog] + extensions: + [ + pprof/user-defined, + zpages/user-defined, + health_check/user-defined, + ddflare/user-defined, + ] + pipelines: + traces: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog] + metrics: + receivers: [nop, prometheus/user-defined] + processors: [infraattributes/user-defined] + exporters: [datadog] + logs: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog] diff --git a/comp/otelcol/converter/impl/testdata/receivers/job-name-change/config.yaml b/comp/otelcol/converter/impl/testdata/receivers/job-name-change/config.yaml index 28666713c70b7..47e9b4f58463c 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/job-name-change/config.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/job-name-change/config.yaml @@ -1,40 +1,46 @@ receivers: - otlp: - prometheus/user-defined: - config: - scrape_configs: - - job_name: 'otelcol' - scrape_interval: 10s - static_configs: - - targets: ['0.0.0.0:8888'] + otlp: + prometheus/user-defined: + config: + scrape_configs: + - job_name: "otelcol" + scrape_interval: 10s + static_configs: + - targets: ["0.0.0.0:8888"] exporters: - datadog: - api: - key: 12345 + datadog: + api: + key: 12345 extensions: pprof/user-defined: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: - + ddflare/user-defined: + processors: infraattributes/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] - pipelines: - traces: - receivers: [nop] - processors: [infraattributes/user-defined] - exporters: [datadog] - metrics: - receivers: [nop, prometheus/user-defined] - processors: [infraattributes/user-defined] - exporters: [datadog] - logs: - receivers: [nop] - processors: [infraattributes/user-defined] - exporters: [datadog] + extensions: + [ + pprof/user-defined, + zpages/user-defined, + health_check/user-defined, + ddflare/user-defined, + ] + pipelines: + traces: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog] + metrics: + receivers: [nop, prometheus/user-defined] + processors: [infraattributes/user-defined] + exporters: [datadog] + logs: + receivers: [nop] + processors: [infraattributes/user-defined] + exporters: [datadog] diff --git a/comp/otelcol/converter/impl/testdata/receivers/multi-dd-partial-prom/config-result.yaml b/comp/otelcol/converter/impl/testdata/receivers/multi-dd-partial-prom/config-result.yaml index 71fe27339ea3a..baf1856351220 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/multi-dd-partial-prom/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/multi-dd-partial-prom/config-result.yaml @@ -31,7 +31,7 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: @@ -40,7 +40,7 @@ service: telemetry: metrics: address: "localhost:1234" - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/receivers/multi-dd-partial-prom/config.yaml b/comp/otelcol/converter/impl/testdata/receivers/multi-dd-partial-prom/config.yaml index e7ad53fde07c7..51b90562c7f44 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/multi-dd-partial-prom/config.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/multi-dd-partial-prom/config.yaml @@ -24,7 +24,7 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: @@ -33,7 +33,7 @@ service: telemetry: metrics: address: "localhost:1234" - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/receivers/no-changes/config.yaml b/comp/otelcol/converter/impl/testdata/receivers/no-changes/config.yaml index 9b2beefe39020..3d814075872f2 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/no-changes/config.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/no-changes/config.yaml @@ -18,13 +18,13 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/receivers/no-prom-multi-dd/config-result.yaml b/comp/otelcol/converter/impl/testdata/receivers/no-prom-multi-dd/config-result.yaml index d5f0dcf5b4906..a31a1402f3500 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/no-prom-multi-dd/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/no-prom-multi-dd/config-result.yaml @@ -21,13 +21,13 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/receivers/no-prom-multi-dd/config.yaml b/comp/otelcol/converter/impl/testdata/receivers/no-prom-multi-dd/config.yaml index 6ef059da19e6c..d0a052ac1e521 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/no-prom-multi-dd/config.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/no-prom-multi-dd/config.yaml @@ -14,13 +14,13 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/receivers/no-prom-not-default-addr/config-result.yaml b/comp/otelcol/converter/impl/testdata/receivers/no-prom-not-default-addr/config-result.yaml index b5391b16abc70..7a6cd6cf2558d 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/no-prom-not-default-addr/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/no-prom-not-default-addr/config-result.yaml @@ -18,7 +18,7 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: @@ -27,7 +27,7 @@ service: telemetry: metrics: address: "localhost:1234" - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/receivers/no-prom-not-default-addr/config.yaml b/comp/otelcol/converter/impl/testdata/receivers/no-prom-not-default-addr/config.yaml index a7e3fdeb00d50..9da2bedafb8bc 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/no-prom-not-default-addr/config.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/no-prom-not-default-addr/config.yaml @@ -11,7 +11,7 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: @@ -20,7 +20,7 @@ service: telemetry: metrics: address: "localhost:1234" - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/receivers/no-prometheus-receiver/config-result.yaml b/comp/otelcol/converter/impl/testdata/receivers/no-prometheus-receiver/config-result.yaml index ff42c6b03ee36..203185d2272ff 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/no-prometheus-receiver/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/no-prometheus-receiver/config-result.yaml @@ -18,13 +18,13 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/receivers/no-prometheus-receiver/config.yaml b/comp/otelcol/converter/impl/testdata/receivers/no-prometheus-receiver/config.yaml index 4300ce740dde3..07452dca0f605 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/no-prometheus-receiver/config.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/no-prometheus-receiver/config.yaml @@ -11,13 +11,13 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: receivers: [nop] diff --git a/comp/otelcol/converter/impl/testdata/receivers/no-receivers-defined/config-result.yaml b/comp/otelcol/converter/impl/testdata/receivers/no-receivers-defined/config-result.yaml index 075a05ae3898c..39e6cb511c45f 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/no-receivers-defined/config-result.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/no-receivers-defined/config-result.yaml @@ -17,13 +17,13 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: processors: [infraattributes/user-defined] diff --git a/comp/otelcol/converter/impl/testdata/receivers/no-receivers-defined/config.yaml b/comp/otelcol/converter/impl/testdata/receivers/no-receivers-defined/config.yaml index 3915568853a25..9a1ec2e6c0fa9 100644 --- a/comp/otelcol/converter/impl/testdata/receivers/no-receivers-defined/config.yaml +++ b/comp/otelcol/converter/impl/testdata/receivers/no-receivers-defined/config.yaml @@ -8,13 +8,13 @@ extensions: health_check/user-defined: zpages/user-defined: endpoint: "localhost:55679" - datadog/user-defined: + ddflare/user-defined: processors: infraattributes/user-defined: service: - extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, datadog/user-defined] + extensions: [pprof/user-defined, zpages/user-defined, health_check/user-defined, ddflare/user-defined] pipelines: traces: processors: [infraattributes/user-defined] diff --git a/comp/otelcol/extension/def/component.go b/comp/otelcol/ddflareextension/def/component.go similarity index 84% rename from comp/otelcol/extension/def/component.go rename to comp/otelcol/ddflareextension/def/component.go index b2297e0adaf47..e49d6bf0392d0 100644 --- a/comp/otelcol/extension/def/component.go +++ b/comp/otelcol/ddflareextension/def/component.go @@ -3,8 +3,8 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -// Package extension defines the OpenTelemetry Extension component. -package extension +// Package ddflareextension defines the OpenTelemetry Extension component. +package ddflareextension import ( "net/http" diff --git a/comp/otelcol/extension/def/go.mod b/comp/otelcol/ddflareextension/def/go.mod similarity index 87% rename from comp/otelcol/extension/def/go.mod rename to comp/otelcol/ddflareextension/def/go.mod index e8df495a91dba..3d3a4aec795e7 100644 --- a/comp/otelcol/extension/def/go.mod +++ b/comp/otelcol/ddflareextension/def/go.mod @@ -1,4 +1,4 @@ -module github.com/DataDog/datadog-agent/comp/otelcol/extension/def +module github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def go 1.22.0 @@ -23,9 +23,9 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // 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 google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect google.golang.org/grpc v1.64.0 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/comp/otelcol/extension/def/go.sum b/comp/otelcol/ddflareextension/def/go.sum similarity index 96% rename from comp/otelcol/extension/def/go.sum rename to comp/otelcol/ddflareextension/def/go.sum index b617dd0b120b1..8ca7d6059a157 100644 --- a/comp/otelcol/extension/def/go.sum +++ b/comp/otelcol/ddflareextension/def/go.sum @@ -87,20 +87,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn 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.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/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-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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= diff --git a/comp/otelcol/extension/def/types.go b/comp/otelcol/ddflareextension/def/types.go similarity index 93% rename from comp/otelcol/extension/def/types.go rename to comp/otelcol/ddflareextension/def/types.go index b4529253d0e87..9651e85476920 100644 --- a/comp/otelcol/extension/def/types.go +++ b/comp/otelcol/ddflareextension/def/types.go @@ -3,8 +3,8 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package extension defines the OpenTelemetry Extension component. -package extension +// Package ddflareextension defines the OpenTelemetry Extension component. +package ddflareextension // BuildInfoResponse is the response struct for BuildInfo type BuildInfoResponse struct { diff --git a/comp/otelcol/extension/fx/fx.go b/comp/otelcol/ddflareextension/fx/fx.go similarity index 67% rename from comp/otelcol/extension/fx/fx.go rename to comp/otelcol/ddflareextension/fx/fx.go index 28578667a9a35..3219a81b43d83 100644 --- a/comp/otelcol/extension/fx/fx.go +++ b/comp/otelcol/ddflareextension/fx/fx.go @@ -3,12 +3,12 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package extensionfx provides fx access for the provider component -package extensionfx +// Package ddflareextensionfx provides fx access for the provider component +package ddflareextensionfx import ( - extension "github.com/DataDog/datadog-agent/comp/otelcol/extension/def" - extensionimpl "github.com/DataDog/datadog-agent/comp/otelcol/extension/impl" + extension "github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def" + extensionimpl "github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl" "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) diff --git a/comp/otelcol/extension/impl/config.go b/comp/otelcol/ddflareextension/impl/config.go similarity index 95% rename from comp/otelcol/extension/impl/config.go rename to comp/otelcol/ddflareextension/impl/config.go index 23267fa5874af..46940561d4dc8 100644 --- a/comp/otelcol/extension/impl/config.go +++ b/comp/otelcol/ddflareextension/impl/config.go @@ -3,8 +3,8 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package extensionimpl defines the OpenTelemetry Extension implementation. -package extensionimpl +// Package ddflareextensionimpl defines the OpenTelemetry Extension implementation. +package ddflareextensionimpl import ( "errors" diff --git a/comp/otelcol/extension/impl/config_test.go b/comp/otelcol/ddflareextension/impl/config_test.go similarity index 94% rename from comp/otelcol/extension/impl/config_test.go rename to comp/otelcol/ddflareextension/impl/config_test.go index 018efae699f5a..1c1aa99056858 100644 --- a/comp/otelcol/extension/impl/config_test.go +++ b/comp/otelcol/ddflareextension/impl/config_test.go @@ -3,8 +3,8 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package extensionimpl defines the OpenTelemetry Extension implementation. -package extensionimpl +// Package ddflareextensionimpl defines the OpenTelemetry Extension implementation. +package ddflareextensionimpl import ( "testing" diff --git a/comp/otelcol/extension/impl/extension.go b/comp/otelcol/ddflareextension/impl/extension.go similarity index 91% rename from comp/otelcol/extension/impl/extension.go rename to comp/otelcol/ddflareextension/impl/extension.go index 83fdd827b51e1..94be1c0915380 100644 --- a/comp/otelcol/extension/impl/extension.go +++ b/comp/otelcol/ddflareextension/impl/extension.go @@ -3,8 +3,8 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package extensionimpl defines the OpenTelemetry Extension implementation. -package extensionimpl +// Package ddflareextensionimpl defines the OpenTelemetry Extension implementation. +package ddflareextensionimpl import ( "context" @@ -17,8 +17,8 @@ import ( "go.opentelemetry.io/collector/extension" "go.uber.org/zap" - extensionDef "github.com/DataDog/datadog-agent/comp/otelcol/extension/def" - "github.com/DataDog/datadog-agent/comp/otelcol/extension/impl/internal/metadata" + extensionDef "github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def" + "github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl/internal/metadata" ) // Type exports the internal metadata type for easy reference @@ -64,7 +64,7 @@ func (ext *ddExtension) Start(_ context.Context, host component.Host) error { // List configured Extensions configstore := ext.cfg.ConfigStore - c, err := configstore.GetProvidedConf() + c, err := configstore.GetEnhancedConf() if err != nil { return err } @@ -76,7 +76,7 @@ func (ext *ddExtension) Start(_ context.Context, host component.Host) error { extensions := host.GetExtensions() for extension := range extensions { - extractor, ok := supportedDebugExtensions[extension.String()] + extractor, ok := supportedDebugExtensions[extension.Type().String()] if !ok { continue } diff --git a/comp/otelcol/ddflareextension/impl/extension_test.go b/comp/otelcol/ddflareextension/impl/extension_test.go new file mode 100644 index 0000000000000..f1bd7dd398407 --- /dev/null +++ b/comp/otelcol/ddflareextension/impl/extension_test.go @@ -0,0 +1,204 @@ +// 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 2024-present Datadog, Inc. + +// Package ddflareextensionimpl defines the OpenTelemetry Extension implementation. +package ddflareextensionimpl + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "path/filepath" + "testing" + + ddflareextension "github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + configstore "github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl" + spanmetricsconnector "github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector" + healthcheckextension "github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension" + pprofextension "github.com/open-telemetry/opentelemetry-collector-contrib/extension/pprofextension" + transformprocessor "github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/provider/fileprovider" + "go.opentelemetry.io/collector/confmap/provider/yamlprovider" + "go.opentelemetry.io/collector/connector" + "go.opentelemetry.io/collector/exporter" + otlpexporter "go.opentelemetry.io/collector/exporter/otlpexporter" + otlphttpexporter "go.opentelemetry.io/collector/exporter/otlphttpexporter" + "go.opentelemetry.io/collector/extension" + "go.opentelemetry.io/collector/otelcol" + "go.opentelemetry.io/collector/processor" + batchprocessor "go.opentelemetry.io/collector/processor/batchprocessor" + "go.opentelemetry.io/collector/receiver" + nopreceiver "go.opentelemetry.io/collector/receiver/nopreceiver" + otlpreceiver "go.opentelemetry.io/collector/receiver/otlpreceiver" + "go.uber.org/zap" +) + +var cpSettings = otelcol.ConfigProviderSettings{ + ResolverSettings: confmap.ResolverSettings{ + URIs: []string{filepath.Join("testdata", "config.yaml")}, + ProviderFactories: []confmap.ProviderFactory{ + fileprovider.NewFactory(), + yamlprovider.NewFactory(), + }, + }, +} + +func components() (otelcol.Factories, error) { + var err error + factories := otelcol.Factories{} + + factories.Extensions, err = extension.MakeFactoryMap( + healthcheckextension.NewFactory(), + pprofextension.NewFactory(), + ) + if err != nil { + return otelcol.Factories{}, err + } + + factories.Receivers, err = receiver.MakeFactoryMap( + nopreceiver.NewFactory(), + otlpreceiver.NewFactory(), + ) + if err != nil { + return otelcol.Factories{}, err + } + + factories.Exporters, err = exporter.MakeFactoryMap( + otlpexporter.NewFactory(), + otlphttpexporter.NewFactory(), + ) + if err != nil { + return otelcol.Factories{}, err + } + + factories.Processors, err = processor.MakeFactoryMap( + batchprocessor.NewFactory(), + transformprocessor.NewFactory(), + ) + if err != nil { + return otelcol.Factories{}, err + } + + factories.Connectors, err = connector.MakeFactoryMap( + spanmetricsconnector.NewFactory(), + ) + if err != nil { + return otelcol.Factories{}, err + } + + return factories, nil +} + +func getExtensionTestConfig(t *testing.T) *Config { + cf, err := configstore.NewConfigStore() + assert.NoError(t, err) + + factories, err := components() + assert.NoError(t, err) + + cf.AddConfigs(cpSettings, cpSettings, factories) + return &Config{ + HTTPConfig: &confighttp.ServerConfig{ + Endpoint: "localhost:0", + }, + ConfigStore: cf, + } +} + +func getTestExtension(t *testing.T) (ddflareextension.Component, error) { + c := context.Background() + telemetry := component.TelemetrySettings{} + info := component.NewDefaultBuildInfo() + cfg := getExtensionTestConfig(t) + + return NewExtension(c, cfg, telemetry, info) +} + +func TestNewExtension(t *testing.T) { + ext, err := getTestExtension(t) + assert.NoError(t, err) + assert.NotNil(t, ext) + + _, ok := ext.(*ddExtension) + assert.True(t, ok) +} + +func TestExtensionHTTPHandler(t *testing.T) { + // Create a request + req, err := http.NewRequest("GET", "/", nil) + if err != nil { + t.Fatal(err) + } + + // Create a ResponseRecorder + rr := httptest.NewRecorder() + + // Create an instance of your handler + ext, err := getTestExtension(t) + require.NoError(t, err) + + ddExt := ext.(*ddExtension) + ddExt.telemetry.Logger = zap.New(zap.NewNop().Core()) + + host := newHostWithExtensions( + map[component.ID]component.Component{ + component.MustNewIDWithName("pprof", "custom"): nil, + }, + ) + + ddExt.Start(context.TODO(), host) + + // Call the handler's ServeHTTP method + ddExt.ServeHTTP(rr, req) + + // Check the response status code + assert.Equalf(t, http.StatusOK, rr.Code, + "handler returned wrong status code: got %v want %v", rr.Code, http.StatusOK) + + // Check the response body + expectedKeys := []string{ + "version", + "command", + "description", + "extension_version", + "provided_configuration", + "full_configuration", + "runtime_override_configuration", + "environment_variable_configuration", + "environment", + "sources", + } + var response map[string]interface{} + json.Unmarshal(rr.Body.Bytes(), &response) + + for _, key := range expectedKeys { + _, ok := response[key] + assert.True(t, ok) + } +} + +type hostWithExtensions struct { + component.Host + exts map[component.ID]component.Component +} + +func newHostWithExtensions(exts map[component.ID]component.Component) component.Host { + return &hostWithExtensions{ + Host: componenttest.NewNopHost(), + exts: exts, + } +} + +func (h *hostWithExtensions) GetExtensions() map[component.ID]component.Component { + return h.exts +} diff --git a/comp/otelcol/extension/impl/factory.go b/comp/otelcol/ddflareextension/impl/factory.go similarity index 88% rename from comp/otelcol/extension/impl/factory.go rename to comp/otelcol/ddflareextension/impl/factory.go index 35e448805c639..eb6967ebaed44 100644 --- a/comp/otelcol/extension/impl/factory.go +++ b/comp/otelcol/ddflareextension/impl/factory.go @@ -3,15 +3,15 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package extensionimpl defines the OpenTelemetry Extension implementation. -package extensionimpl +// Package ddflareextensionimpl defines the OpenTelemetry Extension implementation. +package ddflareextensionimpl import ( "context" "fmt" configstore "github.com/DataDog/datadog-agent/comp/otelcol/configstore/def" - "github.com/DataDog/datadog-agent/comp/otelcol/extension/impl/internal/metadata" + "github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl/internal/metadata" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/confighttp" "go.opentelemetry.io/collector/extension" diff --git a/comp/otelcol/extension/impl/factory_test.go b/comp/otelcol/ddflareextension/impl/factory_test.go similarity index 87% rename from comp/otelcol/extension/impl/factory_test.go rename to comp/otelcol/ddflareextension/impl/factory_test.go index cd4802a4ef98a..16ae62a1cd8c5 100644 --- a/comp/otelcol/extension/impl/factory_test.go +++ b/comp/otelcol/ddflareextension/impl/factory_test.go @@ -3,15 +3,15 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package extensionimpl defines the OpenTelemetry Extension implementation. -package extensionimpl +// Package ddflareextensionimpl defines the OpenTelemetry Extension implementation. +package ddflareextensionimpl import ( "context" "testing" configstore "github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl" - "github.com/DataDog/datadog-agent/comp/otelcol/extension/impl/internal/metadata" + "github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl/internal/metadata" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/extension" diff --git a/comp/otelcol/ddflareextension/impl/go.mod b/comp/otelcol/ddflareextension/impl/go.mod new file mode 100644 index 0000000000000..eba0f9a9e9570 --- /dev/null +++ b/comp/otelcol/ddflareextension/impl/go.mod @@ -0,0 +1,202 @@ +module github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl + +go 1.22.0 + +replace ( + github.com/DataDog/datadog-agent/comp/core/config => ../../../core/config + github.com/DataDog/datadog-agent/comp/core/flare/builder => ../../../core/flare/builder + github.com/DataDog/datadog-agent/comp/core/flare/types => ../../../core/flare/types + github.com/DataDog/datadog-agent/comp/core/hostname/hostnameinterface => ../../../core/hostname/hostnameinterface + github.com/DataDog/datadog-agent/comp/core/log/def => ../../../core/log/def + github.com/DataDog/datadog-agent/comp/core/secrets => ../../../core/secrets + github.com/DataDog/datadog-agent/comp/core/telemetry => ../../../core/telemetry + github.com/DataDog/datadog-agent/comp/def => ../../../def + github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../logs/agent/config + github.com/DataDog/datadog-agent/comp/otelcol/configstore/def => ../../configstore/def + github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl => ../../configstore/impl + github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def => ../../ddflareextension/def + github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline => ../../logsagentpipeline + github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline/logsagentpipelineimpl => ../../logsagentpipeline/logsagentpipelineimpl + github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/exporter/logsagentexporter => ../../otlp/components/exporter/logsagentexporter + github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/metricsclient => ../../otlp/components/metricsclient + github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/statsprocessor => ../../otlp/components/statsprocessor + github.com/DataDog/datadog-agent/comp/trace/compression/def => ../../../trace/compression/def + github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip => ../../../trace/compression/impl-gzip + github.com/DataDog/datadog-agent/comp/trace/compression/impl-zstd => ../../../trace/compression/impl-zstd + github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../../pkg/collector/check/defaults + github.com/DataDog/datadog-agent/pkg/config/env => ../../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/model => ../../../../pkg/config/model + github.com/DataDog/datadog-agent/pkg/config/setup => ../../../../pkg/config/setup + github.com/DataDog/datadog-agent/pkg/config/utils => ../../../../pkg/config/utils + github.com/DataDog/datadog-agent/pkg/logs/auditor => ../../../../pkg/logs/auditor + github.com/DataDog/datadog-agent/pkg/logs/client => ../../../../pkg/logs/client + github.com/DataDog/datadog-agent/pkg/logs/diagnostic => ../../../../pkg/logs/diagnostic + github.com/DataDog/datadog-agent/pkg/logs/message => ../../../../pkg/logs/message + github.com/DataDog/datadog-agent/pkg/logs/metrics => ../../../../pkg/logs/metrics + github.com/DataDog/datadog-agent/pkg/logs/pipeline => ../../../../pkg/logs/pipeline + github.com/DataDog/datadog-agent/pkg/logs/processor => ../../../../pkg/logs/processor + github.com/DataDog/datadog-agent/pkg/logs/sds => ../../../../pkg/logs/sds + github.com/DataDog/datadog-agent/pkg/logs/sender => ../../../../pkg/logs/sender + github.com/DataDog/datadog-agent/pkg/logs/sources => ../../../../pkg/logs/sources + github.com/DataDog/datadog-agent/pkg/logs/status/statusinterface => ../../../../pkg/logs/status/statusinterface + github.com/DataDog/datadog-agent/pkg/logs/status/utils => ../../../../pkg/logs/status/utils + github.com/DataDog/datadog-agent/pkg/obfuscate => ../../../../pkg/obfuscate + github.com/DataDog/datadog-agent/pkg/proto => ../../../../pkg/proto + github.com/DataDog/datadog-agent/pkg/remoteconfig/state => ../../../../pkg/remoteconfig/state + github.com/DataDog/datadog-agent/pkg/status/health => ../../../../pkg/status/health + github.com/DataDog/datadog-agent/pkg/telemetry => ../../../../pkg/telemetry + github.com/DataDog/datadog-agent/pkg/trace => ../../../../pkg/trace + github.com/DataDog/datadog-agent/pkg/util/backoff => ../../../../pkg/util/backoff + github.com/DataDog/datadog-agent/pkg/util/cgroups => ../../../../pkg/util/cgroups + github.com/DataDog/datadog-agent/pkg/util/executable => ../../../../pkg/util/executable + github.com/DataDog/datadog-agent/pkg/util/filesystem => ../../../../pkg/util/filesystem + github.com/DataDog/datadog-agent/pkg/util/fxutil => ../../../../pkg/util/fxutil + github.com/DataDog/datadog-agent/pkg/util/hostname/validate => ../../../../pkg/util/hostname/validate + github.com/DataDog/datadog-agent/pkg/util/http => ../../../../pkg/util/http + github.com/DataDog/datadog-agent/pkg/util/log => ../../../../pkg/util/log + github.com/DataDog/datadog-agent/pkg/util/optional => ../../../../pkg/util/optional + github.com/DataDog/datadog-agent/pkg/util/pointer => ../../../../pkg/util/pointer + github.com/DataDog/datadog-agent/pkg/util/scrubber => ../../../../pkg/util/scrubber + github.com/DataDog/datadog-agent/pkg/util/startstop => ../../../../pkg/util/startstop + github.com/DataDog/datadog-agent/pkg/util/statstracker => ../../../../pkg/util/statstracker + github.com/DataDog/datadog-agent/pkg/util/system => ../../../../pkg/util/system + github.com/DataDog/datadog-agent/pkg/util/system/socket => ../../../../pkg/util/system/socket + github.com/DataDog/datadog-agent/pkg/util/winutil => ../../../../pkg/util/winutil + github.com/DataDog/datadog-agent/pkg/version => ../../../../pkg/version +) + +require ( + github.com/DataDog/datadog-agent/comp/otelcol/configstore/def v0.56.0-rc.3 + github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl v0.56.0-rc.3 + github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def v0.0.0-00010101000000-000000000000 + github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.104.0 + github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.104.0 + github.com/open-telemetry/opentelemetry-collector-contrib/extension/pprofextension v0.104.0 + github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.104.0 + github.com/stretchr/testify v1.9.0 + go.opentelemetry.io/collector/component v0.104.0 + go.opentelemetry.io/collector/config/confighttp v0.104.0 + go.opentelemetry.io/collector/confmap v0.104.0 + go.opentelemetry.io/collector/confmap/provider/fileprovider v0.104.0 + go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.104.0 + go.opentelemetry.io/collector/connector v0.104.0 + go.opentelemetry.io/collector/exporter 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/processor v0.104.0 + go.opentelemetry.io/collector/processor/batchprocessor v0.104.0 + go.opentelemetry.io/collector/receiver v0.104.0 + go.opentelemetry.io/collector/receiver/nopreceiver v0.104.0 + go.opentelemetry.io/collector/receiver/otlpreceiver v0.104.0 + go.uber.org/zap v1.27.0 + +) + +require ( + github.com/alecthomas/participle/v2 v2.1.1 // indirect + 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect + github.com/gobwas/glob v0.2.3 // 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/hashicorp/golang-lru v1.0.2 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/iancoleman/strcase v0.3.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/lightstep/go-expohisto v1.0.0 // indirect + github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // 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/open-telemetry/opentelemetry-collector-contrib/internal/common v0.104.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.104.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.104.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/pdatautil v0.104.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.104.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.104.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // 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.1 // indirect + github.com/rs/cors v1.11.0 // indirect + github.com/shirou/gopsutil/v4 v4.24.5 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/shoenig/test v1.7.1 // indirect + github.com/spf13/cobra v1.8.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/tilinna/clock v1.1.0 // indirect + github.com/tklauser/go-sysconf v0.3.14 // indirect + github.com/tklauser/numcpus v0.8.0 // 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/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/consumer 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/pdata 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 + go.uber.org/multierr v1.11.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-20240624140628-dc46fd24d27d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // indirect + google.golang.org/grpc v1.64.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/comp/otelcol/ddflareextension/impl/go.sum b/comp/otelcol/ddflareextension/impl/go.sum new file mode 100644 index 0000000000000..8abd0addada8f --- /dev/null +++ b/comp/otelcol/ddflareextension/impl/go.sum @@ -0,0 +1,400 @@ +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/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0= +github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= +github.com/alecthomas/participle/v2 v2.1.1 h1:hrjKESvSqGHzRb4yW1ciisFJ4p3MGYih6icjJvbsmV8= +github.com/alecthomas/participle/v2 v2.1.1/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c= +github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= +github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/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.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/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/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +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/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +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.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= +github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +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/lightstep/go-expohisto v1.0.0 h1:UPtTS1rGdtehbbAF7o/dhkWLTDI73UifG8LbfQI7cA4= +github.com/lightstep/go-expohisto v1.0.0/go.mod h1:xDXD0++Mu2FOaItXtdDfksfgxfV0z1TMPa+e/EUd0cs= +github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY= +github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= +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/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.104.0 h1:6dvpPt8pCcV+TfMnnanFk2NQYf9HN1voSS9iIHdW+L8= +github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.104.0/go.mod h1:MfSM6mt9qH3vHCaj2rlX6IY/7fN+zCLzNJC25XG9rNU= +github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.104.0 h1:SveJtKEP2pXyCbucjrDzbBGQUUgrU+vBMTyUgy0tplc= +github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.104.0/go.mod h1:HdVNjnRruSyRiqXvPBy/ZVumw7zjegmoJmFRgtBnaQU= +github.com/open-telemetry/opentelemetry-collector-contrib/extension/pprofextension v0.104.0 h1:dcs3PHXBShL5+DWmDrNXnESlehQjRjIaVE84GPyZL5E= +github.com/open-telemetry/opentelemetry-collector-contrib/extension/pprofextension v0.104.0/go.mod h1:Vh707OU/o72qqlDGS+8WVkMCTIlmiTfy3k6PQeq/tgY= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.104.0 h1:4ke4j/y7AQnRAyYveB+KGcdjVYEKVrwTxc3BDHagdd0= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.104.0/go.mod h1:I2zX9YBggIum9LAHXN1DqqbYOENrHXbXdkXouhwVCHw= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.104.0 h1:/koTWTWCFF7tBYkDX5UzCaEc/ceTU8jij/Yzuj0So3M= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.104.0/go.mod h1:KWVekIHTPScOrLKVYOiijxfEdGK5OBhD4EFNBh96ESg= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.104.0 h1:4dU16tXhXWUfOYHoDtpEJHYze1ltgMFWvD1jWVeARRI= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.104.0/go.mod h1:poM/ch3rxaWlkiGV3ohdEDALhfwx6jaKd1z7xk6iY0o= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/pdatautil v0.104.0 h1:dOPRk39L5bwQNbxJ7mSUyHan0un/r9DV9X7G+YrktGk= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/pdatautil v0.104.0/go.mod h1:nyUlZ88VgBDoA9SfmUs0RcsVzqts9z0PpLxjFZPjD3w= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.104.0 h1:J4VwD+t7XpMuhdgd5KwhI5f17bOKHDD862szUW2ulVo= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.104.0/go.mod h1:MYspCVghl0glPIWT/gca6hXL48fROuJxo7lkEB171Ws= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.104.0 h1:4ES79GC+1fyDlLmC2ASM7MpKGLx1LIBpL8wE7G3zzSA= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.104.0/go.mod h1:h5v/Xn0jreStYi9nyPHjwfYseH8Xe3DznsUNS5R4Oqg= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.104.0 h1:bgS1X1UnUuYfKXsQPq3U50jsMNpN5lI+BcDeklPJOW8= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.104.0/go.mod h1:tImy4FWNu1qpaXRVaNi2BU+TmZHtYgLO6LbB6mspZio= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.104.0 h1:Pl4rXXpRG/xJuNWUS3I/w1jViHcrssMf47bGX/Ug/KY= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.104.0/go.mod h1:tP4dyc5+g/qoXYb8lmNj+y+Nhphn4MkL23/np0Zhx2g= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.104.0 h1:Vwkk+0+cppH+TrmdiVFWcshhdvh2g2IZEj16V8SLjLw= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.104.0/go.mod h1:QmV2JbLC0lzzi0hMUKv5hJ824wdzvYInjVJsphQQ5Uo= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/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.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +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.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= +github.com/rs/cors v1.11.0/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 v1.7.1 h1:UJcjSAI3aUKx52kfcfhblgyhZceouhvvs3OYdWgn+PY= +github.com/shoenig/test v1.7.1/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI= +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/tilinna/clock v1.1.0 h1:6IQQQCo6KoBxVudv6gwtY8o4eDfhHo8ojA5dP0MfhSs= +github.com/tilinna/clock v1.1.0/go.mod h1:ZsP7BcY7sEEz7ktc0IVy8Us6boDrK8VradlKRUGfOao= +github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= +github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= +github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= +github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= +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/confmap/provider/fileprovider v0.104.0 h1:B+nMVlIUQxuP52CZSegGuA2z9S+Cv2XwFb2a/TLFPhc= +go.opentelemetry.io/collector/confmap/provider/fileprovider v0.104.0/go.mod h1:O0RcaP/I/kn7JHrwohUfj6AwvQYLxjbqg/HnjkvLLTw= +go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.104.0 h1:itBGhyEbX+iz8kz3nc4PYxQx4bL7y87xXNUcGnbKPuY= +go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.104.0/go.mod h1:iPVsTBkRFHZ21UEfSGWk8c4maOzTp6BWWpTk+l6PjJI= +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/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/processor/batchprocessor v0.104.0 h1:6xXvHYkPjwM1zdzliDM2H/omTGgIOkY96JTCln7CFZQ= +go.opentelemetry.io/collector/processor/batchprocessor v0.104.0/go.mod h1:f1VfVdiOlqtJDAvQy8YONEee19nJ3haxNeiMPy59w8M= +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/receiver/nopreceiver v0.104.0 h1:xkfiTIGEXMXosYbZe8C8tIEZiw+gEL8QhCxz8slSYcM= +go.opentelemetry.io/collector/receiver/nopreceiver v0.104.0/go.mod h1:9vZPqdvOBDh9fKugWiv8WIINkF+TFpOw7RhvZxctZ9w= +go.opentelemetry.io/collector/receiver/otlpreceiver v0.104.0 h1:t9cACuSc7kY09guws7VyB/z9QnG7/zWLC1NQ29WH4+o= +go.opentelemetry.io/collector/receiver/otlpreceiver v0.104.0/go.mod h1:sPIIO4F6uit1i/XQgfe2WryvdO5Hr16bQgZTaXcR8mM= +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.1.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-20240624140628-dc46fd24d27d h1:Aqf0fiIdUQEj0Gn9mKFFXoQfTTEaNopWpfVyYADxiSg= +google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Od4k8V1LQSizPRUK4OzZ7TBE/20k+jPczUDAEyvn69Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +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.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +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/comp/otelcol/extension/impl/internal/metadata/metadata.go b/comp/otelcol/ddflareextension/impl/internal/metadata/metadata.go similarity index 84% rename from comp/otelcol/extension/impl/internal/metadata/metadata.go rename to comp/otelcol/ddflareextension/impl/internal/metadata/metadata.go index fae8a6244acd9..758e7130b8841 100644 --- a/comp/otelcol/extension/impl/internal/metadata/metadata.go +++ b/comp/otelcol/ddflareextension/impl/internal/metadata/metadata.go @@ -10,10 +10,8 @@ import ( "go.opentelemetry.io/collector/component" ) -var ( - // Type is the OpenTelemetry type for the extenstion - Type = component.MustNewType("datadog") -) +// Type is the OpenTelemetry type for the extenstion +var Type = component.MustNewType("ddflare") const ( // ExtensionStability is the OpenTelemetry current stability level for the extenstion diff --git a/comp/otelcol/extension/impl/server.go b/comp/otelcol/ddflareextension/impl/server.go similarity index 96% rename from comp/otelcol/extension/impl/server.go rename to comp/otelcol/ddflareextension/impl/server.go index b602326df09ad..2a4c74f66fda8 100644 --- a/comp/otelcol/extension/impl/server.go +++ b/comp/otelcol/ddflareextension/impl/server.go @@ -3,8 +3,8 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package extensionimpl defines the OpenTelemetry Extension implementation. -package extensionimpl +// Package ddflareextensionimpl defines the OpenTelemetry Extension implementation. +package ddflareextensionimpl import ( "crypto/rand" diff --git a/comp/otelcol/extension/impl/testdata/config.yaml b/comp/otelcol/ddflareextension/impl/testdata/config.yaml similarity index 73% rename from comp/otelcol/extension/impl/testdata/config.yaml rename to comp/otelcol/ddflareextension/impl/testdata/config.yaml index cc3698a720498..eaa894ec2d049 100644 --- a/comp/otelcol/extension/impl/testdata/config.yaml +++ b/comp/otelcol/ddflareextension/impl/testdata/config.yaml @@ -5,7 +5,10 @@ receivers: http: exporters: otlp: +extensions: + pprof/custom: service: + extensions: [pprof/custom] pipelines: traces: receivers: [otlp] diff --git a/comp/otelcol/extension/impl/utils.go b/comp/otelcol/ddflareextension/impl/utils.go similarity index 81% rename from comp/otelcol/extension/impl/utils.go rename to comp/otelcol/ddflareextension/impl/utils.go index bff39ba6f2fc1..f19285d75dfe8 100644 --- a/comp/otelcol/extension/impl/utils.go +++ b/comp/otelcol/ddflareextension/impl/utils.go @@ -3,8 +3,8 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. -// Package extensionimpl defines the OpenTelemetry Extension implementation. -package extensionimpl +// Package ddflareextensionimpl defines the OpenTelemetry Extension implementation. +package ddflareextensionimpl import ( "os" diff --git a/comp/otelcol/extension/impl/extension_test.go b/comp/otelcol/extension/impl/extension_test.go deleted file mode 100644 index 05cfaddf270b8..0000000000000 --- a/comp/otelcol/extension/impl/extension_test.go +++ /dev/null @@ -1,121 +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 2024-present Datadog, Inc. - -// Package extensionimpl defines the OpenTelemetry Extension implementation. -package extensionimpl - -import ( - "context" - "encoding/json" - "net/http" - "net/http/httptest" - "path/filepath" - "testing" - - collectorcontribimpl "github.com/DataDog/datadog-agent/comp/otelcol/collector-contrib/impl" - configstore "github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl" - extension "github.com/DataDog/datadog-agent/comp/otelcol/extension/def" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/config/confighttp" - "go.opentelemetry.io/collector/confmap" - "go.opentelemetry.io/collector/confmap/provider/fileprovider" - "go.opentelemetry.io/collector/confmap/provider/yamlprovider" - "go.opentelemetry.io/collector/otelcol" -) - -var cpSettings = otelcol.ConfigProviderSettings{ - ResolverSettings: confmap.ResolverSettings{ - URIs: []string{filepath.Join("testdata", "config.yaml")}, - ProviderFactories: []confmap.ProviderFactory{ - fileprovider.NewFactory(), - yamlprovider.NewFactory(), - }, - }, -} - -func getExtensionTestConfig(t *testing.T) *Config { - cf, err := configstore.NewConfigStore() - assert.NoError(t, err) - - factories, err := collectorcontribimpl.NewComponent().OTelComponentFactories() - assert.NoError(t, err) - - cf.AddConfigs(cpSettings, cpSettings, factories) - return &Config{ - HTTPConfig: &confighttp.ServerConfig{ - Endpoint: "localhost:0", - }, - ConfigStore: cf, - } -} - -func getTestExtension(t *testing.T) (extension.Component, error) { - c := context.Background() - telemetry := component.TelemetrySettings{} - info := component.NewDefaultBuildInfo() - cfg := getExtensionTestConfig(t) - - return NewExtension(c, cfg, telemetry, info) -} - -func TestNewExtension(t *testing.T) { - ext, err := getTestExtension(t) - assert.NoError(t, err) - assert.NotNil(t, ext) - - _, ok := ext.(*ddExtension) - assert.True(t, ok) -} - -func TestExtensionHTTPHandler(t *testing.T) { - // Create a request - req, err := http.NewRequest("GET", "/", nil) - if err != nil { - t.Fatal(err) - } - - // Create a ResponseRecorder - rr := httptest.NewRecorder() - - // Create an instance of your handler - ext, err := getTestExtension(t) - require.NoError(t, err) - - ddExt := ext.(*ddExtension) - - // Call the handler's ServeHTTP method - ddExt.ServeHTTP(rr, req) - - // Check the response status code - assert.Equalf(t, http.StatusOK, rr.Code, - "handler returned wrong status code: got %v want %v", rr.Code, http.StatusOK) - - // Check the response body - expectedKeys := []string{ - "version", - "command", - "description", - "extension_version", - "provided_configuration", - "full_configuration", - "runtime_override_configuration", - "environment_variable_configuration", - "environment", - } - var response map[string]interface{} - json.Unmarshal(rr.Body.Bytes(), &response) - - for _, key := range expectedKeys { - _, ok := response[key] - assert.True(t, ok) - } - - // There will be no sources configured and thus, that key - // should not be present - _, ok := response["sources"] - assert.False(t, ok) -} diff --git a/comp/otelcol/extension/impl/go.mod b/comp/otelcol/extension/impl/go.mod deleted file mode 100644 index f7d04d1db5ec0..0000000000000 --- a/comp/otelcol/extension/impl/go.mod +++ /dev/null @@ -1,376 +0,0 @@ -module github.com/DataDog/datadog-agent/comp/otelcol/extension/impl - -go 1.22.0 - -replace ( - github.com/DataDog/datadog-agent/comp/core/config => ../../../core/config - github.com/DataDog/datadog-agent/comp/core/flare/builder => ../../../core/flare/builder - github.com/DataDog/datadog-agent/comp/core/flare/types => ../../../core/flare/types - github.com/DataDog/datadog-agent/comp/core/hostname/hostnameinterface => ../../../core/hostname/hostnameinterface - github.com/DataDog/datadog-agent/comp/core/log/def => ../../../core/log/def - github.com/DataDog/datadog-agent/comp/core/secrets => ../../../core/secrets - github.com/DataDog/datadog-agent/comp/core/telemetry => ../../../core/telemetry - github.com/DataDog/datadog-agent/comp/def => ../../../def - github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../logs/agent/config - github.com/DataDog/datadog-agent/comp/otelcol/collector-contrib/def => ../../collector-contrib/def - github.com/DataDog/datadog-agent/comp/otelcol/collector-contrib/impl => ../../collector-contrib/impl - github.com/DataDog/datadog-agent/comp/otelcol/configstore/def => ../../configstore/def - github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl => ../../configstore/impl - github.com/DataDog/datadog-agent/comp/otelcol/extension/def => ../../extension/def - github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline => ../../logsagentpipeline - github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline/logsagentpipelineimpl => ../../logsagentpipeline/logsagentpipelineimpl - github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/exporter/logsagentexporter => ../../otlp/components/exporter/logsagentexporter - github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/metricsclient => ../../otlp/components/metricsclient - github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/statsprocessor => ../../otlp/components/statsprocessor - github.com/DataDog/datadog-agent/comp/trace/compression/def => ../../../trace/compression/def - github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip => ../../../trace/compression/impl-gzip - github.com/DataDog/datadog-agent/comp/trace/compression/impl-zstd => ../../../trace/compression/impl-zstd - github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../../pkg/collector/check/defaults - github.com/DataDog/datadog-agent/pkg/config/env => ../../../../pkg/config/env - github.com/DataDog/datadog-agent/pkg/config/model => ../../../../pkg/config/model - github.com/DataDog/datadog-agent/pkg/config/setup => ../../../../pkg/config/setup - github.com/DataDog/datadog-agent/pkg/config/utils => ../../../../pkg/config/utils - github.com/DataDog/datadog-agent/pkg/logs/auditor => ../../../../pkg/logs/auditor - github.com/DataDog/datadog-agent/pkg/logs/client => ../../../../pkg/logs/client - github.com/DataDog/datadog-agent/pkg/logs/diagnostic => ../../../../pkg/logs/diagnostic - github.com/DataDog/datadog-agent/pkg/logs/message => ../../../../pkg/logs/message - github.com/DataDog/datadog-agent/pkg/logs/metrics => ../../../../pkg/logs/metrics - github.com/DataDog/datadog-agent/pkg/logs/pipeline => ../../../../pkg/logs/pipeline - github.com/DataDog/datadog-agent/pkg/logs/processor => ../../../../pkg/logs/processor - github.com/DataDog/datadog-agent/pkg/logs/sds => ../../../../pkg/logs/sds - github.com/DataDog/datadog-agent/pkg/logs/sender => ../../../../pkg/logs/sender - github.com/DataDog/datadog-agent/pkg/logs/sources => ../../../../pkg/logs/sources - github.com/DataDog/datadog-agent/pkg/logs/status/statusinterface => ../../../../pkg/logs/status/statusinterface - github.com/DataDog/datadog-agent/pkg/logs/status/utils => ../../../../pkg/logs/status/utils - github.com/DataDog/datadog-agent/pkg/obfuscate => ../../../../pkg/obfuscate - github.com/DataDog/datadog-agent/pkg/proto => ../../../../pkg/proto - github.com/DataDog/datadog-agent/pkg/remoteconfig/state => ../../../../pkg/remoteconfig/state - github.com/DataDog/datadog-agent/pkg/status/health => ../../../../pkg/status/health - github.com/DataDog/datadog-agent/pkg/telemetry => ../../../../pkg/telemetry - github.com/DataDog/datadog-agent/pkg/trace => ../../../../pkg/trace - github.com/DataDog/datadog-agent/pkg/util/backoff => ../../../../pkg/util/backoff - github.com/DataDog/datadog-agent/pkg/util/cgroups => ../../../../pkg/util/cgroups - github.com/DataDog/datadog-agent/pkg/util/executable => ../../../../pkg/util/executable - github.com/DataDog/datadog-agent/pkg/util/filesystem => ../../../../pkg/util/filesystem - github.com/DataDog/datadog-agent/pkg/util/fxutil => ../../../../pkg/util/fxutil - github.com/DataDog/datadog-agent/pkg/util/hostname/validate => ../../../../pkg/util/hostname/validate - github.com/DataDog/datadog-agent/pkg/util/http => ../../../../pkg/util/http - github.com/DataDog/datadog-agent/pkg/util/log => ../../../../pkg/util/log - github.com/DataDog/datadog-agent/pkg/util/optional => ../../../../pkg/util/optional - github.com/DataDog/datadog-agent/pkg/util/pointer => ../../../../pkg/util/pointer - github.com/DataDog/datadog-agent/pkg/util/scrubber => ../../../../pkg/util/scrubber - github.com/DataDog/datadog-agent/pkg/util/startstop => ../../../../pkg/util/startstop - github.com/DataDog/datadog-agent/pkg/util/statstracker => ../../../../pkg/util/statstracker - github.com/DataDog/datadog-agent/pkg/util/system => ../../../../pkg/util/system - github.com/DataDog/datadog-agent/pkg/util/system/socket => ../../../../pkg/util/system/socket - github.com/DataDog/datadog-agent/pkg/util/winutil => ../../../../pkg/util/winutil - github.com/DataDog/datadog-agent/pkg/version => ../../../../pkg/version - // todo: update datadog connector with breaking changes from https://github.com/DataDog/datadog-agent/pull/26347. - github.com/open-telemetry/opentelemetry-collector-contrib/connector/datadogconnector => github.com/open-telemetry/opentelemetry-collector-contrib/connector/datadogconnector v0.103.0 -) - -require ( - github.com/DataDog/datadog-agent/comp/otelcol/collector-contrib/impl v0.0.0-00010101000000-000000000000 - github.com/DataDog/datadog-agent/comp/otelcol/configstore/def v0.56.0-rc.3 - github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl v0.56.0-rc.3 - github.com/DataDog/datadog-agent/comp/otelcol/extension/def v0.56.0-rc.3 - github.com/stretchr/testify v1.9.0 - go.opentelemetry.io/collector/component v0.104.0 - go.opentelemetry.io/collector/config/confighttp v0.104.0 - go.opentelemetry.io/collector/confmap v0.104.0 - go.opentelemetry.io/collector/confmap/provider/fileprovider v0.104.0 - go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.104.0 - go.opentelemetry.io/collector/extension v0.104.0 - go.opentelemetry.io/collector/otelcol v0.104.0 - go.uber.org/zap v1.27.0 -) - -require ( - cloud.google.com/go/auth v0.5.1 // indirect - cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect - cloud.google.com/go/compute/metadata v0.3.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.5.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect - github.com/Code-Hex/go-generics-cache v1.3.1 // indirect - github.com/DataDog/datadog-agent/comp/otelcol/collector-contrib/def v0.56.0-rc.3 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.0 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Showmax/go-fqdn v1.0.0 // indirect - github.com/alecthomas/participle/v2 v2.1.1 // indirect - github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect - github.com/apache/thrift v0.20.0 // indirect - github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go v1.53.11 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/dennwc/varint v1.0.0 // indirect - github.com/digitalocean/godo v1.109.0 // indirect - github.com/distribution/reference v0.5.0 // indirect - github.com/docker/docker v25.0.6+incompatible // indirect - github.com/docker/go-connections v0.5.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/envoyproxy/go-control-plane v0.12.0 // indirect - github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect - github.com/expr-lang/expr v1.16.9 // indirect - github.com/fatih/color v1.16.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.20.2 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect - github.com/go-openapi/swag v0.22.9 // indirect - github.com/go-resty/resty/v2 v2.12.0 // indirect - github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect - github.com/go-zookeeper/zk v1.0.3 // indirect - github.com/gobwas/glob v0.2.3 // indirect - github.com/goccy/go-json v0.10.3 // indirect - github.com/gogo/googleapis v1.4.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v5 v5.2.1 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/go-querystring v1.1.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/s2a-go v0.1.7 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.4 // indirect - github.com/gophercloud/gophercloud v1.8.0 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.1 // indirect - github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect - github.com/hashicorp/consul/api v1.29.1 // indirect - github.com/hashicorp/cronexpr v1.1.2 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.6.3 // indirect - github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.7.4 // indirect - github.com/hashicorp/go-rootcerts v1.0.2 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect - github.com/hashicorp/golang-lru v1.0.2 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/hashicorp/nomad/api v0.0.0-20240306004928-3e7191ccb702 // indirect - github.com/hashicorp/serf v0.10.1 // indirect - github.com/hetznercloud/hcloud-go/v2 v2.6.0 // indirect - github.com/iancoleman/strcase v0.3.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/ionos-cloud/sdk-go/v6 v6.1.11 // indirect - github.com/jaegertracing/jaeger v1.58.1 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/jpillora/backoff v1.0.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/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b // indirect - github.com/kylelemons/godebug v1.1.0 // indirect - github.com/leodido/go-syslog/v4 v4.1.0 // indirect - github.com/leodido/ragel-machinery v0.0.0-20190525184631-5f46317e436b // indirect - github.com/lightstep/go-expohisto v1.0.0 // indirect - github.com/linode/linodego v1.33.0 // indirect - github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/miekg/dns v1.1.58 // indirect - github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect - github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // 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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect - github.com/onsi/ginkgo/v2 v2.14.0 // indirect - github.com/onsi/gomega v1.30.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sapmexporter v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/dockerobserver v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/ecsobserver v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/ecstaskobserver v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/hostobserver v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/k8sobserver v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/extension/pprofextension v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/docker v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/pdatautil v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/splunk v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchperresourceattr v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheus v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/zipkin v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/cumulativetodeltaprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/filterprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/groupbyattrsprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/routingprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/fluentforwardreceiver v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/receivercreator v0.104.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver v0.104.0 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/openshift/api v3.9.0+incompatible // indirect - github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142 // indirect - github.com/openzipkin/zipkin-go v0.4.3 // indirect - github.com/ovh/go-ovh v1.4.3 // indirect - github.com/philhofer/fwd v1.1.2 // indirect - github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect - github.com/prometheus-community/windows_exporter v0.25.1 // 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/common/sigv4 v0.1.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect - github.com/prometheus/prometheus v0.51.2-0.20240405174432-b4a973753c6e // indirect - github.com/rs/cors v1.11.0 // indirect - github.com/scaleway/scaleway-sdk-go v1.0.0-beta.25 // indirect - github.com/shirou/gopsutil/v4 v4.24.5 // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect - github.com/signalfx/sapm-proto v0.14.0 // indirect - github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.5.2 // indirect - github.com/tidwall/gjson v1.14.2 // indirect - github.com/tilinna/clock v1.1.0 // indirect - github.com/tinylib/msgp v1.1.9 // indirect - github.com/tklauser/go-sysconf v0.3.14 // indirect - github.com/tklauser/numcpus v0.8.0 // indirect - github.com/valyala/fastjson v1.6.4 // indirect - github.com/vultr/govultr/v2 v2.17.2 // 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/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/connector v0.104.0 // indirect - go.opentelemetry.io/collector/consumer v0.104.0 // indirect - go.opentelemetry.io/collector/exporter v0.104.0 // indirect - go.opentelemetry.io/collector/exporter/debugexporter v0.104.0 // indirect - go.opentelemetry.io/collector/exporter/loggingexporter v0.104.0 // indirect - go.opentelemetry.io/collector/exporter/nopexporter v0.104.0 // indirect - go.opentelemetry.io/collector/exporter/otlpexporter v0.104.0 // indirect - go.opentelemetry.io/collector/exporter/otlphttpexporter v0.104.0 // indirect - go.opentelemetry.io/collector/extension/auth v0.104.0 // indirect - go.opentelemetry.io/collector/extension/zpagesextension v0.104.0 // indirect - go.opentelemetry.io/collector/featuregate v1.11.0 // indirect - go.opentelemetry.io/collector/filter v0.104.0 // indirect - go.opentelemetry.io/collector/pdata v1.11.0 // indirect - go.opentelemetry.io/collector/processor v0.104.0 // indirect - go.opentelemetry.io/collector/processor/batchprocessor v0.104.0 // indirect - go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.104.0 // indirect - go.opentelemetry.io/collector/receiver v0.104.0 // indirect - go.opentelemetry.io/collector/receiver/nopreceiver v0.104.0 // indirect - go.opentelemetry.io/collector/receiver/otlpreceiver v0.104.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/contrib/zpages v0.52.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 - go.uber.org/atomic v1.11.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.23.0 // indirect - gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/api v0.185.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // indirect - google.golang.org/grpc v1.64.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.29.3 // indirect - k8s.io/apimachinery v0.29.3 // indirect - k8s.io/client-go v0.29.3 // indirect - k8s.io/klog/v2 v2.120.1 // indirect - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect - k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect -) diff --git a/comp/otelcol/extension/impl/go.sum b/comp/otelcol/extension/impl/go.sum deleted file mode 100644 index 22b735b72db0e..0000000000000 --- a/comp/otelcol/extension/impl/go.sum +++ /dev/null @@ -1,1401 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/auth v0.5.1 h1:0QNO7VThG54LUzKiQxv8C6x1YX7lUrzlAa1nVLF8CIw= -cloud.google.com/go/auth v0.5.1/go.mod h1:vbZT8GjzDf3AVqCcQmqeeM32U9HBFc32vVVAbwDsa6s= -cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= -cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.5.0 h1:MxA59PGoCFb+vCwRQi3PhQEwHj4+r2dhuv9HG+vM7iM= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.5.0/go.mod h1:uYt4CfhkJA9o0FN7jfE5minm/i4nUE4MjGUJkzB6Zs8= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0/go.mod h1:Y/HgrePTmGy9HjdSGTqZNa+apUpTVIEVKXJyARP2lrk= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= -github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Code-Hex/go-generics-cache v1.3.1 h1:i8rLwyhoyhaerr7JpjtYjJZUcCbWOdiYO3fZXLiEC4g= -github.com/Code-Hex/go-generics-cache v1.3.1/go.mod h1:qxcC9kRVrct9rHeiYpFWSoW1vxyillCVzX13KZG8dl4= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.0 h1:N4xzkSD2BkRwEZSPf3C2eUZxjS5trpo4gOwRh8mu+BA= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.0/go.mod h1:p2puVVSKjQ84Qb1gzw2XHLs34WQyHTYFZLaVxypAFYs= -github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= -github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= -github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Showmax/go-fqdn v1.0.0 h1:0rG5IbmVliNT5O19Mfuvna9LL7zlHyRfsSvBPZmF9tM= -github.com/Showmax/go-fqdn v1.0.0/go.mod h1:SfrFBzmDCtCGrnHhoDjuvFnKsWjEQX/Q9ARZvOrJAko= -github.com/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0= -github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= -github.com/alecthomas/participle/v2 v2.1.1 h1:hrjKESvSqGHzRb4yW1ciisFJ4p3MGYih6icjJvbsmV8= -github.com/alecthomas/participle/v2 v2.1.1/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c= -github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= -github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/apache/thrift v0.20.0 h1:631+KvYbsBZxmuJjYwhezVsrfc/TbqtZV4QcxOX1fOI= -github.com/apache/thrift v0.20.0/go.mod h1:hOk1BQqcp2OLzGsyVXdfMk7YFlMxK3aoEVhjD06QhB8= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.53.11 h1:KcmduYvX15rRqt4ZU/7jKkmDxU/G87LJ9MUI0yQJh00= -github.com/aws/aws-sdk-go v1.53.11/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps= -github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3/go.mod h1:CIWtjkly68+yqLPbvwwR/fjNJA/idrtULjZWh2v1ys0= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -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/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= -github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -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.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -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/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -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/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50 h1:DBmgJDC9dTfkVyGgipamEh2BpGYxScCH1TOF1LL1cXc= -github.com/cncf/xds/go v0.0.0-20240318125728-8a4994d93e50/go.mod h1:5e1+Vvlzido69INQaVO6d87Qn543Xr6nooe9Kz7oBFM= -github.com/containerd/containerd v1.7.15 h1:afEHXdil9iAm03BmhjzKyXnnEBtjaLJefdU7DV0IFes= -github.com/containerd/containerd v1.7.15/go.mod h1:ISzRRTMF8EXNpJlTzyr2XMhN+j9K302C21/+cr3kUnY= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= -github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= -github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= -github.com/digitalocean/godo v1.109.0 h1:4W97RJLJSUQ3veRZDNbp1Ol3Rbn6Lmt9bKGvfqYI5SU= -github.com/digitalocean/godo v1.109.0/go.mod h1:R6EmmWI8CT1+fCtjWY9UCB+L5uufuZH13wk3YhxycCs= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= -github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -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/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI= -github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= -github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= -github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/expr-lang/expr v1.16.9 h1:WUAzmR0JNI9JCiF0/ewwHB1gmcGw5wW7nWt8gc6PpCI= -github.com/expr-lang/expr v1.16.9/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -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-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= -github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/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/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= -github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= -github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= -github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= -github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA= -github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -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/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= -github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= -github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -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/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -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.4.1/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.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/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.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -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/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 h1:y3N7Bm7Y9/CtpiVkw/ZWj6lSlDF3F74SfKwfTCer72Q= -github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -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/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg= -github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI= -github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/gophercloud/gophercloud v1.8.0 h1:TM3Jawprb2NrdOnvcHhWJalmKmAmOGgfZElM/3oBYCk= -github.com/gophercloud/gophercloud v1.8.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= -github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= -github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= -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/consul/api v1.29.1 h1:UEwOjYJrd3lG1x5w7HxDRMGiAUPrb3f103EoeKuuEcc= -github.com/hashicorp/consul/api v1.29.1/go.mod h1:lumfRkY/coLuqMICkI7Fh3ylMG31mQSRZyef2c5YvJI= -github.com/hashicorp/consul/proto-public v0.6.1 h1:+uzH3olCrksXYWAYHKqK782CtK9scfqH+Unlw3UHhCg= -github.com/hashicorp/consul/proto-public v0.6.1/go.mod h1:cXXbOg74KBNGajC+o8RlA502Esf0R9prcoJgiOX/2Tg= -github.com/hashicorp/consul/sdk v0.16.1 h1:V8TxTnImoPD5cj0U9Spl0TUxcytjcbbJeADFF07KdHg= -github.com/hashicorp/consul/sdk v0.16.1/go.mod h1:fSXvwxB2hmh1FMZCNl6PwX0Q/1wdWtHJcZ7Ea5tns0s= -github.com/hashicorp/cronexpr v1.1.2 h1:wG/ZYIKT+RT3QkOdgYc+xsKWVRgnxJ1OJtjjy84fJ9A= -github.com/hashicorp/cronexpr v1.1.2/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= -github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= -github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= -github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= -github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= -github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -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/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= -github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= -github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= -github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= -github.com/hashicorp/nomad/api v0.0.0-20240306004928-3e7191ccb702 h1:fI1LXuBaS1d9z1kmb++Og6YD8uMRwadXorCwE+xgOFA= -github.com/hashicorp/nomad/api v0.0.0-20240306004928-3e7191ccb702/go.mod h1:z71gkJdrkAt/Rl6C7Q79VE7AwJ5lUF+M+fzFTyIHYB0= -github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= -github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hetznercloud/hcloud-go/v2 v2.6.0 h1:RJOA2hHZ7rD1pScA4O1NF6qhkHyUdbbxjHgFNot8928= -github.com/hetznercloud/hcloud-go/v2 v2.6.0/go.mod h1:4J1cSE57+g0WS93IiHLV7ubTHItcp+awzeBp5bM9mfA= -github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= -github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/ionos-cloud/sdk-go/v6 v6.1.11 h1:J/uRN4UWO3wCyGOeDdMKv8LWRzKu6UIkLEaes38Kzh8= -github.com/ionos-cloud/sdk-go/v6 v6.1.11/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= -github.com/jaegertracing/jaeger v1.58.1 h1:bFtX70yQbBfRbS8TB1JL4/ENr/qR09VJMeC/C892q4w= -github.com/jaegertracing/jaeger v1.58.1/go.mod h1:2qpJpm9BzpbxNpaillaCA4pvdAIRTJT0ZRxrzMglBlo= -github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= -github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -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/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= -github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/leodido/go-syslog/v4 v4.1.0 h1:Wsl194qyWXr7V6DrGWC3xmxA9Ra6XgWO+toNt2fmCaI= -github.com/leodido/go-syslog/v4 v4.1.0/go.mod h1:eJ8rUfDN5OS6dOkCOBYlg2a+hbAg6pJa99QXXgMrd98= -github.com/leodido/ragel-machinery v0.0.0-20190525184631-5f46317e436b h1:11UHH39z1RhZ5dc4y4r/4koJo6IYFgTRMe/LlwRTEw0= -github.com/leodido/ragel-machinery v0.0.0-20190525184631-5f46317e436b/go.mod h1:WZxr2/6a/Ar9bMDc2rN/LJrE/hF6bXE4LPyDSIxwAfg= -github.com/lightstep/go-expohisto v1.0.0 h1:UPtTS1rGdtehbbAF7o/dhkWLTDI73UifG8LbfQI7cA4= -github.com/lightstep/go-expohisto v1.0.0/go.mod h1:xDXD0++Mu2FOaItXtdDfksfgxfV0z1TMPa+e/EUd0cs= -github.com/linode/linodego v1.33.0 h1:cX2FYry7r6CA1ujBMsdqiM4VhvIQtnWsOuVblzfBhCw= -github.com/linode/linodego v1.33.0/go.mod h1:dSJJgIwqZCF5wnpuC6w5cyIbRtcexAm7uVvuJopGB40= -github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY= -github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= -github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -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/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= -github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= -github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE= -github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= -github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= -github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= -github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= -github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -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 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -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/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -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/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY= -github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= -github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.104.0 h1:6dvpPt8pCcV+TfMnnanFk2NQYf9HN1voSS9iIHdW+L8= -github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.104.0/go.mod h1:MfSM6mt9qH3vHCaj2rlX6IY/7fN+zCLzNJC25XG9rNU= -github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusremotewriteexporter v0.104.0 h1:lkf7Bof0rbPy2/0+tu+FAgEzwVKmJKcMlx8xsR26TdA= -github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusremotewriteexporter v0.104.0/go.mod h1:B6dQmrNwW1q7rOadf57fwIaZHYzwrovTSSEEaiFyf0w= -github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sapmexporter v0.104.0 h1:vYEXEsS7T3a4XUgVbHG1dS351hqTKC3NtD+5Ef3FpVE= -github.com/open-telemetry/opentelemetry-collector-contrib/exporter/sapmexporter v0.104.0/go.mod h1:CRg5FSH3MfuLP8cH6SYYTPAZCZFgDj6xhShrDrpfejw= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.104.0 h1:SveJtKEP2pXyCbucjrDzbBGQUUgrU+vBMTyUgy0tplc= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckextension v0.104.0/go.mod h1:HdVNjnRruSyRiqXvPBy/ZVumw7zjegmoJmFRgtBnaQU= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer v0.104.0 h1:XYnVSDSqmMWUhwg83jChG2HL6vvM0vxQaBKLM9zxbyc= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer v0.104.0/go.mod h1:QQUgfXBq28KcvwxFwY4NPy4XA/theDwBqfssy/HSjLc= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/dockerobserver v0.104.0 h1:Xfu4oqbfYAQeJauZzAHI574zHVMDv+OLZQ2i0w3hce0= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/dockerobserver v0.104.0/go.mod h1:Hs8zV9mc4lAE/wX4Kaj+vHwIi4kyOQDl5f6EW8cn04E= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/ecsobserver v0.104.0 h1:TTWsWRjCJCNrdoHVEyyPVctKgzN0yjxY/2V+ghdrgn0= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/ecsobserver v0.104.0/go.mod h1:zIGvzLDK/hkALfrmlI8OtTE74uL6aCZ+dy6npBoiNGE= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/ecstaskobserver v0.104.0 h1:/TziEfyXaO+B7xaVgiH0bHnH5CQ29+VXsFZ2lxjAWzY= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/ecstaskobserver v0.104.0/go.mod h1:53b9O4S4LLOI8bk4LpVff6UhG2UE6HJPvAELMjj8klo= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/hostobserver v0.104.0 h1:LVv3Ew/UFAGHDXAzy5xIsSiQAd0+v9yyRyvqhgrjNl4= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/hostobserver v0.104.0/go.mod h1:pZKyo2Vl0EdywKlo10JfX75+jKC+kRsnh1oGS5wKzG8= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/k8sobserver v0.104.0 h1:B3rS5T6RytaaNwun4VVfQrcHmP5l9X+k3d6cfwAMma4= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer/k8sobserver v0.104.0/go.mod h1:EojYuU5AT6O9iIqmMThOFqD117irYCopCSs7ZCfSS8w= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/pprofextension v0.104.0 h1:dcs3PHXBShL5+DWmDrNXnESlehQjRjIaVE84GPyZL5E= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/pprofextension v0.104.0/go.mod h1:Vh707OU/o72qqlDGS+8WVkMCTIlmiTfy3k6PQeq/tgY= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.104.0 h1:VD2R4q2XziQCJIAsQG2qhlSKyDoT9XaTR2LNkJHs2C0= -github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.104.0/go.mod h1:sOdPmcOeSXXqZeBflu3Oa+0aWFL8QkAKpr/X1txJYSs= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.104.0 h1:KmZvS+RN2w4zxMuX1yiobjkN8fvwBUJ+vl5LkO3O7bk= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.104.0/go.mod h1:fc7PiNmgpw+RlWzdWcuoiH9mIlDgiryy70ZjEJC+nlY= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.104.0 h1:4ke4j/y7AQnRAyYveB+KGcdjVYEKVrwTxc3BDHagdd0= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.104.0/go.mod h1:I2zX9YBggIum9LAHXN1DqqbYOENrHXbXdkXouhwVCHw= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.104.0 h1:/koTWTWCFF7tBYkDX5UzCaEc/ceTU8jij/Yzuj0So3M= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.104.0/go.mod h1:KWVekIHTPScOrLKVYOiijxfEdGK5OBhD4EFNBh96ESg= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/docker v0.104.0 h1:P8h6WXcRr91SxfsC4kZw3nn8SzQiJoN5IWdFxKwTHzs= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/docker v0.104.0/go.mod h1:fuk7yN1ywQn03CebMPfC2BiWYNJYwl3DZjWAW7wLskg= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.104.0 h1:4dU16tXhXWUfOYHoDtpEJHYze1ltgMFWvD1jWVeARRI= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.104.0/go.mod h1:poM/ch3rxaWlkiGV3ohdEDALhfwx6jaKd1z7xk6iY0o= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig v0.104.0 h1:j5EAcIE5iA03KdrfrmXmplfPc1Lybt6D8RAmuumoq60= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig v0.104.0/go.mod h1:VS66oUydCMwiWl1BFmLs7iNy4lGsfVYsriXr/d1fpAk= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8stest v0.104.0 h1:yH3BLXIYH8D+NEdnaWN8NMrTmJV/UqB2ySRJGZlZzJI= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8stest v0.104.0/go.mod h1:hCzgpzXbUUDUlETMDKYOpPaOhPjR9T6M3W3nAW5cGX4= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.104.0 h1:hB2LSx2h/Xvnfam8jXu8sGy3M6YVSD6bcI5saenp+kY= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.104.0/go.mod h1:jTZf5CwMDiILww23FgxvLdIkCPH952ItR/3dJUb/sSk= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/pdatautil v0.104.0 h1:dOPRk39L5bwQNbxJ7mSUyHan0un/r9DV9X7G+YrktGk= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/pdatautil v0.104.0/go.mod h1:nyUlZ88VgBDoA9SfmUs0RcsVzqts9z0PpLxjFZPjD3w= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.104.0 h1:HrmXvaX8dbdEaygJhHMZ8MeHw40qTV0dpkmJDsWM2X4= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.104.0/go.mod h1:+sS/JnqjKPpcG+Zm+02h0te/+6KG86GPAvMgbqr1i+o= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/splunk v0.104.0 h1:KQkibS2K78OeojqCCoRG1HkgrqaXOjNUv9BIbRR9EP4= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/splunk v0.104.0/go.mod h1:ehoDySOe8p/IfYHm9Hp5gSZDk/2+m86A6Wb1+dQvwOI= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchperresourceattr v0.104.0 h1:R6Ia4hCOiCFDcWFA5DEYYY9j9Yr0fCrftGM+f429jpE= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchperresourceattr v0.104.0/go.mod h1:hp8fiwIcaNYGgqcMYdZVzxs2kNJ79gMsTDjkH7PJeiI= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.104.0 h1:J4VwD+t7XpMuhdgd5KwhI5f17bOKHDD862szUW2ulVo= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.104.0/go.mod h1:MYspCVghl0glPIWT/gca6hXL48fROuJxo7lkEB171Ws= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.104.0 h1:4ES79GC+1fyDlLmC2ASM7MpKGLx1LIBpL8wE7G3zzSA= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.104.0/go.mod h1:h5v/Xn0jreStYi9nyPHjwfYseH8Xe3DznsUNS5R4Oqg= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.104.0 h1:bgS1X1UnUuYfKXsQPq3U50jsMNpN5lI+BcDeklPJOW8= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.104.0/go.mod h1:tImy4FWNu1qpaXRVaNi2BU+TmZHtYgLO6LbB6mspZio= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.104.0 h1:Pl4rXXpRG/xJuNWUS3I/w1jViHcrssMf47bGX/Ug/KY= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.104.0/go.mod h1:tP4dyc5+g/qoXYb8lmNj+y+Nhphn4MkL23/np0Zhx2g= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry v0.104.0 h1:dNDjrDhJmSv2JoK3n2hX/nyf/twTTnLuvAhQTMHGQ5M= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry v0.104.0/go.mod h1:SyCZC+vcI2lnyb7iqH0/6dGgCihuqtCxGmLaZToxSHk= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.104.0 h1:iNr5/wS/0Rg4PnPO2Zf3Yj4Qc1RooVQ/7U7jKzocyPo= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.104.0/go.mod h1:4bLfc6BnVKRp3yY+ueEUEeyNWjW/InCGbFs9ZA7o/ko= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.104.0 h1:7GOOjgAFyvRS++8Q6BIoczShFdxRtsR2uUWlLw/DKdA= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza v0.104.0/go.mod h1:8DCdU7V1JdcnZtk3X1OvqI5wjpKiULf/wmqhLpsldAc= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.104.0 h1:3joQv7QiLvsVfrpqYAxHvq3bKUaUEpgg93fMLW+TU2w= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.104.0/go.mod h1:aUAgxXQQPiSajwMXQv4LobDTc16ezeF9S1Xh53yHbOg= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheus v0.104.0 h1:eCceBGaatwEKLiOzYjrYc4zNSMMfb+5Of9VNUnTYU80= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheus v0.104.0/go.mod h1:/mkH8dlZxnFRoccQoXkN/XOP6Q7G/1F8XTUO9+xZw7U= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheusremotewrite v0.104.0 h1:avbrkX0c51UjJE13RBqk/Z5QyO/J7J2/O9FIBaJ+Few= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheusremotewrite v0.104.0/go.mod h1:tkmsd1veEEsXtFdYSvoZU7S80INqCbNUGkEGQAivlV0= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/zipkin v0.104.0 h1:oIYYjBh2kNi7APSArA/9YCQzLwOlMdUhqMxUoMoTChY= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/zipkin v0.104.0/go.mod h1:hRayDDoU1e1POXuDO7RpwcqIirFJoCdSgHgICY0hNNI= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.104.0 h1:vP+DbTtQaF4sv2flxZwfY33q9hR2M1bJpSQvuwlDbFY= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/attributesprocessor v0.104.0/go.mod h1:eHsCNhiPuHFE5sKlsKzcos4gjkDF0LGnx6RJ/bGb4xw= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/cumulativetodeltaprocessor v0.104.0 h1:lsgzH/Rht06d+aiJPA7bAkuHHmar/Le97tHzN/VuECE= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/cumulativetodeltaprocessor v0.104.0/go.mod h1:LLzdMOPhoxAwda24odUyMZcOOmM56GnySfRjXwQ7tP0= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/filterprocessor v0.104.0 h1:R0XS3J1awJ5NHNSuxhGL+XGI7DN4v3tcHWw0VKfeoTo= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/filterprocessor v0.104.0/go.mod h1:QAd09DxYjA7EZeksoSLyri6uFNV/RUQQhdw7XF5T0zs= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/groupbyattrsprocessor v0.104.0 h1:Dust79ten+1/q92AgOLdnBnQDCsVT5rjl0/eSKFLdYo= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/groupbyattrsprocessor v0.104.0/go.mod h1:evkdeLcXutvRAz202BdwNk2g3+Y/mxVqX7hhDIJId5k= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor v0.104.0 h1:aSXAOm9JoGUGU6yVFULCe/gcls5Ofc8/N609tT1bv2U= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/k8sattributesprocessor v0.104.0/go.mod h1:kkTouWK3zdLS3iQXLjX338cPkjo3Ji5qcGvOqlmu0CQ= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.104.0 h1:W2OartqDicbzoLjAp2MCi+FIt2FBy5PyeYce0kIuerc= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.104.0/go.mod h1:I2so4Vn+ROaCECo0bdQXNxyUjY9tbq1JvcyuWPETLcM= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor v0.104.0 h1:cygcerFBuD8dbKRL/bm0U9JMl0MDpcbcQyG814QCU1Q= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor v0.104.0/go.mod h1:ygrHdjWKqcv/NjtclZAFw3mE5t/vsjIo/5zmqLHEI/w= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.104.0 h1:3eBOsSL2XmD/3Una1LcghKGATvJzwPpHEH/zZEW3GEA= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourceprocessor v0.104.0/go.mod h1:vpRTdMLbw7Kj5oxqUFIp4y75ta1uhtmVdDu6XDOwkvI= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/routingprocessor v0.104.0 h1:R56yHmF59ityfC3+HIzW/y0yNBufmU60s09TAtA0IO4= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/routingprocessor v0.104.0/go.mod h1:FvE+XtYk2t2cLcg3h/uFOLVcBwyEQENwBFJeKRi93rM= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor v0.104.0 h1:AnzZUTLBT5kADIOTE3NKqXK214sqnkilQqXkqgLjhJs= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor v0.104.0/go.mod h1:5FQezrJhOulRFWMnrpo3Z9O/qWySgDNniPp0p2mFJs0= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.104.0 h1:Vwkk+0+cppH+TrmdiVFWcshhdvh2g2IZEj16V8SLjLw= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/transformprocessor v0.104.0/go.mod h1:QmV2JbLC0lzzi0hMUKv5hJ824wdzvYInjVJsphQQ5Uo= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.104.0 h1:m+GTXZxfvajyiC2Tb+ItpbUvSJs8jtZUDwHOTUqU8GQ= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.104.0/go.mod h1:NAOAFKcnVeSDI4ZALPZOmgC4MzaT8+nnPKgdcjvXgms= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/fluentforwardreceiver v0.104.0 h1:wBncmXWbUr05VpttF0mPmmg7t2ozFmEL5t4H4IQJ3DI= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/fluentforwardreceiver v0.104.0/go.mod h1:JDNHNY3N/aDI39hgj07yZdfSOTqe07fZgZEw5Hqux0E= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver v0.104.0 h1:IOLup9RIHMwRF2C3fk67/q+4gRMQIWhv5cLMnfpBHwk= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver v0.104.0/go.mod h1:uFaeC99TK2kngdB/VWtgz0kNEAxMDkNEA0jP0FfOXyY= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver v0.104.0 h1:9HJ3ejNoiMFWxTRy9gobdurEocf79QlxwlYrOY9tMIQ= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver v0.104.0/go.mod h1:Ax4DroNn/xKyjWoJCd3FQE9xOZqHSTdDEj1I3HLNOeQ= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.104.0 h1:Nwkj5EFH90NxWPcl4qeef5AX+A1COWn1Xy1mkzuyIHE= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.104.0/go.mod h1:NJwlpVFJu2Dd1mEqCHzSXSNmd5JDhWGVDqo1Oi3RZKk= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/receivercreator v0.104.0 h1:q2GcJVLqe8V4KLCrmc1t2VUEz+z1xQC4kIcrPEs7r1Q= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/receivercreator v0.104.0/go.mod h1:X65iy1QrpMcEc9EA3t1Xlb9bxUEsbmInex/4tKlfq2o= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver v0.104.0 h1:U04Ezl3Keb1j6bcVktvgvAbbMEyPDkM5sNboQgPYI1w= -github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver v0.104.0/go.mod h1:GbpsurP8UERCcHyIB/gUMKcAK3kIypKGE0O+aqbNa/c= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/openshift/api v0.0.0-20210521075222-e273a339932a/go.mod h1:izBmoXbUu3z5kUa4FjZhvekTsyzIWiOoaIgJiZBBMQs= -github.com/openshift/api v3.9.0+incompatible h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs= -github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= -github.com/openshift/build-machinery-go v0.0.0-20210423112049-9415d7ebd33e/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= -github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142 h1:ZHRIMCFIJN1p9LsJt4HQ+akDrys4PrYnXzOWI5LK03I= -github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142/go.mod h1:fjS8r9mqDVsPb5td3NehsNOAWa4uiFkYEfVZioQ2gH0= -github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= -github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= -github.com/ovh/go-ovh v1.4.3 h1:Gs3V823zwTFpzgGLZNI6ILS4rmxZgJwJCz54Er9LwD0= -github.com/ovh/go-ovh v1.4.3/go.mod h1:AkPXVtgwB6xlKblMjRKJJmjRp+ogrE7fz2lVgcQY8SY= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= -github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI= -github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus-community/windows_exporter v0.25.1 h1:sagNoaBC1TirUNt8YE4eIpeDNQbswrRHsMxvluYHbyU= -github.com/prometheus-community/windows_exporter v0.25.1/go.mod h1:fmM+2zsneBex4oamnr5YHzikZ+34Zhkxg7h3fZVtDWY= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -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-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/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.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= -github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= -github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= -github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/prometheus v0.51.2-0.20240405174432-b4a973753c6e h1:UmqAuY2OyDoog8+l5FybViJE5B2r+UxVGCUwFTsY5AA= -github.com/prometheus/prometheus v0.51.2-0.20240405174432-b4a973753c6e/go.mod h1:+0ld+ozir7zWFcHA2vVpWAKxXakIioEjPPNOqH+J3ZA= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -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.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= -github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= -github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= -github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.25 h1:/8rfZAdFfafRXOgz+ZpMZZWZ5pYggCY9t7e/BvjaBHM= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.25/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= -github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= -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 v1.7.1 h1:UJcjSAI3aUKx52kfcfhblgyhZceouhvvs3OYdWgn+PY= -github.com/shoenig/test v1.7.1/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI= -github.com/signalfx/sapm-proto v0.14.0 h1:KWh3I5E4EkelB19aP1/54Ik8khSioC/RVRW/riOfRGg= -github.com/signalfx/sapm-proto v0.14.0/go.mod h1:Km6PskZh966cqNoUn3AmRyGRix5VfwnxVBvn2vjRC9U= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= -github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -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 v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -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/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= -github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -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/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -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/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/testcontainers/testcontainers-go v0.31.0 h1:W0VwIhcEVhRflwL9as3dhY6jXjVCA27AkmbnZ+UTh3U= -github.com/testcontainers/testcontainers-go v0.31.0/go.mod h1:D2lAoA0zUFiSY+eAflqK5mcUx/A5hrrORaEQrd0SefI= -github.com/tidwall/gjson v1.14.2 h1:6BBkirS0rAHjumnjHF6qgy5d2YAJ1TLIaFE2lzfOLqo= -github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/tinylru v1.1.0 h1:XY6IUfzVTU9rpwdhKUF6nQdChgCdGjkMfLzbWyiau6I= -github.com/tidwall/tinylru v1.1.0/go.mod h1:3+bX+TJ2baOLMWTnlyNWHh4QMnFyARg2TLTQ6OFbzw8= -github.com/tidwall/wal v1.1.7 h1:emc1TRjIVsdKKSnpwGBAcsAGg0767SvUk8+ygx7Bb+4= -github.com/tidwall/wal v1.1.7/go.mod h1:r6lR1j27W9EPalgHiB7zLJDYu3mzW5BQP5KrzBpYY/E= -github.com/tilinna/clock v1.1.0 h1:6IQQQCo6KoBxVudv6gwtY8o4eDfhHo8ojA5dP0MfhSs= -github.com/tilinna/clock v1.1.0/go.mod h1:ZsP7BcY7sEEz7ktc0IVy8Us6boDrK8VradlKRUGfOao= -github.com/tinylib/msgp v1.1.9 h1:SHf3yoO2sGA0veCJeCBYLHuttAVFHGm2RHgNodW7wQU= -github.com/tinylib/msgp v1.1.9/go.mod h1:BCXGB54lDD8qUEPmiG0cQQUANC4IUQyB2ItS2UDlO/k= -github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= -github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= -github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= -github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= -github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= -github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -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.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -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/confmap/converter/expandconverter v0.104.0 h1:7BhJk71V8xhm8wUpuHG4CVRAPu8JajKj8VmGZ6zS7SA= -go.opentelemetry.io/collector/confmap/converter/expandconverter v0.104.0/go.mod h1:o2xTZJpc65SyYPOAGOjyvWwQEqYSWT4Q4/gMfOYpAzc= -go.opentelemetry.io/collector/confmap/provider/envprovider v0.104.0 h1:/3iSlUHH1Q3xeZc55oVekd4dibXzqgphXZI7EaYJ+ak= -go.opentelemetry.io/collector/confmap/provider/envprovider v0.104.0/go.mod h1:RZDXvP81JwvIGeq3rvDBrRKMUfn2BeKCmppHm4Qm0D8= -go.opentelemetry.io/collector/confmap/provider/fileprovider v0.104.0 h1:B+nMVlIUQxuP52CZSegGuA2z9S+Cv2XwFb2a/TLFPhc= -go.opentelemetry.io/collector/confmap/provider/fileprovider v0.104.0/go.mod h1:O0RcaP/I/kn7JHrwohUfj6AwvQYLxjbqg/HnjkvLLTw= -go.opentelemetry.io/collector/confmap/provider/httpprovider v0.104.0 h1:6UreSAu64Ft3VfKWE3sjcmf+mWMyWemSsrjS/fjRPpQ= -go.opentelemetry.io/collector/confmap/provider/httpprovider v0.104.0/go.mod h1:+vP6R5i9h+oYJNjp4bQHvtSHEu1t+CgSKIeZYZZRQXA= -go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.104.0 h1:itBGhyEbX+iz8kz3nc4PYxQx4bL7y87xXNUcGnbKPuY= -go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.104.0/go.mod h1:iPVsTBkRFHZ21UEfSGWk8c4maOzTp6BWWpTk+l6PjJI= -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/loggingexporter v0.104.0 h1:MaBTuHmK/HAQ+/rLTrGf3tazKum8Sic3/CaXgNr5xnc= -go.opentelemetry.io/collector/exporter/loggingexporter v0.104.0/go.mod h1:sXZhACvds6z71cf2fzKrojMgdJItJZxeClKlF/PI/l8= -go.opentelemetry.io/collector/exporter/nopexporter v0.104.0 h1:33JeCQiJbvhSXFqQ34R4ole/wD4iHtF5LYp2GziYVnY= -go.opentelemetry.io/collector/exporter/nopexporter v0.104.0/go.mod h1:73afhI8uc5NKAl9pMJlgQQ46Ck9e7nQ2zZGXHHSzuwo= -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/filter v0.104.0 h1:6BkLJuqWtWFdXHEgbn4TpK5d7Ha5aMdDhLmdvZ6VHxk= -go.opentelemetry.io/collector/filter v0.104.0/go.mod h1:l9+6CTcA0wHOg+J3HSereMuXy47cHPGiHevCun0SbNM= -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/otelcol/otelcoltest v0.104.0 h1:duPbOTahDcDP+XupC/KkHvebb8+NVKh7LzIpiEuKwLU= -go.opentelemetry.io/collector/otelcol/otelcoltest v0.104.0/go.mod h1:cNosA2o77fGp2N4Ofs5h6HBdHhlPQAbKBjBIc1l+8O4= -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/processor/batchprocessor v0.104.0 h1:6xXvHYkPjwM1zdzliDM2H/omTGgIOkY96JTCln7CFZQ= -go.opentelemetry.io/collector/processor/batchprocessor v0.104.0/go.mod h1:f1VfVdiOlqtJDAvQy8YONEee19nJ3haxNeiMPy59w8M= -go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.104.0 h1:bfxUNxP2i41Dpdp5cXwVuh4ZIQ8g6e4NDnu5HakWQw4= -go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.104.0/go.mod h1:2HtP0f+EBu99Uq07JF20fa2FKAsjnIieOZ4f9Jysfpc= -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/receiver/nopreceiver v0.104.0 h1:xkfiTIGEXMXosYbZe8C8tIEZiw+gEL8QhCxz8slSYcM= -go.opentelemetry.io/collector/receiver/nopreceiver v0.104.0/go.mod h1:9vZPqdvOBDh9fKugWiv8WIINkF+TFpOw7RhvZxctZ9w= -go.opentelemetry.io/collector/receiver/otlpreceiver v0.104.0 h1:t9cACuSc7kY09guws7VyB/z9QnG7/zWLC1NQ29WH4+o= -go.opentelemetry.io/collector/receiver/otlpreceiver v0.104.0/go.mod h1:sPIIO4F6uit1i/XQgfe2WryvdO5Hr16bQgZTaXcR8mM= -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/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -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/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -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/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -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.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= -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/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.185.0 h1:ENEKk1k4jW8SmmaT6RE+ZasxmxezCrD5Vw4npvr+pAU= -google.golang.org/api v0.185.0/go.mod h1:HNfvIkJGlgrIlrbYkAm9W9IdkmKZjOTVh33YltygGbg= -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/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d h1:Aqf0fiIdUQEj0Gn9mKFFXoQfTTEaNopWpfVyYADxiSg= -google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Od4k8V1LQSizPRUK4OzZ7TBE/20k+jPczUDAEyvn69Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -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.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -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.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -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= -gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I= -gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= -k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw= -k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80= -k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= -k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU= -k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU= -k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= -k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg= -k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0= -k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= -k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/comp/otelcol/logsagentpipeline/go.mod b/comp/otelcol/logsagentpipeline/go.mod index d6074b90aad42..b5adb734302e7 100644 --- a/comp/otelcol/logsagentpipeline/go.mod +++ b/comp/otelcol/logsagentpipeline/go.mod @@ -17,6 +17,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../pkg/config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../../pkg/config/utils @@ -98,7 +99,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/system/socket v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/winutil v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/version v0.56.0-rc.3 // indirect - github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe // indirect + github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 // indirect github.com/DataDog/viper v1.13.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/benbjohnson/clock v1.3.5 // indirect @@ -148,17 +149,17 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/comp/otelcol/logsagentpipeline/go.sum b/comp/otelcol/logsagentpipeline/go.sum index 8ffcc43e6b943..a9a19f40f3cb2 100644 --- a/comp/otelcol/logsagentpipeline/go.sum +++ b/comp/otelcol/logsagentpipeline/go.sum @@ -41,8 +41,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/agent-payload/v5 v5.0.106 h1:A3dGX+JYoL7OJe2crpxznW7hWxLxhOk/17WbYskRWVk= github.com/DataDog/agent-payload/v5 v5.0.106/go.mod h1:COngtbYYCncpIPiE5D93QlXDH/3VAKk10jDNwGHcMRE= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe h1:efzxujZ7VHWFxjmWjcJyUEpPrN8qdiZPYb+dBw547Wo= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 h1:RoH7VLzTnxHEugRPIgnGlxwDFszFGI7b3WZZUtWuPRM= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= github.com/DataDog/viper v1.13.5 h1:SZMcyMknYQN2jRY/40A16gUXexlNJOI8sDs1cWZnI64= github.com/DataDog/viper v1.13.5/go.mod h1:wDdUVJ2SHaMaPrCZrlRCObwkubsX8j5sme3LaR/SGTc= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -371,10 +371,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -404,8 +404,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -468,8 +468,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -537,8 +537,8 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -548,8 +548,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -607,8 +607,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.mod b/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.mod index 879a347efb9ae..471ae801b59bb 100644 --- a/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.mod +++ b/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.mod @@ -18,6 +18,7 @@ replace ( github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline => ../../logsagentpipeline github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../../pkg/config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../../../pkg/config/utils @@ -79,7 +80,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/startstop v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/util/testutil v0.56.0-rc.3 github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.18.2 + go.uber.org/fx v1.22.2 go.uber.org/zap v1.27.0 ) @@ -92,6 +93,7 @@ require ( github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel // indirect github.com/DataDog/datadog-agent/pkg/config/utils v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/logs/processor v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/logs/sds v0.56.0-rc.3 // indirect @@ -112,7 +114,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/system/socket v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/winutil v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/version v0.56.0-rc.3 // indirect - github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe // indirect + github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 // indirect github.com/DataDog/viper v1.13.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/benbjohnson/clock v1.3.5 // indirect @@ -161,15 +163,15 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect + go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum b/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum index c9621a727cc1c..ecc6e5a04d3a6 100644 --- a/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum +++ b/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum @@ -41,8 +41,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/agent-payload/v5 v5.0.106 h1:A3dGX+JYoL7OJe2crpxznW7hWxLxhOk/17WbYskRWVk= github.com/DataDog/agent-payload/v5 v5.0.106/go.mod h1:COngtbYYCncpIPiE5D93QlXDH/3VAKk10jDNwGHcMRE= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe h1:efzxujZ7VHWFxjmWjcJyUEpPrN8qdiZPYb+dBw547Wo= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 h1:RoH7VLzTnxHEugRPIgnGlxwDFszFGI7b3WZZUtWuPRM= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= github.com/DataDog/viper v1.13.5 h1:SZMcyMknYQN2jRY/40A16gUXexlNJOI8sDs1cWZnI64= github.com/DataDog/viper v1.13.5/go.mod h1:wDdUVJ2SHaMaPrCZrlRCObwkubsX8j5sme3LaR/SGTc= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -372,10 +372,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -405,8 +405,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -469,8 +469,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -538,8 +538,8 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -549,8 +549,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -608,8 +608,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/comp/otelcol/otlp/collector.go b/comp/otelcol/otlp/collector.go index ae3f84e587243..e3978764031e5 100644 --- a/comp/otelcol/otlp/collector.go +++ b/comp/otelcol/otlp/collector.go @@ -27,6 +27,8 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" + otlpmetrics "github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/metrics" + "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/comp/core/tagger" "github.com/DataDog/datadog-agent/comp/core/tagger/types" @@ -42,7 +44,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/util/log" zapAgent "github.com/DataDog/datadog-agent/pkg/util/log/zap" "github.com/DataDog/datadog-agent/pkg/version" - otlpmetrics "github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/metrics" ) var pipelineError = atomic.NewError(nil) @@ -247,7 +248,7 @@ func recoverAndStoreError() { if r := recover(); r != nil { err := fmt.Errorf("OTLP pipeline had a panic: %v", r) pipelineError.Store(err) - log.Errorf(err.Error()) + log.Errorf("%s", err.Error()) } } diff --git a/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod b/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod index 79edbfd4d5c62..8857c8dcff0c4 100644 --- a/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod +++ b/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod @@ -31,6 +31,7 @@ replace ( github.com/DataDog/datadog-agent/pkg/aggregator/ckey => ../../../../../../pkg/aggregator/ckey github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../../../../pkg/config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../../../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../../../../../pkg/config/utils @@ -138,6 +139,7 @@ require ( github.com/DataDog/datadog-agent/pkg/aggregator/ckey v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel // indirect github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/setup v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/utils v0.56.0-rc.3 // indirect @@ -182,7 +184,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/winutil v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/version v0.56.0-rc.3 // indirect github.com/DataDog/datadog-api-client-go/v2 v2.26.0 // indirect - github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe // indirect + github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 // indirect github.com/DataDog/go-sqllexer v0.0.13 // indirect github.com/DataDog/go-tuf v1.1.0-0.5.2 // indirect github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 // indirect @@ -285,15 +287,15 @@ require ( go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e // indirect google.golang.org/grpc v1.64.0 // indirect diff --git a/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum b/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum index 1e7aa021d45aa..e60a093490cb1 100644 --- a/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum +++ b/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum @@ -6,8 +6,8 @@ github.com/DataDog/datadog-api-client-go/v2 v2.26.0 h1:bZr0hu+hx8L91+yU5EGw8wK3F github.com/DataDog/datadog-api-client-go/v2 v2.26.0/go.mod h1:QKOu6vscsh87fMY1lHfLEmNSunyXImj8BUaUWJXOehc= github.com/DataDog/datadog-go/v5 v5.5.0 h1:G5KHeB8pWBNXT4Jtw0zAkhdxEAWSpWH00geHI6LDrKU= github.com/DataDog/datadog-go/v5 v5.5.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe h1:efzxujZ7VHWFxjmWjcJyUEpPrN8qdiZPYb+dBw547Wo= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 h1:RoH7VLzTnxHEugRPIgnGlxwDFszFGI7b3WZZUtWuPRM= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= github.com/DataDog/go-sqllexer v0.0.13 h1:9mKfe+3s73GI/7dWBxi2Ds7+xZynJqMKK9cIUBrutak= github.com/DataDog/go-sqllexer v0.0.13/go.mod h1:KwkYhpFEVIq+BfobkTC1vfqm4gTi65skV/DpDBXtexc= github.com/DataDog/go-tuf v1.1.0-0.5.2 h1:4CagiIekonLSfL8GMHRHcHudo1fQnxELS9g4tiAupQ4= @@ -450,10 +450,10 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -470,11 +470,11 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 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/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -497,8 +497,8 @@ golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLL 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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -530,15 +530,15 @@ golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= 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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= diff --git a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod index 5695efb6ef844..e689f59dd1341 100644 --- a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod +++ b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod @@ -14,6 +14,7 @@ replace ( github.com/DataDog/datadog-agent/comp/otelcol/otlp/testutil => ../../../../../../comp/otelcol/otlp/testutil github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../../../../pkg/config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../../../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../../../../../pkg/config/utils @@ -148,12 +149,12 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // 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 diff --git a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum index bcbf7f51d5bdc..35e04032d9e4c 100644 --- a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum +++ b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum @@ -328,10 +328,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -350,8 +350,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -377,8 +377,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -413,19 +413,19 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod b/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod index 71de11f84f1cd..14c69501c50af 100644 --- a/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod +++ b/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod @@ -20,6 +20,7 @@ replace ( github.com/DataDog/datadog-agent/pkg/aggregator/ckey => ../../../../../../pkg/aggregator/ckey github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../../../../pkg/config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../../../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../../../../../pkg/config/utils @@ -101,6 +102,7 @@ require ( github.com/DataDog/datadog-agent/pkg/aggregator/ckey v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel // indirect github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/setup v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/utils v0.56.0-rc.3 // indirect @@ -198,16 +200,16 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // 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 diff --git a/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum b/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum index c89a520016b4b..cc8e3ecec4203 100644 --- a/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum +++ b/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum @@ -29,8 +29,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -374,10 +372,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -396,8 +394,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -425,8 +423,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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= @@ -461,8 +459,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -470,8 +468,8 @@ 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -490,8 +488,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/comp/otelcol/otlp/components/metricsclient/go.mod b/comp/otelcol/otlp/components/metricsclient/go.mod index 3a4f2a0e2d406..d26aef015d46e 100644 --- a/comp/otelcol/otlp/components/metricsclient/go.mod +++ b/comp/otelcol/otlp/components/metricsclient/go.mod @@ -24,7 +24,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/comp/otelcol/otlp/components/metricsclient/go.sum b/comp/otelcol/otlp/components/metricsclient/go.sum index 5ae840a108349..cd98d136c9692 100644 --- a/comp/otelcol/otlp/components/metricsclient/go.sum +++ b/comp/otelcol/otlp/components/metricsclient/go.sum @@ -50,8 +50,8 @@ golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= @@ -63,16 +63,16 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/comp/otelcol/otlp/components/statsprocessor/agent_test.go b/comp/otelcol/otlp/components/statsprocessor/agent_test.go index 8810c0513abcc..cf24fba275034 100644 --- a/comp/otelcol/otlp/components/statsprocessor/agent_test.go +++ b/comp/otelcol/otlp/components/statsprocessor/agent_test.go @@ -89,9 +89,13 @@ func TestTraceAgent(t *testing.T) { case stats = <-out: if len(stats.Stats) != 0 { require.Len(t, stats.Stats, 1) - require.Len(t, stats.Stats[0].Stats, 1) - assert.Greater(t, len(stats.Stats[0].Stats[0].Stats), 0) - actual = append(actual, stats.Stats[0].Stats[0].Stats...) + cspayload := stats.Stats[0] + // stats can be in one or multiple buckets + assert.Greater(t, len(cspayload.Stats), 0) + for _, bucket := range cspayload.Stats { + assert.Greater(t, len(bucket.Stats), 0) + actual = append(actual, bucket.Stats...) + } } case <-timeout: t.Fatal("timed out") diff --git a/comp/otelcol/otlp/components/statsprocessor/go.mod b/comp/otelcol/otlp/components/statsprocessor/go.mod index 10eaecf69c553..50b1bae9469db 100644 --- a/comp/otelcol/otlp/components/statsprocessor/go.mod +++ b/comp/otelcol/otlp/components/statsprocessor/go.mod @@ -91,12 +91,12 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // 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 diff --git a/comp/otelcol/otlp/components/statsprocessor/go.sum b/comp/otelcol/otlp/components/statsprocessor/go.sum index d04b9f5c249c8..dcf72c47c645c 100644 --- a/comp/otelcol/otlp/components/statsprocessor/go.sum +++ b/comp/otelcol/otlp/components/statsprocessor/go.sum @@ -193,8 +193,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= 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/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -210,8 +210,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/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= @@ -238,8 +238,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -247,8 +247,8 @@ 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -258,8 +258,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/comp/otelcol/otlp/integrationtest/integration_test.go b/comp/otelcol/otlp/integrationtest/integration_test.go index 787e535660c86..e0c6a5e86034a 100644 --- a/comp/otelcol/otlp/integrationtest/integration_test.go +++ b/comp/otelcol/otlp/integrationtest/integration_test.go @@ -80,10 +80,10 @@ import ( func runTestOTelAgent(ctx context.Context, params *subcommands.GlobalParams) error { return fxutil.Run( - forwarder.Bundle(), + forwarder.BundleWithProvider(defaultforwarder.NewParams), logtrace.Module(), inventoryagentimpl.Module(), - workloadmetafx.Module(), + workloadmetafx.Module(workloadmeta.NewParams()), fx.Supply(metricsclient.NewStatsdClientWrapper(&ddgostatsd.NoOpClient{})), fx.Provide(func(client *metricsclient.StatsdClientWrapper) statsd.Component { return statsd.NewOTelStatsd(client) @@ -105,9 +105,6 @@ func runTestOTelAgent(ctx context.Context, params *subcommands.GlobalParams) err pkgconfigenv.DetectFeatures(c) return c, nil }), - fx.Provide(func() workloadmeta.Params { - return workloadmeta.NewParams() - }), fx.Provide(func() []string { return append(params.ConfPaths, params.Sets...) }), @@ -132,7 +129,6 @@ func runTestOTelAgent(ctx context.Context, params *subcommands.GlobalParams) err return s }), fx.Supply("test-host"), - fx.Provide(defaultforwarder.NewParams), fx.Provide(func(c defaultforwarder.Component) (defaultforwarder.Forwarder, error) { return defaultforwarder.Forwarder(c), nil }), diff --git a/comp/otelcol/otlp/testutil/go.mod b/comp/otelcol/otlp/testutil/go.mod index 2d893aa1ebc74..cd00e6506c335 100644 --- a/comp/otelcol/otlp/testutil/go.mod +++ b/comp/otelcol/otlp/testutil/go.mod @@ -94,11 +94,10 @@ require ( github.com/yusufpapurcu/wmi v1.2.4 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.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 google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect google.golang.org/grpc v1.64.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/comp/otelcol/otlp/testutil/go.sum b/comp/otelcol/otlp/testutil/go.sum index 44ccb79a64b6b..b4d06b630c428 100644 --- a/comp/otelcol/otlp/testutil/go.sum +++ b/comp/otelcol/otlp/testutil/go.sum @@ -264,10 +264,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -286,8 +286,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -313,8 +313,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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= @@ -345,8 +345,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -354,8 +354,8 @@ 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/comp/process/agent/status_test.go b/comp/process/agent/status_test.go index 0122262e4c052..355411fabb930 100644 --- a/comp/process/agent/status_test.go +++ b/comp/process/agent/status_test.go @@ -14,7 +14,6 @@ import ( "testing" "github.com/DataDog/datadog-agent/comp/core/config" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -44,7 +43,7 @@ func TestStatus(t *testing.T) { server := fakeStatusServer(t, 200, jsonBytes) defer server.Close() - configComponent := fxutil.Test[config.Component](t, config.MockModule()) + configComponent := config.NewMock(t) headerProvider := StatusProvider{ testServerURL: server.URL, @@ -97,7 +96,7 @@ func TestStatusError(t *testing.T) { errorResponse, err := fixturesTemplates.ReadFile("fixtures/text_error_response.tmpl") assert.NoError(t, err) - configComponent := fxutil.Test[config.Component](t, config.MockModule()) + configComponent := config.NewMock(t) headerProvider := StatusProvider{ testServerURL: server.URL, diff --git a/comp/process/apiserver/apiserver_test.go b/comp/process/apiserver/apiserver_test.go index 1c19cc7c91cb0..8719f3d8db91d 100644 --- a/comp/process/apiserver/apiserver_test.go +++ b/comp/process/apiserver/apiserver_test.go @@ -26,8 +26,7 @@ func TestLifecycle(t *testing.T) { _ = fxutil.Test[Component](t, fx.Options( Module(), core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafx.Module(), + workloadmetafx.Module(workloadmeta.NewParams()), fx.Supply( status.Params{ PythonVersionGetFunc: func() string { return "n/a" }, diff --git a/comp/process/bundle_test.go b/comp/process/bundle_test.go index dc39090d6f6e7..1c95f526f423a 100644 --- a/comp/process/bundle_test.go +++ b/comp/process/bundle_test.go @@ -40,10 +40,9 @@ var mockCoreBundleParams = core.BundleParams{ func TestBundleDependencies(t *testing.T) { fxutil.TestBundle(t, Bundle(), fx.Supply(mockCoreBundleParams), - fx.Supply(workloadmeta.NewParams()), fx.Provide(func() types.CheckComponent { return nil }), core.MockBundle(), - workloadmetafx.Module(), + workloadmetafx.Module(workloadmeta.NewParams()), coreStatusImpl.Module(), settingsimpl.MockModule(), statusimpl.Module(), @@ -90,11 +89,9 @@ func TestBundleOneShot(t *testing.T) { "hostname": "testhost", }}), core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafx.Module(), + workloadmetafx.Module(workloadmeta.NewParams()), eventplatformreceiverimpl.Module(), - eventplatformimpl.Module(), - fx.Supply(eventplatformimpl.NewDefaultParams()), + eventplatformimpl.Module(eventplatformimpl.NewDefaultParams()), npcollectorimpl.Module(), statsd.MockModule(), Bundle(), diff --git a/comp/process/runner/runnerimpl/runner_test.go b/comp/process/runner/runnerimpl/runner_test.go index 1257df2bab329..023dba2ad4172 100644 --- a/comp/process/runner/runnerimpl/runner_test.go +++ b/comp/process/runner/runnerimpl/runner_test.go @@ -120,8 +120,7 @@ func createDeps(t *testing.T, options ...fx.Option) Deps { containercheckimpl.MockModule(), core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafx.Module(), + workloadmetafx.Module(workloadmeta.NewParams()), fx.Options(options...), )) } diff --git a/comp/process/status/statusimpl/status_test.go b/comp/process/status/statusimpl/status_test.go index a3bd612c618fe..6f8fd2071b1a4 100644 --- a/comp/process/status/statusimpl/status_test.go +++ b/comp/process/status/statusimpl/status_test.go @@ -14,7 +14,6 @@ import ( "testing" "github.com/DataDog/datadog-agent/comp/core/config" - "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -44,7 +43,7 @@ func TestStatus(t *testing.T) { server := fakeStatusServer(t, 200, jsonBytes) defer server.Close() - configComponent := fxutil.Test[config.Component](t, config.MockModule()) + configComponent := config.NewMock(t) headerProvider := statusProvider{ testServerURL: server.URL, @@ -98,7 +97,7 @@ func TestStatusError(t *testing.T) { errorResponse, err := fixturesTemplates.ReadFile("fixtures/text_error_response.tmpl") assert.NoError(t, err) - configComponent := fxutil.Test[config.Component](t, config.MockModule()) + configComponent := config.NewMock(t) headerProvider := statusProvider{ testServerURL: server.URL, diff --git a/comp/rdnsquerier/impl/rdnsquerier_test.go b/comp/rdnsquerier/impl/rdnsquerier_test.go index 54ecbdc8d8fc4..fb5102e511815 100644 --- a/comp/rdnsquerier/impl/rdnsquerier_test.go +++ b/comp/rdnsquerier/impl/rdnsquerier_test.go @@ -678,7 +678,7 @@ func TestRetriesExceeded(t *testing.T) { func(_ string) { assert.FailNow(t, "Sync callback should not be called") }, - func(hostname string, err error) { + func(_ string, err error) { assert.Error(t, err) wg.Done() }, diff --git a/comp/remote-config/rctelemetryreporter/rctelemetryreporterimpl/rctelemetryreporter.go b/comp/remote-config/rctelemetryreporter/rctelemetryreporterimpl/rctelemetryreporter.go index 476af2e258eae..34c2658f07c3d 100644 --- a/comp/remote-config/rctelemetryreporter/rctelemetryreporterimpl/rctelemetryreporter.go +++ b/comp/remote-config/rctelemetryreporter/rctelemetryreporterimpl/rctelemetryreporter.go @@ -35,12 +35,16 @@ type DdRcTelemetryReporter struct { // IncRateLimit increments the DdRcTelemetryReporter BypassRateLimitCounter counter. func (r *DdRcTelemetryReporter) IncRateLimit() { - r.BypassRateLimitCounter.Inc() + if r.BypassRateLimitCounter != nil { + r.BypassRateLimitCounter.Inc() + } } // IncTimeout increments the DdRcTelemetryReporter BypassTimeoutCounter counter. func (r *DdRcTelemetryReporter) IncTimeout() { - r.BypassTimeoutCounter.Inc() + if r.BypassTimeoutCounter != nil { + r.BypassTimeoutCounter.Inc() + } } // newDdRcTelemetryReporter creates a new Remote Config telemetry reporter for sending RC metrics to Datadog diff --git a/comp/serializer/compression/go.mod b/comp/serializer/compression/go.mod index de991ab0b44da..efb7938bcb160 100644 --- a/comp/serializer/compression/go.mod +++ b/comp/serializer/compression/go.mod @@ -13,6 +13,7 @@ replace ( github.com/DataDog/datadog-agent/comp/def => ../../def github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../pkg/collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../pkg/config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../pkg/config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../pkg/config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../../pkg/config/setup github.com/DataDog/datadog-agent/pkg/telemetry => ../../../pkg/telemetry @@ -35,7 +36,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/fxutil v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/util/log v0.56.0-rc.3 github.com/DataDog/zstd v1.5.5 - go.uber.org/fx v1.18.2 + go.uber.org/fx v1.22.2 ) require ( @@ -45,6 +46,7 @@ require ( github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel // indirect github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/setup v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/executable v0.56.0-rc.3 // indirect @@ -85,15 +87,15 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/comp/serializer/compression/go.sum b/comp/serializer/compression/go.sum index 4232b9ae9a0bb..f283093babdbd 100644 --- a/comp/serializer/compression/go.sum +++ b/comp/serializer/compression/go.sum @@ -14,8 +14,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -240,27 +238,27 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -303,11 +301,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -320,8 +318,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/comp/snmptraps/forwarder/forwarderimpl/forwarder.go b/comp/snmptraps/forwarder/forwarderimpl/forwarder.go index c31e9a4f0a592..52f0c5113078a 100644 --- a/comp/snmptraps/forwarder/forwarderimpl/forwarder.go +++ b/comp/snmptraps/forwarder/forwarderimpl/forwarder.go @@ -98,7 +98,8 @@ func (tf *trapForwarder) Stop() { } func (tf *trapForwarder) run() { - flushTicker := time.NewTicker(10 * time.Second).C + flushTicker := time.NewTicker(10 * time.Second) + defer flushTicker.Stop() for { select { case <-tf.stopChan: @@ -106,7 +107,7 @@ func (tf *trapForwarder) run() { return case packet := <-tf.trapsIn: tf.sendTrap(packet) - case <-flushTicker: + case <-flushTicker.C: tf.sender.Commit() // Commit metrics } } diff --git a/comp/systray/systray/systrayimpl/doconfigure.go b/comp/systray/systray/systrayimpl/doconfigure.go index 76917b51df7f0..31883325861da 100644 --- a/comp/systray/systray/systrayimpl/doconfigure.go +++ b/comp/systray/systray/systrayimpl/doconfigure.go @@ -8,8 +8,10 @@ package systrayimpl import ( "fmt" + "net" apiutil "github.com/DataDog/datadog-agent/pkg/api/util" + "github.com/DataDog/datadog-agent/pkg/util/system" ) func onConfigure(s *systrayImpl) { @@ -28,6 +30,14 @@ func doConfigure(s *systrayImpl) error { return fmt.Errorf("GUI not enabled: to enable, please set an appropriate port in your datadog.yaml file") } + // 'http://localhost' is preferred over 'http://127.0.0.1' due to Internet Explorer behavior. + // Internet Explorer High Security Level does not support setting cookies via HTTP Header response. + // By default, 'http://localhost' is categorized as an "intranet" website, which is considered safer and allowed to use cookies. This is not the case for 'http://127.0.0.1'. + guiHost, err := system.IsLocalAddress(s.config.GetString("GUI_host")) + if err != nil { + return fmt.Errorf("GUI server host is not a local address: %s", err) + } + endpoint, err := apiutil.NewIPCEndpoint(s.config, "/agent/gui/intent") if err != nil { return err @@ -38,12 +48,14 @@ func doConfigure(s *systrayImpl) error { return err } + guiAddress := net.JoinHostPort(guiHost, guiPort) + // Open the GUI in a browser, passing the authorization tokens as parameters - err = open("http://127.0.0.1:" + guiPort + "/auth?intent=" + string(intentToken)) + err = open("http://" + guiAddress + "/auth?intent=" + string(intentToken)) if err != nil { - return fmt.Errorf("error opening GUI: " + err.Error()) + return fmt.Errorf("error opening GUI: %s", err.Error()) } - s.log.Debugf("GUI opened at 127.0.0.1:" + guiPort + "\n") + s.log.Debugf("GUI opened at %s\n", guiAddress) return nil } diff --git a/comp/trace/agent/def/go.mod b/comp/trace/agent/def/go.mod index e3e82cd3eed5c..3647b991a6acd 100644 --- a/comp/trace/agent/def/go.mod +++ b/comp/trace/agent/def/go.mod @@ -33,9 +33,9 @@ require ( go.opentelemetry.io/otel/trace v1.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // 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 google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect google.golang.org/grpc v1.64.0 // indirect google.golang.org/protobuf v1.34.1 // indirect diff --git a/comp/trace/agent/def/go.sum b/comp/trace/agent/def/go.sum index b8a71f025c90b..99ed13405a9d9 100644 --- a/comp/trace/agent/def/go.sum +++ b/comp/trace/agent/def/go.sum @@ -111,8 +111,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/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= @@ -126,8 +126,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -135,8 +135,8 @@ 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= diff --git a/comp/trace/agent/impl/agent.go b/comp/trace/agent/impl/agent.go index 1005283b808a4..e3cde73dec0bb 100644 --- a/comp/trace/agent/impl/agent.go +++ b/comp/trace/agent/impl/agent.go @@ -30,7 +30,7 @@ import ( traceagent "github.com/DataDog/datadog-agent/comp/trace/agent/def" compression "github.com/DataDog/datadog-agent/comp/trace/compression/def" "github.com/DataDog/datadog-agent/comp/trace/config" - coreconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/pidfile" pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" agentrt "github.com/DataDog/datadog-agent/pkg/runtime" @@ -161,7 +161,7 @@ func prepGoRuntime(tracecfg *tracecfg.AgentConfig) { } log.Infof("Trace Agent final GOMAXPROCS: %v", runtime.GOMAXPROCS(0)) - cgmem, err := agentrt.SetGoMemLimit(coreconfig.IsContainerized()) + cgmem, err := agentrt.SetGoMemLimit(env.IsContainerized()) if err != nil { log.Infof("Couldn't set Go memory limit from cgroup: %s", err) } diff --git a/comp/trace/bundle_test.go b/comp/trace/bundle_test.go index f4037b6816796..69bd1346c4158 100644 --- a/comp/trace/bundle_test.go +++ b/comp/trace/bundle_test.go @@ -38,8 +38,7 @@ func TestBundleDependencies(t *testing.T) { fx.Provide(func() context.Context { return context.TODO() }), // fx.Supply(ctx) fails with a missing type error. fx.Supply(core.BundleParams{}), core.Bundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafx.Module(), + workloadmetafx.Module(workloadmeta.NewParams()), statsd.Module(), fx.Provide(func(cfg config.Component) telemetry.TelemetryCollector { return telemetry.NewCollector(cfg.Object()) }), fx.Supply(tagger.NewFakeTaggerParams()), @@ -66,8 +65,7 @@ func TestMockBundleDependencies(t *testing.T) { coreconfig.MockModule(), telemetryimpl.MockModule(), fx.Provide(func() log.Component { return logmock.New(t) }), - fx.Supply(workloadmeta.NewParams()), - workloadmetafx.Module(), + workloadmetafx.Module(workloadmeta.NewParams()), fx.Invoke(func(_ config.Component) {}), fx.Provide(func(cfg config.Component) telemetry.TelemetryCollector { return telemetry.NewCollector(cfg.Object()) }), statsd.MockModule(), diff --git a/comp/trace/config/config.go b/comp/trace/config/config.go index e5d678d4a7255..a2347ee3e62a8 100644 --- a/comp/trace/config/config.go +++ b/comp/trace/config/config.go @@ -18,6 +18,7 @@ import ( coreconfig "github.com/DataDog/datadog-agent/comp/core/config" apiutil "github.com/DataDog/datadog-agent/pkg/api/util" pkgconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/config/model" pkgconfigutils "github.com/DataDog/datadog-agent/pkg/config/utils" traceconfig "github.com/DataDog/datadog-agent/pkg/trace/config" @@ -60,7 +61,7 @@ func newConfig(deps dependencies) (Component, error) { AgentConfig: tracecfg, coreConfig: deps.Config, } - c.SetMaxMemCPU(pkgconfig.IsContainerized()) + c.SetMaxMemCPU(env.IsContainerized()) return &c, nil } diff --git a/comp/trace/config/config_mock.go b/comp/trace/config/config_mock.go index 13052fccd9fe1..4e07d76c107ea 100644 --- a/comp/trace/config/config_mock.go +++ b/comp/trace/config/config_mock.go @@ -12,6 +12,7 @@ import ( "testing" pkgconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" ) // newMock exported mock builder to allow modifying mocks that might be @@ -28,7 +29,7 @@ func newMock(deps dependencies, _ testing.TB) (Component, error) { AgentConfig: traceCfg, } - c.SetMaxMemCPU(pkgconfig.IsContainerized()) + c.SetMaxMemCPU(env.IsContainerized()) return &c, nil } diff --git a/comp/trace/config/config_otlp_test.go b/comp/trace/config/config_otlp_test.go index 173b0b3f89131..a15b74ee3bd1b 100644 --- a/comp/trace/config/config_otlp_test.go +++ b/comp/trace/config/config_otlp_test.go @@ -25,8 +25,7 @@ func TestFullYamlConfigWithOTLP(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) diff --git a/comp/trace/config/config_test.go b/comp/trace/config/config_test.go index 1d75bdf19380e..093b90295e106 100644 --- a/comp/trace/config/config_test.go +++ b/comp/trace/config/config_test.go @@ -11,7 +11,6 @@ import ( "context" "encoding/json" "errors" - "html/template" "net/http" "net/http/httptest" "os" @@ -21,6 +20,7 @@ import ( "regexp" "strings" "testing" + "text/template" "time" "github.com/cihub/seelog" @@ -32,6 +32,7 @@ import ( corecomp "github.com/DataDog/datadog-agent/comp/core/config" apiutil "github.com/DataDog/datadog-agent/pkg/api/util" coreconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" traceconfig "github.com/DataDog/datadog-agent/pkg/trace/config" "github.com/DataDog/datadog-agent/pkg/util/fxutil" @@ -144,13 +145,11 @@ func TestSplitTagRegex(t *testing.T) { } func TestTelemetryEndpointsConfig(t *testing.T) { - t.Run("default", func(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -160,7 +159,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { }) t.Run("dd_url", func(t *testing.T) { - overrides := map[string]interface{}{ "apm_config.telemetry.dd_url": "http://example.com/", } @@ -170,7 +168,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -180,7 +177,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { }) t.Run("dd_url-malformed", func(t *testing.T) { - overrides := map[string]interface{}{ "apm_config.telemetry.dd_url": "111://abc.com", } @@ -191,7 +187,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -201,7 +196,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { }) t.Run("site", func(t *testing.T) { - overrides := map[string]interface{}{ "site": "new_site.example.com", } @@ -211,7 +205,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -221,7 +214,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { }) t.Run("additional-hosts", func(t *testing.T) { - additionalEndpoints := map[string]string{ "http://test_backend_2.example.com": "test_apikey_2", "http://test_backend_3.example.com": "test_apikey_3", @@ -235,7 +227,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -250,7 +241,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { }) t.Run("keep-malformed", func(t *testing.T) { - additionalEndpoints := map[string]string{ "11://test_backend_2.example.com": "test_apikey_2", "http://test_backend_3.example.com": "test_apikey_3", @@ -264,7 +254,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -280,7 +269,6 @@ func TestTelemetryEndpointsConfig(t *testing.T) { } func TestConfigHostname(t *testing.T) { - t.Run("fail", func(t *testing.T) { overrides := map[string]interface{}{ "apm_config.dd_agent_bin": "/not/exist", @@ -297,13 +285,11 @@ func TestConfigHostname(t *testing.T) { fxutil.TestStart(t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/site_override.yaml"}, - SetupConfig: true, - Overrides: overrides, + Params: corecomp.Params{ConfFilePath: "./testdata/site_override.yaml"}, + Overrides: overrides, }), MockModule(), ), func(t testing.TB, app *fx.App) { - require.NotNil(t, app) ctx := context.Background() @@ -332,9 +318,8 @@ func TestConfigHostname(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/site_override.yaml"}, - SetupConfig: true, - Overrides: overrides, + Params: corecomp.Params{ConfFilePath: "./testdata/site_override.yaml"}, + Overrides: overrides, }), MockModule(), )) @@ -345,12 +330,10 @@ func TestConfigHostname(t *testing.T) { }) t.Run("file", func(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -362,13 +345,12 @@ func TestConfigHostname(t *testing.T) { }) t.Run("env", func(t *testing.T) { - t.Setenv("XXXX_HOSTNAME", "onlyenv") + t.Setenv("DD_HOSTNAME", "onlyenv") config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/site_override.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/site_override.yaml"}, }), MockModule(), )) @@ -379,13 +361,12 @@ func TestConfigHostname(t *testing.T) { }) t.Run("file+env", func(t *testing.T) { - t.Setenv("XXXX_HOSTNAME", "envoverride") + t.Setenv("DD_HOSTNAME", "envoverride") config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -403,9 +384,8 @@ func TestConfigHostname(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/site_default.yaml"}, - SetupConfig: true, - Overrides: overrides, + Params: corecomp.Params{ConfFilePath: "./testdata/site_default.yaml"}, + Overrides: overrides, }), MockModule(), )) @@ -455,7 +435,6 @@ func TestConfigHostname(t *testing.T) { fallbackHostnameFunc = func() (string, error) { return "fallback.host", nil } t.Run("good", func(t *testing.T) { - bin := makeProgram("host.name", 0) defer os.Remove(bin) @@ -463,7 +442,6 @@ func TestConfigHostname(t *testing.T) { corecomp.MockModule(), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -481,7 +459,6 @@ func TestConfigHostname(t *testing.T) { corecomp.MockModule(), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -499,7 +476,6 @@ func TestConfigHostname(t *testing.T) { MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -517,7 +493,6 @@ func TestConfigHostname(t *testing.T) { corecomp.MockModule(), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -534,7 +509,6 @@ func TestConfigHostname(t *testing.T) { corecomp.MockModule(), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -557,12 +531,10 @@ func TestSite(t *testing.T) { "vector": {"./testdata/observability_pipelines_worker_override.yaml", "https://observability_pipelines_worker.domain.tld:8443"}, } { t.Run(name, func(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: tt.file}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: tt.file}, }), MockModule(), )) @@ -575,7 +547,6 @@ func TestSite(t *testing.T) { } func TestDefaultConfig(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), MockModule(), @@ -600,12 +571,10 @@ func TestDefaultConfig(t *testing.T) { } func TestNoAPMConfig(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/no_apm_config.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/no_apm_config.yaml"}, }), MockModule(), )) @@ -620,12 +589,10 @@ func TestNoAPMConfig(t *testing.T) { } func TestDisableLoggingConfig(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/disable_file_logging.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/disable_file_logging.yaml"}, }), MockModule(), )) @@ -637,12 +604,10 @@ func TestDisableLoggingConfig(t *testing.T) { } func TestFullYamlConfig(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -744,12 +709,10 @@ func TestFullYamlConfig(t *testing.T) { } func TestFileLoggingDisabled(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/disable_file_logging.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/disable_file_logging.yaml"}, }), MockModule(), )) @@ -760,12 +723,10 @@ func TestFileLoggingDisabled(t *testing.T) { } func TestUndocumentedYamlConfig(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/undocumented.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/undocumented.yaml"}, }), MockModule(), )) @@ -816,20 +777,18 @@ func TestAcquireHostnameFallback(t *testing.T) { } func TestNormalizeEnvFromDDEnv(t *testing.T) { - for in, out := range map[string]string{ "staging": "staging", "stAging": "staging", "staging 1": "staging_1", } { t.Run("", func(t *testing.T) { - t.Setenv("XXXX_ENV", in) + t.Setenv("DD_ENV", in) config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/no_apm_config.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/no_apm_config.yaml"}, }), MockModule(), )) @@ -843,7 +802,6 @@ func TestNormalizeEnvFromDDEnv(t *testing.T) { } func TestNormalizeEnvFromDDTags(t *testing.T) { - for in, out := range map[string]string{ "env:staging": "staging", "env:stAging": "staging", @@ -851,13 +809,12 @@ func TestNormalizeEnvFromDDTags(t *testing.T) { "tag:value env:STAGING tag2:value2": "staging", } { t.Run("", func(t *testing.T) { - t.Setenv("XXXX_TAGS", in) + t.Setenv("DD_TAGS", in) config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/no_apm_config.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/no_apm_config.yaml"}, }), MockModule(), )) @@ -871,7 +828,6 @@ func TestNormalizeEnvFromDDTags(t *testing.T) { } func TestNormalizeEnvFromConfig(t *testing.T) { - for _, cfgFile := range []string{ "./testdata/ok_env_apm_config.yaml", "./testdata/ok_env_top_level.yaml", @@ -881,12 +837,10 @@ func TestNormalizeEnvFromConfig(t *testing.T) { "./testdata/non-normalized_env_host_tag.yaml", } { t.Run("", func(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: cfgFile}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: cfgFile}, }), MockModule(), )) @@ -919,8 +873,7 @@ func TestLoadEnv(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -936,15 +889,14 @@ func TestLoadEnv(t *testing.T) { } }) - env := "XXXX_API_KEY" + env := "DD_API_KEY" t.Run(env, func(t *testing.T) { t.Setenv(env, "123") config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -954,16 +906,14 @@ func TestLoadEnv(t *testing.T) { assert.Equal(t, "123", cfg.Endpoints[0].APIKey) }) - env = "XXXX_SITE" + env = "DD_SITE" t.Run(env, func(t *testing.T) { - os.Setenv(env, "my-site.com") - defer os.Unsetenv(env) + t.Setenv(env, "my-site.com") config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/site_default.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/site_default.yaml"}, }), MockModule(), )) @@ -979,8 +929,7 @@ func TestLoadEnv(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -996,8 +945,7 @@ func TestLoadEnv(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1013,8 +961,7 @@ func TestLoadEnv(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1030,8 +977,7 @@ func TestLoadEnv(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1041,14 +987,13 @@ func TestLoadEnv(t *testing.T) { assert.Equal(t, "my-proxy.url", cfg.ProxyURL.String()) }) - env = "XXXX_HOSTNAME" + env = "DD_HOSTNAME" t.Run(env, func(t *testing.T) { t.Setenv(env, "local.host") config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1058,14 +1003,13 @@ func TestLoadEnv(t *testing.T) { assert.Equal(t, "local.host", cfg.Hostname) }) - env = "XXXX_BIND_HOST" + env = "DD_BIND_HOST" t.Run(env, func(t *testing.T) { t.Setenv(env, "bindhost.com") config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1085,8 +1029,7 @@ func TestLoadEnv(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1097,15 +1040,14 @@ func TestLoadEnv(t *testing.T) { }) } - env = "XXXX_DOGSTATSD_PORT" + env = "DD_DOGSTATSD_PORT" t.Run(env, func(t *testing.T) { t.Setenv(env, "4321") config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1122,8 +1064,7 @@ func TestLoadEnv(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/undocumented.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/undocumented.yaml"}, }), MockModule(), )) @@ -1140,8 +1081,7 @@ func TestLoadEnv(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/undocumented.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/undocumented.yaml"}, }), MockModule(), )) @@ -1161,8 +1101,7 @@ func TestLoadEnv(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1175,14 +1114,12 @@ func TestLoadEnv(t *testing.T) { env = "DD_APM_ANALYZED_SPANS" t.Run(env, func(t *testing.T) { - t.Setenv(env, "web|http.request=1,db|sql.query=0.5") config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1203,8 +1140,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1235,8 +1171,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1254,8 +1189,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1273,8 +1207,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1292,8 +1225,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1312,8 +1244,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1330,8 +1261,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1348,8 +1278,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1369,8 +1298,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1386,8 +1314,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1408,8 +1335,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1432,8 +1358,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/deprecated-max-tps-apm.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/deprecated-max-tps-apm.yaml"}, }), MockModule(), )) @@ -1451,8 +1376,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1477,8 +1401,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1498,8 +1421,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1519,8 +1441,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1538,8 +1459,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1556,8 +1476,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1577,8 +1496,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1596,8 +1514,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1615,8 +1532,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1634,8 +1550,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1660,8 +1575,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1679,8 +1593,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1698,8 +1611,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1724,8 +1636,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1742,8 +1653,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1760,8 +1670,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1786,8 +1695,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1806,8 +1714,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1824,8 +1731,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1843,8 +1749,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1865,8 +1770,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1887,8 +1791,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1906,8 +1809,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1925,8 +1827,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1944,8 +1845,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1965,8 +1865,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -1984,8 +1883,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2006,8 +1904,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2028,8 +1925,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2047,8 +1943,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2066,8 +1961,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2085,8 +1979,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2104,8 +1997,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2126,8 +2018,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2148,8 +2039,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2167,8 +2057,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2189,8 +2078,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2211,8 +2099,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2237,8 +2124,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2268,8 +2154,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2287,8 +2172,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2306,8 +2190,7 @@ func TestLoadEnv(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/full.yaml"}, }), MockModule(), )) @@ -2321,31 +2204,29 @@ func TestLoadEnv(t *testing.T) { func TestFargateConfig(t *testing.T) { type testData struct { - features []coreconfig.Feature + features []env.Feature expectedOrchestrator traceconfig.FargateOrchestratorName } for _, data := range []testData{ { - features: []coreconfig.Feature{coreconfig.ECSFargate}, + features: []env.Feature{env.ECSFargate}, expectedOrchestrator: traceconfig.OrchestratorECS, }, { - features: []coreconfig.Feature{coreconfig.EKSFargate}, + features: []env.Feature{env.EKSFargate}, expectedOrchestrator: traceconfig.OrchestratorEKS, }, { - features: []coreconfig.Feature{}, + features: []env.Feature{}, expectedOrchestrator: traceconfig.OrchestratorUnknown, }, } { t.Run("", func(t *testing.T) { - + env.SetFeatures(t, data.features...) c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/no_apm_config.yaml"}, - Features: data.features, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/no_apm_config.yaml"}, }), MockModule(), )) @@ -2360,7 +2241,6 @@ func TestFargateConfig(t *testing.T) { func TestSetMaxMemCPU(t *testing.T) { t.Run("default, non-containerized", func(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), MockModule(), @@ -2375,7 +2255,6 @@ func TestSetMaxMemCPU(t *testing.T) { }) t.Run("default, containerized", func(t *testing.T) { - config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), MockModule(), @@ -2390,7 +2269,6 @@ func TestSetMaxMemCPU(t *testing.T) { }) t.Run("limits set, non-containerized", func(t *testing.T) { - overrides := map[string]interface{}{ "apm_config.max_cpu_percent": "20", "apm_config.max_memory": "200", @@ -2401,7 +2279,6 @@ func TestSetMaxMemCPU(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -2411,7 +2288,6 @@ func TestSetMaxMemCPU(t *testing.T) { }) t.Run("limits set, containerized", func(t *testing.T) { - overrides := map[string]interface{}{ "apm_config.max_cpu_percent": "30", "apm_config.max_memory": "300", @@ -2422,7 +2298,6 @@ func TestSetMaxMemCPU(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -2438,7 +2313,6 @@ func TestPeerTagsAggregation(t *testing.T) { corecomp.MockModule(), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) assert.False(t, cfg.PeerTagsAggregation) @@ -2455,7 +2329,6 @@ func TestPeerTagsAggregation(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) assert.True(t, cfg.PeerTagsAggregation) @@ -2471,7 +2344,6 @@ func TestPeerTagsAggregation(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() assert.True(t, cfg.PeerTagsAggregation) assert.Nil(t, cfg.PeerTags) @@ -2487,7 +2359,6 @@ func TestPeerTagsAggregation(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) assert.True(t, cfg.PeerTagsAggregation) @@ -2503,7 +2374,6 @@ func TestPeerTagsAggregation(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) assert.False(t, cfg.PeerTagsAggregation) @@ -2520,7 +2390,6 @@ func TestPeerTagsAggregation(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() assert.True(t, cfg.PeerTagsAggregation) assert.Equal(t, []string{"user_peer_tag"}, cfg.PeerTags) @@ -2536,7 +2405,6 @@ func TestPeerTagsAggregation(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) assert.True(t, cfg.PeerTagsAggregation) @@ -2554,7 +2422,6 @@ func TestPeerTagsAggregation(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) assert.True(t, cfg.PeerTagsAggregation) @@ -2568,7 +2435,6 @@ func TestComputeStatsBySpanKind(t *testing.T) { corecomp.MockModule(), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -2585,7 +2451,6 @@ func TestComputeStatsBySpanKind(t *testing.T) { fx.Replace(corecomp.MockParams{Overrides: overrides}), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) @@ -2595,9 +2460,6 @@ func TestComputeStatsBySpanKind(t *testing.T) { func TestGenerateInstallSignature(t *testing.T) { cfgDir := t.TempDir() - defer func() { - os.RemoveAll(cfgDir) - }() cfgContent, err := os.ReadFile("./testdata/full.yaml") assert.NoError(t, err) cfgFile := filepath.Join(cfgDir, "full.yaml") @@ -2607,8 +2469,7 @@ func TestGenerateInstallSignature(t *testing.T) { c := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: cfgFile}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: cfgFile}, }), MockModule(), )) @@ -2636,28 +2497,30 @@ func TestGenerateInstallSignature(t *testing.T) { } func TestMockConfig(t *testing.T) { - os.Setenv("DD_SITE", "datadoghq.eu") - defer func() { os.Unsetenv("DD_SITE") }() - + t.Setenv("DD_SITE", "datadoghq.eu") config := fxutil.Test[Component](t, fx.Options( fx.Supply(corecomp.Params{}), corecomp.MockModule(), MockModule(), )) - // underlying config cfg := config.Object() require.NotNil(t, cfg) - // values aren't set from env.. - assert.NotEqual(t, "datadoghq.eu", cfg.Site) + assert.Equal(t, true, cfg.Enabled) + assert.Equal(t, "datadoghq.eu", cfg.Site) +} + +func TestMockDefaultConfig(t *testing.T) { + config := fxutil.Test[Component](t, fx.Options( + fx.Supply(corecomp.Params{}), + corecomp.MockModule(), + MockModule(), + )) + cfg := config.Object() + require.NotNil(t, cfg) - // but defaults are set assert.Equal(t, true, cfg.Enabled) assert.Equal(t, "datadoghq.com", cfg.Site) - - // but can be set by the mock - // config.(Mock).Set("app_key", "newvalue") - // require.Equal(t, "newvalue", config.GetString("app_key")) } func TestGetCoreConfigHandler(t *testing.T) { @@ -2705,8 +2568,7 @@ func TestDisableReceiverConfig(t *testing.T) { config := fxutil.Test[Component](t, fx.Options( corecomp.MockModule(), fx.Replace(corecomp.MockParams{ - Params: corecomp.Params{ConfFilePath: "./testdata/disable_receiver.yaml"}, - SetupConfig: true, + Params: corecomp.Params{ConfFilePath: "./testdata/disable_receiver.yaml"}, }), MockModule(), )) diff --git a/comp/trace/config/setup.go b/comp/trace/config/setup.go index ff69fd1c016fb..e2e62d47b4a22 100644 --- a/comp/trace/config/setup.go +++ b/comp/trace/config/setup.go @@ -26,6 +26,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/tagger/types" "github.com/DataDog/datadog-agent/comp/otelcol/otlp" coreconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/config/model" "github.com/DataDog/datadog-agent/pkg/config/utils" "github.com/DataDog/datadog-agent/pkg/trace/config" @@ -332,7 +333,7 @@ func applyDatadogConfig(c *config.AgentConfig, core corecompcfg.Component) error if core.IsSet("apm_config.apm_non_local_traffic") && core.GetBool("apm_config.apm_non_local_traffic") { c.ReceiverHost = "0.0.0.0" } - } else if coreconfig.IsContainerized() { + } else if env.IsContainerized() { // Automatically activate non local traffic in containerized environment if no explicit config set log.Info("Activating non-local traffic automatically in containerized environment, trace-agent will listen on 0.0.0.0") c.ReceiverHost = "0.0.0.0" diff --git a/docs/README.md b/docs/README.md index f19e3d26d7da6..5f07a2ee4b684 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,11 +4,11 @@ This directory contains docs, guides and resources to better use this repo. ## TOC - * [Datadog Agent](agent/README.md) user documentation. - * [Developer Guide](dev/README.md): new users and contributors are encouraged + * [Datadog Agent](https://docs.datadoghq.com/agent/) user documentation. + * [Developer Guide](https://datadoghq.dev/datadog-agent/setup/): new users and contributors are encouraged to build the Datadog Agent themselves and should start reading this guide. - * [DogStatsD](dogstatsd/README.md) user documentation. - * [Datadog Cluster Agent](cluster-agent/README.md) user documentation. + * [DogStatsD](https://docs.datadoghq.com/developers/dogstatsd/) user documentation. + * [Datadog Cluster Agent](https://docs.datadoghq.com/containers/cluster_agent/) user documentation. The Docker images have their own additional documentation: diff --git a/docs/dev/agent_dev_env.md b/docs/dev/agent_dev_env.md index 0929f27d19be0..a4b41fc748379 100644 --- a/docs/dev/agent_dev_env.md +++ b/docs/dev/agent_dev_env.md @@ -52,10 +52,10 @@ To install `deva`, you'll need to: The Python environment will automatically be created on the first run. and will be reused for subsequent runs. For example: ```shell -$ cd datadog-agent -$ curl -L -o deva https://github.com/DataDog/datadog-agent-devtools/releases/download/deva-v1.0.0/deva-aarch64-unknown-linux-gnu-1.0.0 -$ chmod +x deva -$ ./deva linter.go +cd datadog-agent +curl -L -o deva https://github.com/DataDog/datadog-agent-devtools/releases/download/deva-v1.0.0/deva-aarch64-unknown-linux-gnu-1.0.0 +chmod +x deva +./deva linter.go ``` Below a live demo of how the tool works: @@ -287,5 +287,3 @@ To configure the vscode editor to use a container as remote development environm [Microsoft Visual Studio Code](https://code.visualstudio.com/download) is recommended as it's lightweight and versatile. Building on Windows requires multiple 3rd-party software to be installed. To avoid the complexity, Datadog recommends to make the code change in VS Code, and then do the build in Docker image. For complete information, see [Build the Agent packages](https://github.com/DataDog/datadog-agent/blob/main/docs/dev/agent_omnibus.md) - - diff --git a/docs/public/setup.md b/docs/public/setup.md index 957c2ef7c14a0..5f3b8d52f362c 100644 --- a/docs/public/setup.md +++ b/docs/public/setup.md @@ -48,10 +48,10 @@ To install `deva`, you'll need to: The Python environment will automatically be created on the first run. and will be reused for subsequent runs. For example: ```shell -$ cd datadog-agent -$ curl -L -o deva https://github.com/DataDog/datadog-agent-devtools/releases/download/deva-v1.0.0/deva-aarch64-unknown-linux-gnu-1.0.0 -$ chmod +x deva -$ ./deva linter.go +cd datadog-agent +curl -L -o deva https://github.com/DataDog/datadog-agent-devtools/releases/download/deva-v1.0.0/deva-aarch64-unknown-linux-gnu-1.0.0 +chmod +x deva +./deva linter.go ``` Below a live demo of how the tool works: @@ -101,7 +101,7 @@ This procedure ensures you not only get the correct version of `invoke`, but als ### Golang -You must [install Golang](https://golang.org/doc/install) version `1.21.7` or higher. Make sure that `$GOPATH/bin` is in your `$PATH` otherwise `invoke` cannot use any additional tool it might need. +You must [install Golang](https://golang.org/doc/install) version `1.22.6` or higher. Make sure that `$GOPATH/bin` is in your `$PATH` otherwise `invoke` cannot use any additional tool it might need. !!! note Versions of Golang that aren't an exact match to the version specified in our build images (see e.g. [here](https://github.com/DataDog/datadog-agent-buildimages/blob/c025473ee467ee6d884d532e4c12c7d982ce8fe1/circleci/Dockerfile#L43)) may not be able to build the agent and/or the [rtloader](https://github.com/DataDog/datadog-agent/tree/main/rtloader) binary properly. diff --git a/go.mod b/go.mod index fc6c85fe356d4..004010e11841a 100644 --- a/go.mod +++ b/go.mod @@ -50,8 +50,8 @@ replace ( github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl => ./comp/otelcol/configstore/impl github.com/DataDog/datadog-agent/comp/otelcol/converter/def => ./comp/otelcol/converter/def github.com/DataDog/datadog-agent/comp/otelcol/converter/impl => ./comp/otelcol/converter/impl - github.com/DataDog/datadog-agent/comp/otelcol/extension/def => ./comp/otelcol/extension/def - github.com/DataDog/datadog-agent/comp/otelcol/extension/impl => ./comp/otelcol/extension/impl + github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def => ./comp/otelcol/ddflareextension/def/ + github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl => ./comp/otelcol/ddflareextension/impl/ github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline => ./comp/otelcol/logsagentpipeline github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline/logsagentpipelineimpl => ./comp/otelcol/logsagentpipeline/logsagentpipelineimpl github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/exporter/datadogexporter => ./comp/otelcol/otlp/components/exporter/datadogexporter @@ -139,7 +139,7 @@ require ( code.cloudfoundry.org/garden v0.0.0-20210208153517-580cadd489d2 code.cloudfoundry.org/lager v2.0.0+incompatible github.com/CycloneDX/cyclonedx-go v0.8.0 - github.com/DataDog/appsec-internal-go v1.6.0 + github.com/DataDog/appsec-internal-go v1.7.0 github.com/DataDog/datadog-agent/pkg/gohai v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/obfuscate v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.56.0-rc.3 @@ -182,7 +182,7 @@ require ( github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 github.com/cilium/ebpf v0.16.0 github.com/clbanning/mxj v1.8.4 - github.com/containerd/containerd v1.7.18 + github.com/containerd/containerd v1.7.20 github.com/containernetworking/cni v1.2.3 github.com/coreos/go-semver v0.3.1 github.com/coreos/go-systemd v22.5.0+incompatible @@ -213,7 +213,7 @@ require ( github.com/google/gopacket v1.1.19 github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 github.com/gorilla/mux v1.8.1 - github.com/gosnmp/gosnmp v1.37.1-0.20240115134726-db0c09337869 + github.com/gosnmp/gosnmp v1.38.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/h2non/filetype v1.1.3 @@ -231,14 +231,14 @@ require ( github.com/lxn/win v0.0.0-20210218163916-a377121e959e github.com/mailru/easyjson v0.7.7 github.com/mdlayher/netlink v1.7.2 - github.com/miekg/dns v1.1.61 + github.com/miekg/dns v1.1.62 github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c github.com/moby/sys/mountinfo v0.7.2 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 github.com/netsampler/goflow2 v1.3.3 github.com/olekukonko/tablewriter v0.0.5 github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 - github.com/open-policy-agent/opa v0.66.0 + github.com/open-policy-agent/opa v0.67.1 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry v0.104.0 // indirect github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 @@ -266,18 +266,18 @@ require ( github.com/streadway/amqp v1.1.0 github.com/stretchr/testify v1.9.0 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 - github.com/tinylib/msgp v1.1.9 + github.com/tinylib/msgp v1.2.0 github.com/twmb/murmur3 v1.1.8 - github.com/uptrace/bun v1.1.14 - github.com/uptrace/bun/dialect/pgdialect v1.1.14 - github.com/uptrace/bun/driver/pgdriver v1.1.14 + github.com/uptrace/bun v1.2.1 + github.com/uptrace/bun/dialect/pgdialect v1.2.1 + github.com/uptrace/bun/driver/pgdriver v1.2.1 github.com/urfave/negroni v1.0.0 github.com/vishvananda/netlink v1.2.1-beta.2.0.20230807190133-6afddb37c1f0 github.com/vishvananda/netns v0.0.4 github.com/vmihailenco/msgpack/v4 v4.3.13 github.com/wI2L/jsondiff v0.6.0 github.com/xeipuuv/gojsonschema v1.2.0 - go.etcd.io/bbolt v1.3.10 + go.etcd.io/bbolt v1.3.11 go.etcd.io/etcd/client/v2 v2.306.0-alpha.0 go.mongodb.org/mongo-driver v1.15.1 go.opentelemetry.io/collector v0.104.0 // indirect @@ -293,25 +293,25 @@ require ( go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect go.uber.org/atomic v1.11.0 go.uber.org/automaxprocs v1.5.3 - go.uber.org/dig v1.17.1 - go.uber.org/fx v1.18.2 + go.uber.org/dig v1.18.0 + go.uber.org/fx v1.22.2 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 go4.org/netipx v0.0.0-20220812043211-3cc044ffd68d golang.org/x/arch v0.9.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/net v0.27.0 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/net v0.28.0 golang.org/x/sync v0.8.0 - golang.org/x/sys v0.23.0 - golang.org/x/text v0.16.0 + golang.org/x/sys v0.24.0 + golang.org/x/text v0.17.0 golang.org/x/time v0.6.0 - golang.org/x/tools v0.23.0 + golang.org/x/tools v0.24.0 golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 google.golang.org/genproto v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/grpc v1.65.0 google.golang.org/grpc/examples v0.0.0-20221020162917-9127159caf5a google.golang.org/protobuf v1.34.2 - gopkg.in/DataDog/dd-trace-go.v1 v1.65.1 + gopkg.in/DataDog/dd-trace-go.v1 v1.67.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 gopkg.in/zorkian/go-datadog-api.v2 v2.30.0 @@ -393,7 +393,7 @@ require ( github.com/containerd/continuity v0.4.3 // indirect github.com/containerd/fifo v1.1.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect - github.com/containerd/ttrpc v1.2.4 // indirect + github.com/containerd/ttrpc v1.2.5 // indirect github.com/containernetworking/plugins v1.4.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect @@ -496,7 +496,7 @@ require ( github.com/package-url/packageurl-go v0.1.2 // indirect github.com/pborman/uuid v1.2.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/philhofer/fwd v1.1.2 // indirect + github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect @@ -553,22 +553,22 @@ require ( go.opentelemetry.io/collector/consumer v0.104.0 go.opentelemetry.io/collector/featuregate v1.11.0 go.opentelemetry.io/collector/semconv v0.104.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.27.0 // indirect - go.opentelemetry.io/otel v1.27.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 + go.opentelemetry.io/otel v1.28.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/exporters/prometheus v0.49.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 - go.opentelemetry.io/otel/sdk v1.27.0 + go.opentelemetry.io/otel/metric v1.28.0 + go.opentelemetry.io/otel/sdk v1.28.0 go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.27.0 - go.opentelemetry.io/proto/otlp v1.2.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 + go.opentelemetry.io/proto/otlp v1.3.1 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/mod v0.20.0 golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/term v0.22.0 // indirect + golang.org/x/term v0.23.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/api v0.185.0 // indirect google.golang.org/appengine v1.6.8 // indirect @@ -594,6 +594,11 @@ require ( require ( github.com/DataDog/datadog-agent/comp/core/tagger/utils v0.0.0-00010101000000-000000000000 + github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def v0.56.0-rc.3 + github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/impl v0.0.0-00010101000000-000000000000 + github.com/containerd/containerd/api v1.7.19 + github.com/containerd/errdefs v0.1.0 + github.com/distribution/reference v0.6.0 github.com/lorenzosaino/go-sysctl v0.3.1 ) @@ -624,8 +629,6 @@ require ( github.com/DataDog/datadog-agent/comp/otelcol/configstore/impl v0.56.0-rc.3 github.com/DataDog/datadog-agent/comp/otelcol/converter/def v0.56.0-rc.3 github.com/DataDog/datadog-agent/comp/otelcol/converter/impl v0.56.0-rc.3 - github.com/DataDog/datadog-agent/comp/otelcol/extension/def v0.56.0-rc.3 - github.com/DataDog/datadog-agent/comp/otelcol/extension/impl v0.56.0-rc.3 github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline v0.56.0-rc.3 github.com/DataDog/datadog-agent/comp/otelcol/logsagentpipeline/logsagentpipelineimpl v0.56.0-rc.3 github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/exporter/datadogexporter v0.56.0-rc.3 @@ -642,7 +645,7 @@ require ( github.com/DataDog/datadog-agent/pkg/api v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 - github.com/DataDog/datadog-agent/pkg/config/mock v0.0.0-20240726104123-0f372a5f7b15 + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/config/remote v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/config/setup v0.56.0-rc.3 @@ -762,7 +765,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/statstracker v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/system/socket v0.56.0-rc.3 // indirect github.com/DataDog/datadog-api-client-go/v2 v2.26.0 // indirect - github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe // indirect + github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 // indirect github.com/DataDog/opentelemetry-mapping-go/pkg/inframetadata v0.17.0 // indirect github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/logs v0.17.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.0 // indirect @@ -794,12 +797,11 @@ require ( github.com/chrusty/protoc-gen-jsonschema v0.0.0-20240212064413-73d5723042b8 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b // indirect - github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect github.com/csaf-poc/csaf_distribution/v3 v3.0.0 // indirect github.com/dennwc/varint v1.0.0 // indirect github.com/digitalocean/godo v1.109.0 // indirect - github.com/distribution/reference v0.5.0 // indirect github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 // indirect github.com/ebitengine/purego v0.6.0-alpha.5 // indirect github.com/elastic/go-licenser v0.4.1 // indirect @@ -835,7 +837,7 @@ require ( github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect github.com/hashicorp/cronexpr v1.1.2 // indirect github.com/hashicorp/go-getter v1.7.5 // indirect - github.com/hashicorp/go-retryablehttp v0.7.5 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect @@ -927,7 +929,7 @@ require ( github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/prometheus v2.5.0+incompatible // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect - github.com/rs/zerolog v1.29.1 // indirect + github.com/rs/zerolog v1.32.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -989,8 +991,8 @@ require ( golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gotest.tools/v3 v3.5.1 // indirect @@ -1075,3 +1077,5 @@ replace ( // Prevent a false-positive detection by the Google and Ikarus security vendors on VirusTotal exclude go.opentelemetry.io/proto/otlp v1.1.0 + +replace github.com/google/gopacket v1.1.19 => github.com/DataDog/gopacket v0.0.0-20240626205202-4ac4cee31f14 diff --git a/go.sum b/go.sum index 019d7521a3dcb..98f159614e9f7 100644 --- a/go.sum +++ b/go.sum @@ -662,8 +662,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFG github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0/go.mod h1:Y/HgrePTmGy9HjdSGTqZNa+apUpTVIEVKXJyARP2lrk= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1 h1:7CBQ+Ei8SP2c6ydQTGCCrS35bDxgTMfoP2miAwK++OU= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1/go.mod h1:c/wcGeGx5FUPbM/JltUYHZcKmigwyVLJlDq+4HdtXaw= github.com/Azure/azure-storage-blob-go v0.15.0/go.mod h1:vbjsVbX0dlxnRc4FFMPsS9BsJWPcne7GB7onqlPvz58= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= @@ -687,8 +687,8 @@ github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7Oputl github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/DataDog/agent-payload/v5 v5.0.130 h1:pVMRVKkUMmw2vOpmP92TO9jrS0om3K0uKteXHcy/6v0= github.com/DataDog/agent-payload/v5 v5.0.130/go.mod h1:FgVQKmVdqdmZTbxIptqJC/l+xEzdiXsaAOs/vGAvWzs= -github.com/DataDog/appsec-internal-go v1.6.0 h1:QHvPOv/O0s2fSI/BraZJNpRDAtdlrRm5APJFZNBxjAw= -github.com/DataDog/appsec-internal-go v1.6.0/go.mod h1:pEp8gjfNLtEOmz+iZqC8bXhu0h4k7NUsW/qiQb34k1U= +github.com/DataDog/appsec-internal-go v1.7.0 h1:iKRNLih83dJeVya3IoUfK+6HLD/hQsIbyBlfvLmAeb0= +github.com/DataDog/appsec-internal-go v1.7.0/go.mod h1:wW0cRfWBo4C044jHGwYiyh5moQV2x0AhnwqMuiX7O/g= github.com/DataDog/aptly v1.5.3 h1:oLsRvjuXSVM4ia0N83dU3KiQeiJ6BaszYbTZOkSfDlw= github.com/DataDog/aptly v1.5.3/go.mod h1:ZL5TfCso+z4enH03N+s3z8tYUJHhL6DlxIvnnP2TbY4= github.com/DataDog/cast v1.3.1-0.20190301154711-1ee8c8bd14a3 h1:SobA9WYm4K/MUtWlbKaomWTmnuYp1KhIm8Wlx3vmpsg= @@ -702,8 +702,8 @@ github.com/DataDog/datadog-go/v5 v5.5.0 h1:G5KHeB8pWBNXT4Jtw0zAkhdxEAWSpWH00geHI github.com/DataDog/datadog-go/v5 v5.5.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= github.com/DataDog/datadog-operator v1.8.0-rc.1 h1:w6/z5jcTzWGv90/H9AhcgZd3gAdP3eaWEGpnE7nVdRM= github.com/DataDog/datadog-operator v1.8.0-rc.1/go.mod h1:qxwdMzmiZ165BAMbTYkr4yJKvhOnDUMAcGNQiPJVmAA= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe h1:efzxujZ7VHWFxjmWjcJyUEpPrN8qdiZPYb+dBw547Wo= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 h1:RoH7VLzTnxHEugRPIgnGlxwDFszFGI7b3WZZUtWuPRM= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= github.com/DataDog/ebpf-manager v0.7.1 h1:q8y6Kb5Zk1gaLoZpoj3vHi7wUe8MbtNDIq8zO/DODzM= github.com/DataDog/ebpf-manager v0.7.1/go.mod h1:ld5QVq/+O3AEtol/9fhiQziGkdHSECDQvm5+DQ9V98s= github.com/DataDog/extendeddaemonset v0.10.0-rc.4 h1:m88E+emuRHIqKgi7kHMd9N0S/NtruCCOISp3cjB7DNs= @@ -718,6 +718,8 @@ github.com/DataDog/go-tuf v1.1.0-0.5.2 h1:4CagiIekonLSfL8GMHRHcHudo1fQnxELS9g4ti github.com/DataDog/go-tuf v1.1.0-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= github.com/DataDog/gohai v0.0.0-20230524154621-4316413895ee h1:tXibLZk3G6HncIFJKaNItsdzcrk4YqILNDZlXPTNt4k= github.com/DataDog/gohai v0.0.0-20230524154621-4316413895ee/go.mod h1:nTot/Iy0kW16bXgXr6blEc8gFeAS7vTqYlhAxh+dbc0= +github.com/DataDog/gopacket v0.0.0-20240626205202-4ac4cee31f14 h1:t34NfJA77KgFZsh8kcNFW57LZLa0kW2YSUs4MvLKRxU= +github.com/DataDog/gopacket v0.0.0-20240626205202-4ac4cee31f14/go.mod h1:riddUzxTSBpJXk3qBHtYr4qOhFhT6k/1c0E3qkQjQpA= github.com/DataDog/gopsutil v1.2.2 h1:8lmthwyyCXa1NKiYcHlrtl9AAFdfbNI2gPcioCJcBPU= github.com/DataDog/gopsutil v1.2.2/go.mod h1:glkxNt/qRu9lnpmUEQwOIAXW+COWDTBOTEAHqbgBPts= github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= @@ -1086,8 +1088,10 @@ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+Bu github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= -github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= -github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= +github.com/containerd/containerd v1.7.20 h1:Sl6jQYk3TRavaU83h66QMbI2Nqg9Jm6qzwX57Vsn1SQ= +github.com/containerd/containerd v1.7.20/go.mod h1:52GsS5CwquuqPuLncsXwG0t2CiUce+KsNHJZQJvAgR0= +github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA= +github.com/containerd/containerd/api v1.7.19/go.mod h1:fwGavl3LNwAV5ilJ0sbrABL44AQxmNjDRcwheXDb6Ig= github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= @@ -1096,10 +1100,12 @@ github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= -github.com/containerd/ttrpc v1.2.4 h1:eQCQK4h9dxDmpOb9QOOMh2NHTfzroH1IkmHiKZi05Oo= -github.com/containerd/ttrpc v1.2.4/go.mod h1:ojvb8SJBSch0XkqNO0L0YX/5NxR3UnVk2LzFKBK0upc= +github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oLU= +github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8FuJbEslXM= @@ -1160,8 +1166,8 @@ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/digitalocean/godo v1.109.0 h1:4W97RJLJSUQ3veRZDNbp1Ol3Rbn6Lmt9bKGvfqYI5SU= github.com/digitalocean/godo v1.109.0/go.mod h1:R6EmmWI8CT1+fCtjWY9UCB+L5uufuZH13wk3YhxycCs= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/cli v25.0.5+incompatible h1:3Llw3kcE1gOScEojA247iDD+p1l9hHeC7H3vf3Zd5fk= @@ -1263,8 +1269,8 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= github.com/glaslos/ssdeep v0.4.0 h1:w9PtY1HpXbWLYgrL/rvAVkj2ZAMOtDxoGKcBHcUFCLs= github.com/glaslos/ssdeep v0.4.0/go.mod h1:il4NniltMO8eBtU7dqoN+HVJ02gXxbpbUfkcyUvNtG0= -github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4= -github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3q+ihjqxC9u0= +github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= +github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/go-delve/delve v1.20.1 h1:km9RA+oUw6vd/mYL4EGcT5DsqGE0w/To8zFq0ZRj4PQ= @@ -1507,8 +1513,6 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/licenseclassifier/v2 v2.0.0 h1:1Y57HHILNf4m0ABuMVb6xk4vAJYEUO0gDxNpog0pyeA= github.com/google/licenseclassifier/v2 v2.0.0/go.mod h1:cOjbdH0kyC9R22sdQbYsFkto4NGCAc+ZSwbeThazEtM= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= @@ -1592,8 +1596,8 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/gosnmp/gosnmp v1.37.1-0.20240115134726-db0c09337869 h1:MphZl80DUq02iPzdDxVffuUD1V24UH6UtmEY6FX+/M4= -github.com/gosnmp/gosnmp v1.37.1-0.20240115134726-db0c09337869/go.mod h1:GDH9vNqpsD7f2HvZhKs5dlqSEcAS6s6Qp099oZRCR+M= +github.com/gosnmp/gosnmp v1.38.0 h1:I5ZOMR8kb0DXAFg/88ACurnuwGwYkXWq3eLpJPHMEYc= +github.com/gosnmp/gosnmp v1.38.0/go.mod h1:FE+PEZvKrFz9afP9ii1W3cprXuVZ17ypCcyyfYuu5LY= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -1637,7 +1641,6 @@ github.com/hashicorp/go-getter v1.7.5 h1:dT58k9hQ/vbxNMwoI5+xFYAJuv6152UNvdHokfI github.com/hashicorp/go-getter v1.7.5/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= @@ -1654,8 +1657,8 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= -github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= @@ -1930,6 +1933,7 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1957,8 +1961,8 @@ github.com/microsoft/go-rustaudit v0.0.0-20220808201409-204dfee52032/go.mod h1:v github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= -github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= +github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= +github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -2094,8 +2098,8 @@ github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3 github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= -github.com/open-policy-agent/opa v0.66.0 h1:DbrvfJQja0FBRcPOB3Z/BOckocN+M4ApNWyNhSRJt0w= -github.com/open-policy-agent/opa v0.66.0/go.mod h1:EIgNnJcol7AvQR/IcWLwL13k64gHVbNAVG46b2G+/EY= +github.com/open-policy-agent/opa v0.67.1 h1:rzy26J6g1X+CKknAcx0Vfbt41KqjuSzx4E0A8DAZf3E= +github.com/open-policy-agent/opa v0.67.1/go.mod h1:aqKlHc8E2VAAylYE9x09zJYr/fYzGX+JKne89UGqFzk= github.com/open-telemetry/opentelemetry-collector-contrib/connector/datadogconnector v0.103.0 h1:Kpfqjwp+nlgqacXkSS8T8iGiTMTFo8NoT8AoRomDOpU= github.com/open-telemetry/opentelemetry-collector-contrib/connector/datadogconnector v0.103.0/go.mod h1:ymbGC/jEXTq8mgHsxzV1PjVGHmV5hSQXmkYkFfGfuLw= github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.104.0 h1:6dvpPt8pCcV+TfMnnanFk2NQYf9HN1voSS9iIHdW+L8= @@ -2253,8 +2257,8 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= -github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= +github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 h1:jYi87L8j62qkXzaYHAQAhEapgukhenIMZRBKTNRLHJ4= +github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= @@ -2333,9 +2337,10 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= -github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= -github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= @@ -2519,8 +2524,8 @@ github.com/tidwall/wal v1.1.7 h1:emc1TRjIVsdKKSnpwGBAcsAGg0767SvUk8+ygx7Bb+4= github.com/tidwall/wal v1.1.7/go.mod h1:r6lR1j27W9EPalgHiB7zLJDYu3mzW5BQP5KrzBpYY/E= github.com/tilinna/clock v1.1.0 h1:6IQQQCo6KoBxVudv6gwtY8o4eDfhHo8ojA5dP0MfhSs= github.com/tilinna/clock v1.1.0/go.mod h1:ZsP7BcY7sEEz7ktc0IVy8Us6boDrK8VradlKRUGfOao= -github.com/tinylib/msgp v1.1.9 h1:SHf3yoO2sGA0veCJeCBYLHuttAVFHGm2RHgNodW7wQU= -github.com/tinylib/msgp v1.1.9/go.mod h1:BCXGB54lDD8qUEPmiG0cQQUANC4IUQyB2ItS2UDlO/k= +github.com/tinylib/msgp v1.2.0 h1:0uKB/662twsVBpYUPbokj4sTSKhWFKB7LopO2kWK8lY= +github.com/tinylib/msgp v1.2.0/go.mod h1:2vIGs3lcUo8izAATNobrCHevYZC/LMsJtw4JPiYPHro= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= @@ -2550,12 +2555,12 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/uptrace/bun v1.1.14 h1:S5vvNnjEynJ0CvnrBOD7MIRW7q/WbtvFXrdfy0lddAM= -github.com/uptrace/bun v1.1.14/go.mod h1:RHk6DrIisO62dv10pUOJCz5MphXThuOTpVNYEYv7NI8= -github.com/uptrace/bun/dialect/pgdialect v1.1.14 h1:b7+V1KDJPQSFYgkG/6YLXCl2uvwEY3kf/GSM7hTHRDY= -github.com/uptrace/bun/dialect/pgdialect v1.1.14/go.mod h1:v6YiaXmnKQ2FlhRD2c0ZfKd+QXH09pYn4H8ojaavkKk= -github.com/uptrace/bun/driver/pgdriver v1.1.14 h1:V2Etm7mLGS3mhx8ddxZcUnwZLX02Jmq9JTlo0sNVDhA= -github.com/uptrace/bun/driver/pgdriver v1.1.14/go.mod h1:D4FjWV9arDYct6sjMJhFoyU71SpllZRHXFRRP2Kd0Kw= +github.com/uptrace/bun v1.2.1 h1:2ENAcfeCfaY5+2e7z5pXrzFKy3vS8VXvkCag6N2Yzfk= +github.com/uptrace/bun v1.2.1/go.mod h1:cNg+pWBUMmJ8rHnETgf65CEvn3aIKErrwOD6IA8e+Ec= +github.com/uptrace/bun/dialect/pgdialect v1.2.1 h1:ceP99r03u+s8ylaDE/RzgcajwGiC76Jz3nS2ZgyPQ4M= +github.com/uptrace/bun/dialect/pgdialect v1.2.1/go.mod h1:mv6B12cisvSc6bwKm9q9wcrr26awkZK8QXM+nso9n2U= +github.com/uptrace/bun/driver/pgdriver v1.2.1 h1:Cp6c1tKzbTIyL8o0cGT6cOhTsmQZdsUNhgcV51dsmLU= +github.com/uptrace/bun/driver/pgdriver v1.2.1/go.mod h1:jEd3WGx74hWLat3/IkesOoWNjrFNUDADK3nkyOFOOJM= github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= @@ -2567,6 +2572,7 @@ github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8ok github.com/vibrantbyte/go-antpath v1.1.1 h1:SWDIMx4pSjyo7QoAsgTkpNU7QD0X9O0JAgr5O3TsYKk= github.com/vibrantbyte/go-antpath v1.1.1/go.mod h1:ZqMGIk+no3BL2o6OdEZ3ZDiWfIteuastNSaTFv7kgUY= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/vito/go-sse v1.0.0 h1:e6/iTrrvy8BRrOwJwmQmlndlil+TLdxXvHi55ZDzH6M= @@ -2641,8 +2647,8 @@ github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaD github.com/zorkian/go-datadog-api v2.30.0+incompatible h1:R4ryGocppDqZZbnNc5EDR8xGWF/z/MxzWnqTUijDQes= github.com/zorkian/go-datadog-api v2.30.0+incompatible/go.mod h1:PkXwHX9CUQa/FpB9ZwAD45N1uhCW4MT/Wj7m36PbKss= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= -go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= +go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/api/v3 v3.6.0-alpha.0 h1:se+XckWlVTTfwjZSsAZJ2zGPzmIMq3j7fKBCmHoB9UA= go.etcd.io/etcd/api/v3 v3.6.0-alpha.0/go.mod h1:z13pg39zewDLZeXIKeM0xELOeFKcqjLocfwl5M820+w= @@ -2765,24 +2771,24 @@ go.opentelemetry.io/contrib/config v0.7.0 h1:b1rK5tGTuhhPirJiMxOcyQfZs76j2VapY6O 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/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= 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 v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= 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 v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= 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= @@ -2791,19 +2797,19 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.27.0 h1:/jlt1Y8gXWiHG9 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/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= 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/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= -go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.starlark.net v0.0.0-20220816155156-cfacd8902214/go.mod h1:VZcBMdr3cT3PnBoWunTabuSEXwVAH+ZJ5zxfs3AdASk= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -2813,10 +2819,10 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -2874,8 +2880,8 @@ golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -2891,8 +2897,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= @@ -3035,8 +3041,8 @@ golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -3221,8 +3227,8 @@ golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -3239,8 +3245,8 @@ golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3260,8 +3266,8 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -3353,8 +3359,8 @@ golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= @@ -3595,15 +3601,15 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go. google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d h1:Aqf0fiIdUQEj0Gn9mKFFXoQfTTEaNopWpfVyYADxiSg= -google.golang.org/genproto/googleapis/api v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Od4k8V1LQSizPRUK4OzZ7TBE/20k+jPczUDAEyvn69Y= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d h1:k3zyW3BYYR30e8v3x0bTDdE9vpYFjZHK+HcyqkrppWk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -3677,8 +3683,8 @@ google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHh google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/DataDog/dd-trace-go.v1 v1.65.1 h1:Ne7kzWr/br/jwhUJR7CnqPl/mUpNxa6LfgZs0S4htZM= -gopkg.in/DataDog/dd-trace-go.v1 v1.65.1/go.mod h1:beNFIWd/H04d0k96cfltgiDH2+t0T5sDbyYLF3VTXqk= +gopkg.in/DataDog/dd-trace-go.v1 v1.67.0 h1:3Cb46zyKIlEWac21tvDF2O4KyMlOHQxrQkyiaUpdwM0= +gopkg.in/DataDog/dd-trace-go.v1 v1.67.0/go.mod h1:6DdiJPKOeJfZyd/IUGCAd5elY8qPGkztK6wbYYsMjag= gopkg.in/Knetic/govaluate.v3 v3.0.0 h1:18mUyIt4ZlRlFZAAfVetz4/rzlJs9yhN+U02F4u1AOc= gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= @@ -3727,8 +3733,6 @@ gopkg.in/zorkian/go-datadog-api.v2 v2.30.0/go.mod h1:kx0CSMRpzEZfx/nFH62GLU4stZj gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= -honnef.co/go/gotraceui v0.2.0 h1:dmNsfQ9Vl3GwbiVD7Z8d/osC6WtGGrasyrC2suc4ZIQ= -honnef.co/go/gotraceui v0.2.0/go.mod h1:qHo4/W75cA3bX0QQoSvDjbJa4R8mAyyFjbWAj63XElc= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/tools/go.mod b/internal/tools/go.mod index 605c6202baacd..98ea753b30b7a 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -219,16 +219,16 @@ require ( go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gonum.org/v1/gonum v0.7.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/internal/tools/go.sum b/internal/tools/go.sum index 71d9cb377b20e..b929e365f363a 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -748,8 +748,8 @@ golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -764,8 +764,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= @@ -848,8 +848,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -938,8 +938,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -949,8 +949,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -964,8 +964,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1034,8 +1034,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/internal/tools/modformatter/modformatter.go b/internal/tools/modformatter/modformatter.go index 469636416e034..ff5ac8f1625a2 100644 --- a/internal/tools/modformatter/modformatter.go +++ b/internal/tools/modformatter/modformatter.go @@ -23,6 +23,7 @@ import ( var ( path = flag.String("path", ".", "Path to go.mod file to format") formatFile = flag.Bool("formatFile", false, "Enable or Disable formatting of the mod file") + repoPath = flag.String("repoPath", "", "Path to the repository") ) // Delete an element from a slice @@ -64,7 +65,7 @@ func removeExtraLines(lines []string, consecutiveLineNumber int) []string { indexList := make([]int, 0) for idx, content := range lines { if content == "" { - lineCounter += 1 + lineCounter++ } else { lineCounter = 0 } @@ -90,7 +91,7 @@ func formatModFile(content string) string { for idx, line := range strings.Split(content, "\n") { if inRequire { lines = deleteElement(lines, idx-totalRemovedLines) - totalRemovedLines += 1 + totalRemovedLines++ if strings.Contains(line, ")") { inRequire = false } else { @@ -98,7 +99,7 @@ func formatModFile(content string) string { } } else if inReplace { lines = deleteElement(lines, idx-totalRemovedLines) - totalRemovedLines += 1 + totalRemovedLines++ if strings.Contains(line, ")") { inReplace = false } else { @@ -107,7 +108,7 @@ func formatModFile(content string) string { } else if strings.HasPrefix(line, "replace") { parts := strings.Split(line, " ") lines = deleteElement(lines, idx-totalRemovedLines) - totalRemovedLines += 1 + totalRemovedLines++ if parts[1][0] == '(' { inReplace = true } else { @@ -116,7 +117,7 @@ func formatModFile(content string) string { } else if strings.HasPrefix(line, "require") { parts := strings.Split(line, " ") lines = deleteElement(lines, idx-totalRemovedLines) - totalRemovedLines += 1 + totalRemovedLines++ if parts[1][0] == '(' { inRequire = true } else { @@ -139,25 +140,29 @@ func formatModFile(content string) string { func main() { flag.Parse() - if *path == "" { + if *path == "" || *repoPath == "" { flag.PrintDefaults() os.Exit(1) } + if _, err := os.Stat(*repoPath); os.IsNotExist(err) { + fmt.Printf("Repository path %s does not exist\n", *repoPath) + os.Exit(1) + } // Open and parse go.mod file modFilePath := filepath.Join(*path, "go.mod") b, err := os.ReadFile(modFilePath) if err != nil { - fmt.Println("Error opening file %q:", err) + fmt.Println("Error opening file:", err) return } - f, err := modfile.Parse("go.mod", b, func(_, v string) (string, error) { + f, _ := modfile.Parse("go.mod", b, func(_, v string) (string, error) { return module.CanonicalVersion(v), nil }) // Store every dependency already replaced in the go.mod file ReplaceMap := make(map[string]bool) - for i := 0; i < len(f.Replace); i += 1 { + for i := 0; i < len(f.Replace); i++ { token := f.Replace[i].Syntax.Token if len(token) < 1 { continue @@ -188,7 +193,7 @@ func main() { if *formatFile { writeNeeded = true trimName := strings.Split(modname, "github.com/DataDog/datadog-agent/")[1] - trimPath := strings.Split(*path, "github.com/DataDog/datadog-agent/")[1] + trimPath := "." + strings.TrimPrefix(*path, *repoPath) relativePath, err := filepath.Rel(trimPath, trimName) if err != nil { log.Fatal(err) diff --git a/internal/tools/proto/go.mod b/internal/tools/proto/go.mod index 316b0c487a9e3..95787f746e13b 100644 --- a/internal/tools/proto/go.mod +++ b/internal/tools/proto/go.mod @@ -17,11 +17,11 @@ require ( github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/philhofer/fwd v1.1.2 // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/internal/tools/proto/go.sum b/internal/tools/proto/go.sum index 638409848f016..476e8ba46cc90 100644 --- a/internal/tools/proto/go.sum +++ b/internal/tools/proto/go.sum @@ -53,8 +53,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/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.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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= @@ -66,12 +66,12 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h 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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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= @@ -79,8 +79,8 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 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-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/omnibus/config/software/installer.rb b/omnibus/config/software/installer.rb index 826d9de1d5133..fee51d35e8084 100644 --- a/omnibus/config/software/installer.rb +++ b/omnibus/config/software/installer.rb @@ -32,7 +32,7 @@ env = with_embedded_path(env) if linux_target? - command "invoke installer.build --rebuild --run-path=/var/run/datadog-installer --install-path=#{install_dir}", env: env + command "invoke installer.build --rebuild --run-path=/opt/datadog-packages/run --install-path=#{install_dir}", env: env mkdir "#{install_dir}/bin" copy 'bin/installer', "#{install_dir}/bin/" elsif windows_target? @@ -50,4 +50,3 @@ # final package delete "#{install_dir}/uselessfile" end - diff --git a/omnibus/config/software/sds.rb b/omnibus/config/software/sds.rb index 405732ee5a7ba..002c316e50929 100644 --- a/omnibus/config/software/sds.rb +++ b/omnibus/config/software/sds.rb @@ -1,6 +1,6 @@ name "sds" -default_version "v0.1.2" +default_version "v0.2.0" source git: 'https://github.com/DataDog/dd-sensitive-data-scanner' build do @@ -11,10 +11,10 @@ if linux_target? || osx_target? command "cargo build --release", cwd: "#{project_dir}/sds-go/rust" if osx_target? - copy "sds-go/rust/target/release/libsds_go.dylib", "#{install_dir}/embedded/lib" + copy "sds-go/rust/target/release/libdd_sds_go.dylib", "#{install_dir}/embedded/lib" end if linux_target? - copy "sds-go/rust/target/release/libsds_go.so", "#{install_dir}/embedded/lib" + copy "sds-go/rust/target/release/libdd_sds_go.so", "#{install_dir}/embedded/lib" end end end diff --git a/pkg/aggregator/demultiplexer_test.go b/pkg/aggregator/demultiplexer_test.go index dbee16292ac78..efd4ebccebd14 100644 --- a/pkg/aggregator/demultiplexer_test.go +++ b/pkg/aggregator/demultiplexer_test.go @@ -292,9 +292,8 @@ func createDemuxDepsWithOrchestratorFwd( core.MockBundle(), orchestratorForwarderImpl.Module(), fx.Supply(orchestratorParams), - eventplatformimpl.Module(), + eventplatformimpl.Module(eventPlatformParams), eventplatformreceiverimpl.Module(), - fx.Supply(eventPlatformParams), compressionimpl.MockModule(), ) deps := fxutil.Test[internalDemutiplexerDeps](t, modules) diff --git a/pkg/api/go.mod b/pkg/api/go.mod index fb63742620a13..a1dc040010311 100644 --- a/pkg/api/go.mod +++ b/pkg/api/go.mod @@ -14,6 +14,7 @@ replace ( github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config => ../config github.com/DataDog/datadog-agent/pkg/config/env => ../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../config/utils @@ -50,6 +51,7 @@ require ( github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel // indirect github.com/DataDog/datadog-agent/pkg/config/setup v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/executable v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/fxutil v0.56.0-rc.3 // indirect @@ -88,16 +90,16 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/api/go.sum b/pkg/api/go.sum index 7d9bb18a9b376..c0f06ba5f32fa 100644 --- a/pkg/api/go.sum +++ b/pkg/api/go.sum @@ -12,8 +12,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -238,27 +236,27 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -301,11 +299,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -318,8 +316,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/api/security/security.go b/pkg/api/security/security.go index d4aefbc38a81c..40b1310c2f79c 100644 --- a/pkg/api/security/security.go +++ b/pkg/api/security/security.go @@ -157,7 +157,7 @@ func fetchAuthToken(config configModel.Reader, tokenCreationAllowed bool) (strin // Read the token authTokenRaw, e := os.ReadFile(authTokenFile) if e != nil { - return "", fmt.Errorf("unable to read authentication token file: " + e.Error()) + return "", fmt.Errorf("unable to read authentication token file: %s", e.Error()) } // Do some basic validation diff --git a/pkg/api/util/doget.go b/pkg/api/util/doget.go index f7a9bd84593a4..9304932124b7f 100644 --- a/pkg/api/util/doget.go +++ b/pkg/api/util/doget.go @@ -8,7 +8,7 @@ package util import ( "context" "crypto/tls" - "fmt" + "errors" "io" "net/http" ) @@ -81,7 +81,7 @@ func DoGetWithOptions(c *http.Client, url string, options *ReqOptions) (body []b return body, e } if r.StatusCode >= 400 { - return body, fmt.Errorf("%s", body) + return body, errors.New(string(body)) } return body, nil } @@ -105,7 +105,7 @@ func DoPost(c *http.Client, url string, contentType string, body io.Reader) (res return resp, e } if r.StatusCode >= 400 { - return resp, fmt.Errorf("%s", resp) + return resp, errors.New(string(resp)) } return resp, nil } diff --git a/pkg/cli/subcommands/check/command.go b/pkg/cli/subcommands/check/command.go index 329bd790e01d8..18cf25972173e 100644 --- a/pkg/cli/subcommands/check/command.go +++ b/pkg/cli/subcommands/check/command.go @@ -152,6 +152,10 @@ func MakeCommand(globalParamsGetter func() GlobalParams) *cobra.Command { } cliParams.cmd = cmd cliParams.args = args + + eventplatforParams := eventplatformimpl.NewDefaultParams() + eventplatforParams.UseNoopEventPlatformForwarder = true + disableCmdPort() return fxutil.OneShot(run, fx.Supply(cliParams), @@ -164,32 +168,25 @@ func MakeCommand(globalParamsGetter func() GlobalParams) *cobra.Command { // workloadmeta setup wmcatalog.GetCatalog(), - fx.Provide(defaults.DefaultParams), - workloadmetafx.Module(), + workloadmetafx.Module(defaults.DefaultParams()), apiimpl.Module(), authtokenimpl.Module(), fx.Supply(context.Background()), fx.Provide(tagger.NewTaggerParamsForCoreAgent), taggerimpl.Module(), autodiscoveryimpl.Module(), - forwarder.Bundle(), + forwarder.Bundle(defaultforwarder.Params{UseNoopForwarder: true}), inventorychecksimpl.Module(), // inventorychecksimpl depends on a collector and serializer when created to send payload. // Here we just want to collect metadata to be displayed, so we don't need a collector. collector.NoneModule(), fx.Supply(status.NewInformationProvider(statuscollector.Provider{})), fx.Provide(func() serializer.MetricSerializer { return nil }), - fx.Supply(defaultforwarder.Params{UseNoopForwarder: true}), compressionimpl.Module(), demultiplexerimpl.Module(), orchestratorForwarderImpl.Module(), fx.Supply(orchestratorForwarderImpl.NewNoopParams()), - eventplatformimpl.Module(), - fx.Provide(func() eventplatformimpl.Params { - params := eventplatformimpl.NewDefaultParams() - params.UseNoopEventPlatformForwarder = true - return params - }), + eventplatformimpl.Module(eventplatforParams), eventplatformreceiverimpl.Module(), fx.Provide(func() demultiplexerimpl.Params { // Initializing the aggregator with a flush interval of 0 (to disable the flush goroutines) @@ -242,8 +239,6 @@ func MakeCommand(globalParamsGetter func() GlobalParams) *cobra.Command { cmd.Flags().UintVarP(&cliParams.discoveryRetryInterval, "discovery-retry-interval", "", 1, "(unused)") cmd.Flags().UintVarP(&cliParams.discoveryMinInstances, "discovery-min-instances", "", 1, "minimum number of config instances to be discovered before running the check(s)") - pkgconfig.Datadog().BindPFlag("cmd.check.fullsketches", cmd.Flags().Lookup("full-sketches")) //nolint:errcheck - // Power user flags - mark as hidden createHiddenStringFlag(cmd, &cliParams.profileMemoryDir, "m-dir", "", "an existing directory in which to store memory profiling data, ignoring clean-up") createHiddenStringFlag(cmd, &cliParams.profileMemoryFrames, "m-frames", "", "the number of stack frames to consider") diff --git a/pkg/cli/subcommands/clusterchecks/command.go b/pkg/cli/subcommands/clusterchecks/command.go index 061b62c0d67c3..6a29ac12c7cd3 100644 --- a/pkg/cli/subcommands/clusterchecks/command.go +++ b/pkg/cli/subcommands/clusterchecks/command.go @@ -9,6 +9,7 @@ package clusterchecks import ( "bytes" "encoding/json" + "errors" "fmt" "github.com/fatih/color" @@ -153,7 +154,7 @@ func rebalance(_ log.Component, config config.Component, cliParams *cliParams) e json.Unmarshal(r, &errMap) //nolint:errcheck // If the error has been marshalled into a json object, check it and return it properly if e, found := errMap["error"]; found { - err = fmt.Errorf(e) + err = errors.New(e) } fmt.Printf(` @@ -196,7 +197,7 @@ func isolate(_ log.Component, config config.Component, cliParams *cliParams) err json.Unmarshal(r, &errMap) //nolint:errcheck // If the error has been marshalled into a json object, check it and return it properly if e, found := errMap["error"]; found { - err = fmt.Errorf(e) + err = errors.New(e) } fmt.Printf(` diff --git a/pkg/cli/subcommands/health/command.go b/pkg/cli/subcommands/health/command.go index e921ae6031293..f4d1233d61d99 100644 --- a/pkg/cli/subcommands/health/command.go +++ b/pkg/cli/subcommands/health/command.go @@ -9,6 +9,7 @@ package health import ( "context" "encoding/json" + "errors" "fmt" "sort" "strconv" @@ -99,7 +100,7 @@ func requestHealth(_ log.Component, config config.Component, cliParams *cliParam json.Unmarshal(r, &errMap) //nolint:errcheck // If the error has been marshalled into a json object, check it and return it properly if e, found := errMap["error"]; found { - err = fmt.Errorf(e) + err = errors.New(e) } return fmt.Errorf("could not reach agent: %v \nMake sure the agent is running before requesting the status and contact support if you continue having issues", err) diff --git a/pkg/clusteragent/admission/controllers/webhook/controller_base_test.go b/pkg/clusteragent/admission/controllers/webhook/controller_base_test.go index fbd6ed99d6a72..2dadb32102296 100644 --- a/pkg/clusteragent/admission/controllers/webhook/controller_base_test.go +++ b/pkg/clusteragent/admission/controllers/webhook/controller_base_test.go @@ -12,7 +12,6 @@ import ( "time" "github.com/stretchr/testify/assert" - "go.uber.org/fx" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes/fake" @@ -24,7 +23,7 @@ import ( func TestNewController(t *testing.T) { client := fake.NewSimpleClientset() - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) factory := informers.NewSharedInformerFactory(client, time.Duration(0)) // V1 diff --git a/pkg/clusteragent/admission/controllers/webhook/controller_v1_test.go b/pkg/clusteragent/admission/controllers/webhook/controller_v1_test.go index 41a5b17220fe5..b4c990f55459a 100644 --- a/pkg/clusteragent/admission/controllers/webhook/controller_v1_test.go +++ b/pkg/clusteragent/admission/controllers/webhook/controller_v1_test.go @@ -951,8 +951,7 @@ func TestGenerateTemplatesV1(t *testing.T) { wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), fx.Replace(configComp.MockParams{Overrides: map[string]interface{}{"kube_resources_namespace": "nsfoo"}}), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), ) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1088,7 +1087,7 @@ func newFixtureV1(t *testing.T) *fixtureV1 { func (f *fixtureV1) createController() (*ControllerV1, informers.SharedInformerFactory) { factory := informers.NewSharedInformerFactory(f.client, time.Duration(0)) - wmeta := fxutil.Test[workloadmeta.Component](f.t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](f.t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) return NewControllerV1( f.client, factory.Core().V1().Secrets(), diff --git a/pkg/clusteragent/admission/controllers/webhook/controller_v1beta1_test.go b/pkg/clusteragent/admission/controllers/webhook/controller_v1beta1_test.go index c35e0a86ce6fe..540ce5fbc44d6 100644 --- a/pkg/clusteragent/admission/controllers/webhook/controller_v1beta1_test.go +++ b/pkg/clusteragent/admission/controllers/webhook/controller_v1beta1_test.go @@ -944,8 +944,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), fx.Replace(configComp.MockParams{Overrides: map[string]interface{}{"kube_resources_namespace": "nsfoo"}}), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), ) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1081,7 +1080,7 @@ func newFixtureV1beta1(t *testing.T) *fixtureV1beta1 { func (f *fixtureV1beta1) createController() (*ControllerV1beta1, informers.SharedInformerFactory) { factory := informers.NewSharedInformerFactory(f.client, time.Duration(0)) - wmeta := fxutil.Test[workloadmeta.Component](f.t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](f.t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) return NewControllerV1beta1( f.client, factory.Core().V1().Secrets(), diff --git a/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation.go b/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation.go index 0d50bc62e338e..2ea1076879239 100644 --- a/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation.go +++ b/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation.go @@ -89,11 +89,19 @@ func NewWebhook(wmeta workloadmeta.Component, filter mutatecommon.InjectionFilte return nil, fmt.Errorf("invalid version for key apm_config.instrumentation.version: %w", err) } - containerRegistry := mutatecommon.ContainerRegistry("admission_controller.auto_instrumentation.container_registry") + var ( + isEnabled = config.Datadog().GetBool("admission_controller.auto_instrumentation.enabled") + containerRegistry = mutatecommon.ContainerRegistry("admission_controller.auto_instrumentation.container_registry") + pinnedLibraries []libInfo + ) + + if isEnabled { + pinnedLibraries = getPinnedLibraries(containerRegistry) + } return &Webhook{ name: webhookName, - isEnabled: config.Datadog().GetBool("admission_controller.auto_instrumentation.enabled"), + isEnabled: isEnabled, endpoint: config.Datadog().GetString("admission_controller.auto_instrumentation.endpoint"), resources: []string{"pods"}, operations: []admiv1.OperationType{admiv1.Create}, @@ -102,7 +110,7 @@ func NewWebhook(wmeta workloadmeta.Component, filter mutatecommon.InjectionFilte injectionFilter: filter, containerRegistry: containerRegistry, injectorImageTag: config.Datadog().GetString("apm_config.instrumentation.injector_image_tag"), - pinnedLibraries: getPinnedLibraries(containerRegistry), + pinnedLibraries: pinnedLibraries, version: v, wmeta: wmeta, }, nil @@ -155,10 +163,13 @@ func initContainerName(lang language) string { return fmt.Sprintf("datadog-lib-%s-init", lang) } +// isPodEligible checks whether we are allowed to inject in this pod. func (w *Webhook) isPodEligible(pod *corev1.Pod) bool { return w.injectionFilter.ShouldMutatePod(pod) } +// isEnabledInNamespace checks whether this namespace is opted into or out of +// single step (auto_instrumentation) outside pod-specific annotations. func (w *Webhook) isEnabledInNamespace(namespace string) bool { return w.injectionFilter.NSFilter.IsNamespaceEligible(namespace) } @@ -185,8 +196,8 @@ func (w *Webhook) inject(pod *corev1.Pod, ns string, _ dynamic.Interface) (bool, } } - libsToInject, autoDetected := w.extractLibInfo(pod) - if len(libsToInject) == 0 { + extractedLibInfo := w.extractLibInfo(pod) + if len(extractedLibInfo.libs) == 0 { return false, nil } @@ -202,19 +213,7 @@ func (w *Webhook) inject(pod *corev1.Pod, ns string, _ dynamic.Interface) (bool, } } - // Inject env variables used for Onboarding KPIs propagation - var injectionType string - if w.isEnabledInNamespace(pod.Namespace) { - // if Single Step Instrumentation is enabled, inject DD_INSTRUMENTATION_INSTALL_TYPE:k8s_single_step - _ = mutatecommon.InjectEnv(pod, singleStepInstrumentationInstallTypeEnvVar) - injectionType = singleStepInstrumentationInstallType - } else { - // if local library injection is enabled, inject DD_INSTRUMENTATION_INSTALL_TYPE:k8s_lib_injection - _ = mutatecommon.InjectEnv(pod, localLibraryInstrumentationInstallTypeEnvVar) - injectionType = localLibraryInstrumentationInstallType - } - - if err := w.injectAutoInstruConfig(pod, libsToInject, autoDetected, injectionType); err != nil { + if err := w.injectAutoInstruConfig(pod, extractedLibInfo); err != nil { log.Errorf("failed to inject auto instrumentation configurations: %v", err) return false, errors.New(metrics.ConfigInjectionError) } @@ -308,15 +307,59 @@ func getPinnedLibraries(registry string) []libInfo { return res } -// getLibrariesLanguageDetection runs process language auto-detection and returns languages to inject for APM Instrumentation. -// The languages information is available in workloadmeta-store and attached on the pod's owner. -func (w *Webhook) getLibrariesLanguageDetection(pod *corev1.Pod) []libInfo { - if config.Datadog().GetBool("admission_controller.auto_instrumentation.inject_auto_detected_libraries") { - // Use libraries returned by language detection for APM Instrumentation - return w.getAutoDetectedLibraries(pod) +type libInfoLanguageDetection struct { + libs []libInfo + injectionEnabled bool +} + +func (l *libInfoLanguageDetection) containerMutator(v version) containerMutator { + return containerMutatorFunc(func(c *corev1.Container) error { + if !v.usesInjector() || l == nil { + return nil + } + + var langs []string + for _, lib := range l.libs { + if lib.ctrName == c.Name { // strict container name matching + langs = append(langs, string(lib.lang)) + } + } + + // N.B. + // We report on the languages detected regardless + // of if it is empty or not to disambiguate the empty state + // language_detection reporting being disabled. + if err := (containerMutators{ + envVar{ + key: "DD_INSTRUMENTATION_LANGUAGES_DETECTED", + valFunc: identityValFunc(strings.Join(langs, ",")), + }, + envVar{ + key: "DD_INSTRUMENTATION_LANGUAGE_DETECTION_INJECTION_ENABLED", + valFunc: identityValFunc(strconv.FormatBool(l.injectionEnabled)), + }, + }).mutateContainer(c); err != nil { + return err + } + + return nil + }) +} + +// getLibrariesLanguageDetection returns the languages that were detected by process language detection. +// +// The languages information is available in workloadmeta-store +// and attached on the pod's owner. +func (w *Webhook) getLibrariesLanguageDetection(pod *corev1.Pod) *libInfoLanguageDetection { + if !config.Datadog().GetBool("language_detection.enabled") || + !config.Datadog().GetBool("language_detection.reporting.enabled") { + return nil } - return nil + return &libInfoLanguageDetection{ + libs: w.getAutoDetectedLibraries(pod), + injectionEnabled: config.Datadog().GetBool("admission_controller.auto_instrumentation.inject_auto_detected_libraries"), + } } // getAllLatestLibraries returns all supported by APM Instrumentation tracing libraries @@ -329,35 +372,125 @@ func (w *Webhook) getAllLatestLibraries() []libInfo { return libsToInject } -// extractLibInfo returns the language, the image, -// and a boolean indicating whether the library should be injected into the pod -func (w *Webhook) extractLibInfo(pod *corev1.Pod) ([]libInfo, bool) { - // If the pod is "injectable" and annotated with libraries to inject, use those. - if w.isPodEligible(pod) { - // The library version specified via annotation on the Pod takes precedence - // over libraries injected with Single Step Instrumentation - libs := w.extractLibrariesFromAnnotations(pod) - if len(libs) > 0 { - return libs, false - } +// libInfoSource describes where we got the libraries from for +// injection and is used to set up metrics/telemetry. See +// Webhook.injectAutoInstruConfig for usage. +type libInfoSource int + +const ( + // libInfoSourceNone is no source provided. + libInfoSourceNone libInfoSource = iota + // libInfoSourceLibInjection is when the user sets up annotations on their pods for + // library injection and single step is disabled. + libInfoSourceLibInjection + // libInfoSourceSingleStepInstrumentation is when we are using the instrumentation config + // to determine which libraries to inject. + libInfoSourceSingleStepInstrumentation + // libInfoSourceSingleStepLanguageDetection is when we use the language detection + // annotation to determine which libs to inject. + libInfoSourceSingleStepLangaugeDetection +) + +// injectionType produces a string to distinguish between if +// we're using "single step" or "lib injection" for metrics and logging. +func (s libInfoSource) injectionType() string { + switch s { + case libInfoSourceSingleStepInstrumentation, libInfoSourceSingleStepLangaugeDetection: + return singleStepInstrumentationInstallType + case libInfoSourceLibInjection: + return localLibraryInstrumentationInstallType + default: + return "unknown" } +} + +func (s libInfoSource) isSingleStep() bool { + return s.injectionType() == singleStepInstrumentationInstallType +} + +// isFromLanguageDetection tells us whether this source comes from +// the language detection reporting and annotation. +func (s libInfoSource) isFromLanguageDetection() bool { + return s == libInfoSourceSingleStepLangaugeDetection +} + +func (s libInfoSource) mutatePod(pod *corev1.Pod) error { + _ = mutatecommon.InjectEnv(pod, corev1.EnvVar{ + Name: instrumentationInstallTypeEnvVarName, + Value: s.injectionType(), + }) + return nil +} + +type extractedPodLibInfo struct { + // libs are the libraries we are going to attempt to inject into the given pod. + libs []libInfo + // languageDetection is set when we ran/used the language-detection annotation. + languageDetection *libInfoLanguageDetection + // source is where we got the data from, used for telemetry later. + source libInfoSource +} + +func (e extractedPodLibInfo) withLibs(l []libInfo) extractedPodLibInfo { + e.libs = l + return e +} + +func (e extractedPodLibInfo) useLanguageDetectionLibs() (extractedPodLibInfo, bool) { + if e.languageDetection != nil && len(e.languageDetection.libs) > 0 && e.languageDetection.injectionEnabled { + e.libs = e.languageDetection.libs + e.source = libInfoSourceSingleStepLangaugeDetection + return e, true + } + + return e, false +} + +func (w *Webhook) initExtractedLibInfo(pod *corev1.Pod) extractedPodLibInfo { + // it's possible to get here without single step being enabled, and the pod having + // annotations on it to opt it into pod mutation, we disambiguate those two cases. + var ( + source = libInfoSourceLibInjection + languageDetection *libInfoLanguageDetection + ) - // If auto-instrumentation is enabled in the namespace and nothing has been overridden, - // - // 1. We check for pinned libraries in the config - // 2. We check for language detection (if enabled) - // 3. We fall back to "latest" if w.isEnabledInNamespace(pod.Namespace) { - if len(w.pinnedLibraries) > 0 { - return w.pinnedLibraries, false - } + source = libInfoSourceSingleStepInstrumentation + languageDetection = w.getLibrariesLanguageDetection(pod) + } - detected := w.getLibrariesLanguageDetection(pod) - if len(detected) > 0 { - return detected, true - } + return extractedPodLibInfo{ + source: source, + languageDetection: languageDetection, + } +} + +// extractLibInfo metadata about what library information we should be +// injecting into the pod and where it came from. +func (w *Webhook) extractLibInfo(pod *corev1.Pod) extractedPodLibInfo { + extracted := w.initExtractedLibInfo(pod) + + libs := w.extractLibrariesFromAnnotations(pod) + if len(libs) > 0 { + return extracted.withLibs(libs) + } + + // if the user has pinned libraries for their configuration, + // we prefer to use these and not override their behavior. + // + // N.B. this is empty if auto-instrumentation is disabled. + if len(w.pinnedLibraries) > 0 { + return extracted.withLibs(w.pinnedLibraries) + } - return w.getAllLatestLibraries(), false + // if the language_detection injection is enabled + // (and we have things to filter to) we use that! + if e, usingLanguageDetection := extracted.useLanguageDetectionLibs(); usingLanguageDetection { + return e + } + + if extracted.source.isSingleStep() { + return extracted.withLibs(w.getAllLatestLibraries()) } // Get libraries to inject for Remote Instrumentation @@ -370,10 +503,11 @@ func (w *Webhook) extractLibInfo(pod *corev1.Pod) ([]libInfo, bool) { if version != "latest" { log.Warnf("Ignoring version %q. To inject all libs, the only supported version is latest for now", version) } - return w.getAllLatestLibraries(), false + + return extracted.withLibs(w.getAllLatestLibraries()) } - return nil, false + return extractedPodLibInfo{} } // getAutoDetectedLibraries constructs the libraries to be injected if the languages @@ -427,15 +561,14 @@ func (w *Webhook) extractLibrariesFromAnnotations(pod *corev1.Pod) []libInfo { return libList } -func (w *Webhook) initContainerMutators() []containerMutator { - return []containerMutator{ +func (w *Webhook) initContainerMutators() containerMutators { + return containerMutators{ containerResourceRequirements{w.initResourceRequirements}, containerSecurityContext{w.initSecurityContext}, } } -func (w *Webhook) newInjector(startTime time.Time, pod *corev1.Pod) *injector { - var opts []injectorOption +func (w *Webhook) newInjector(startTime time.Time, pod *corev1.Pod, opts ...injectorOption) podMutator { for _, e := range []annotationExtractor[injectorOption]{ injectorVersionAnnotationExtractor, injectorImageAnnotationExtractor, @@ -450,34 +583,48 @@ func (w *Webhook) newInjector(startTime time.Time, pod *corev1.Pod) *injector { opts = append(opts, opt) } - return newInjector(startTime, w.containerRegistry, w.injectorImageTag, opts...) + return newInjector(startTime, w.containerRegistry, w.injectorImageTag, opts...). + podMutator(w.version) } -func (w *Webhook) injectAutoInstruConfig(pod *corev1.Pod, libsToInject []libInfo, autoDetected bool, injectionType string) error { - if len(libsToInject) == 0 { +func (w *Webhook) injectAutoInstruConfig(pod *corev1.Pod, config extractedPodLibInfo) error { + if len(config.libs) == 0 { return nil } - // inject the env for the pod. - _ = mutatecommon.InjectEnv(pod, localLibraryInstrumentationInstallTypeEnvVar) - var ( - lastError error - configInjector = &libConfigInjector{} + lastError error + configInjector = &libConfigInjector{} + injectionType = config.source.injectionType() + autoDetected = config.source.isFromLanguageDetection() + initContainerMutators = w.initContainerMutators() - apmInjector = w.newInjector(time.Now(), pod) + injector = w.newInjector(time.Now(), pod, injectorWithLibRequirementOptions(libRequirementOptions{ + initContainerMutators: initContainerMutators, + })) + containerMutators = containerMutators{ + config.languageDetection.containerMutator(w.version), + } ) - for _, lib := range libsToInject { + // Inject env variables used for Onboarding KPIs propagation... + // if Single Step Instrumentation is enabled, inject DD_INSTRUMENTATION_INSTALL_TYPE:k8s_single_step + // if local library injection is enabled, inject DD_INSTRUMENTATION_INSTALL_TYPE:k8s_lib_injection + if err := config.source.mutatePod(pod); err != nil { + return err + } + + for _, lib := range config.libs { injected := false langStr := string(lib.lang) defer func() { metrics.LibInjectionAttempts.Inc(langStr, strconv.FormatBool(injected), strconv.FormatBool(autoDetected), injectionType) }() - if err := lib.podMutator(w.version, initContainerMutators, []podMutator{ - configInjector.podMutator(lib.lang), - apmInjector.podMutator(w.version), + if err := lib.podMutator(w.version, libRequirementOptions{ + containerMutators: containerMutators, + initContainerMutators: initContainerMutators, + podMutators: []podMutator{configInjector.podMutator(lib.lang), injector}, }).mutatePod(pod); err != nil { metrics.LibInjectionErrors.Inc(langStr, strconv.FormatBool(autoDetected), injectionType) lastError = err diff --git a/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_test.go b/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_test.go index 5c5425073fee6..1722cb5cb0832 100644 --- a/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_test.go +++ b/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_test.go @@ -38,34 +38,42 @@ import ( const commonRegistry = "gcr.io/datadoghq" func TestInjectAutoInstruConfigV2(t *testing.T) { - c := configmock.New(t) tests := []struct { - name string - pod *corev1.Pod - expectedInjectorImage string - libsToInject []libInfo - wantErr bool - config func() + name string + pod *corev1.Pod + libInfo extractedPodLibInfo + expectedInjectorImage string + expectedLangsDetected string + expectedInstallType string + expectedSecurityContext *corev1.SecurityContext + wantErr bool + config func(c model.Config) }{ { name: "no libs, no injection", pod: common.FakePod("java-pod"), }, { - name: "nominal case: java", - pod: common.FakePod("java-pod"), - expectedInjectorImage: commonRegistry + "/apm-inject:0", - libsToInject: []libInfo{ - java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + name: "nominal case: java", + pod: common.FakePod("java-pod"), + expectedInjectorImage: commonRegistry + "/apm-inject:0", + expectedSecurityContext: &corev1.SecurityContext{}, + libInfo: extractedPodLibInfo{ + libs: []libInfo{ + java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + }, }, }, { - name: "nominal case: java & python", - pod: common.FakePod("java-pod"), - expectedInjectorImage: commonRegistry + "/apm-inject:0", - libsToInject: []libInfo{ - java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), - python.libInfo("", "gcr.io/datadoghq/dd-lib-python-init:v1"), + name: "nominal case: java & python", + pod: common.FakePod("java-pod"), + expectedInjectorImage: commonRegistry + "/apm-inject:0", + expectedSecurityContext: &corev1.SecurityContext{}, + libInfo: extractedPodLibInfo{ + libs: []libInfo{ + java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + python.libInfo("", "gcr.io/datadoghq/dd-lib-python-init:v1"), + }, }, }, { @@ -75,9 +83,12 @@ func TestInjectAutoInstruConfigV2(t *testing.T) { "admission.datadoghq.com/apm-inject.version": "v0", }, }.Create(), - expectedInjectorImage: commonRegistry + "/apm-inject:v0", - libsToInject: []libInfo{ - java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + expectedInjectorImage: commonRegistry + "/apm-inject:v0", + expectedSecurityContext: &corev1.SecurityContext{}, + libInfo: extractedPodLibInfo{ + libs: []libInfo{ + java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + }, }, }, { @@ -87,19 +98,100 @@ func TestInjectAutoInstruConfigV2(t *testing.T) { "admission.datadoghq.com/apm-inject.custom-image": "docker.io/library/apm-inject-package:v27", }, }.Create(), - expectedInjectorImage: "docker.io/library/apm-inject-package:v27", - libsToInject: []libInfo{ - java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + expectedInjectorImage: "docker.io/library/apm-inject-package:v27", + expectedSecurityContext: &corev1.SecurityContext{}, + libInfo: extractedPodLibInfo{ + libs: []libInfo{ + java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + }, + }, + }, + { + name: "config injector-image-override", + pod: common.FakePod("java-pod"), + expectedInjectorImage: "gcr.io/datadoghq/apm-inject:0.16-1", + expectedSecurityContext: &corev1.SecurityContext{}, + libInfo: extractedPodLibInfo{ + libs: []libInfo{ + java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + }, + }, + config: func(c model.Config) { + c.SetWithoutSource("apm_config.instrumentation.injector_image_tag", "0.16-1") }, }, { - name: "config injector-image-override", + name: "config language detected env vars", + pod: common.FakePod("java-pod"), + expectedInjectorImage: "gcr.io/datadoghq/apm-inject:0.16-1", + expectedLangsDetected: "python", + expectedInstallType: "k8s_lib_injection", + expectedSecurityContext: &corev1.SecurityContext{}, + libInfo: extractedPodLibInfo{ + languageDetection: &libInfoLanguageDetection{ + libs: []libInfo{ + python.defaultLibInfo(commonRegistry, "java-pod-container"), + }, + }, + libs: []libInfo{ + java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + }, + source: libInfoSourceLibInjection, + }, + config: func(c model.Config) { + c.SetWithoutSource("apm_config.instrumentation.injector_image_tag", "0.16-1") + }, + }, + { + name: "language detected for a different container", + pod: common.FakePod("java-pod"), + expectedInjectorImage: "gcr.io/datadoghq/apm-inject:0", + expectedSecurityContext: &corev1.SecurityContext{}, + expectedLangsDetected: "", + libInfo: extractedPodLibInfo{ + languageDetection: &libInfoLanguageDetection{ + libs: []libInfo{ + python.defaultLibInfo(commonRegistry, "not-java-pod-container"), + }, + }, + libs: []libInfo{ + java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + }, + }, + }, + { + name: "language detected but no languages found", + pod: common.FakePod("java-pod"), + expectedInjectorImage: "gcr.io/datadoghq/apm-inject:0", + expectedSecurityContext: &corev1.SecurityContext{}, + expectedLangsDetected: "", + libInfo: extractedPodLibInfo{ + languageDetection: &libInfoLanguageDetection{}, + libs: []libInfo{ + java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + }, + }, + }, + { + name: "with specified install type and container security context", pod: common.FakePod("java-pod"), expectedInjectorImage: "gcr.io/datadoghq/apm-inject:0.16-1", - libsToInject: []libInfo{ - java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + expectedSecurityContext: &corev1.SecurityContext{ + Privileged: pointer.Ptr(false), + }, + expectedLangsDetected: "python", + libInfo: extractedPodLibInfo{ + languageDetection: &libInfoLanguageDetection{ + libs: []libInfo{ + python.defaultLibInfo(commonRegistry, "java-pod-container"), + }, + }, + libs: []libInfo{ + java.libInfo("", "gcr.io/datadoghq/dd-lib-java-init:v1"), + }, + source: libInfoSourceSingleStepLangaugeDetection, }, - config: func() { + config: func(c model.Config) { c.SetWithoutSource("apm_config.instrumentation.injector_image_tag", "0.16-1") }, }, @@ -107,24 +199,31 @@ func TestInjectAutoInstruConfigV2(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - wmeta := fxutil.Test[workloadmeta.Component]( - t, - core.MockBundle(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), - ) + wmeta := common.FakeStoreWithDeployment(t, nil) + + c := configmock.New(t) - c = configmock.New(t) c.SetWithoutSource("apm_config.instrumentation.version", "v2") if tt.config != nil { - tt.config() + tt.config(c) } webhook := mustWebhook(t, wmeta) require.Equal(t, instrumentationV2, webhook.version) require.True(t, webhook.version.usesInjector()) - err := webhook.injectAutoInstruConfig(tt.pod, tt.libsToInject, false, "") + webhook.initSecurityContext = tt.expectedSecurityContext + + if tt.libInfo.source == libInfoSourceNone { + tt.libInfo.source = libInfoSourceSingleStepInstrumentation + } + + if tt.expectedInstallType == "" { + tt.expectedInstallType = "k8s_single_step" + } + + err := webhook.injectAutoInstruConfig(tt.pod, tt.libInfo) + if tt.wantErr { require.Error(t, err, "expected injectAutoInstruConfig to error") } else { @@ -143,7 +242,7 @@ func TestInjectAutoInstruConfigV2(t *testing.T) { requireEnv := func(t *testing.T, key string, ok bool, value string) { t.Helper() val, exists := envsByName[key] - require.Equal(t, ok, exists, "expected env %v to be %v", key, ok) + require.Equal(t, ok, exists, "expected env %v exists to = %v", key, ok) require.Equal(t, value, val.Value, "expected env %v = %v", key, val) } @@ -151,7 +250,7 @@ func TestInjectAutoInstruConfigV2(t *testing.T) { requireEnv(t, env.Name, false, "") } - if len(tt.libsToInject) == 0 { + if len(tt.libInfo.libs) == 0 { require.Zero(t, len(tt.pod.Spec.InitContainers), "no libs, no init containers") requireEnv(t, "LD_PRELOAD", false, "") return @@ -160,21 +259,27 @@ func TestInjectAutoInstruConfigV2(t *testing.T) { require.Equal(t, volumeName, tt.pod.Spec.Volumes[0].Name, "expected datadog volume to be injected") - require.Equal(t, len(tt.libsToInject)+1, len(tt.pod.Spec.InitContainers), + require.Equal(t, etcVolume.Name, tt.pod.Spec.Volumes[1].Name, + "expected datadog-etc volume to be injected") + + require.Equal(t, len(tt.libInfo.libs)+1, len(tt.pod.Spec.InitContainers), "expected there to be one more than the number of libs to inject for init containers") for i, c := range tt.pod.Spec.InitContainers { + require.Equal(t, tt.expectedSecurityContext, c.SecurityContext, + "expected %s.SecurityContext to be set", c.Name) + var injectorMountPath string - if i == 0 { // check init container + if i == 0 { // check inject container require.Equal(t, "datadog-init-apm-inject", c.Name, "expected the first init container to be apm-inject") require.Equal(t, tt.expectedInjectorImage, c.Image, "expected the container image to be %s", tt.expectedInjectorImage) injectorMountPath = c.VolumeMounts[0].MountPath } else { // lib volumes for each of the rest of the containers - lib := tt.libsToInject[i-1] + lib := tt.libInfo.libs[i-1] require.Equal(t, lib.image, c.Image) require.Equal(t, "opt/datadog/apm/library/"+string(lib.lang), c.VolumeMounts[0].SubPath, "expected a language specific sub-path for the volume mount for lang %s", @@ -187,32 +292,52 @@ func TestInjectAutoInstruConfigV2(t *testing.T) { // each of the init containers writes a timestamp to their given volume mount path require.Equal(t, 1, len(c.Args), "expected container args") - _, suffix, found := strings.Cut(c.Args[0], "&&") - require.True(t, found, "expected container args separated by &&") - echoDate, toFile, found := strings.Cut(suffix, ">>") - require.True(t, found, "expected container args with piping redirection") - require.Equal(t, "echo $(date +%s)", strings.TrimSpace(echoDate), "expected container args with date") - require.Equal(t, injectorMountPath+"/c-init-time."+c.Name, strings.TrimSpace(toFile), - "expected to write to file based on the container name") + // the last part of each of the init container's command should be writing + // a timestamp based on the name of the container. + expectedTimestampPath := injectorMountPath + "/c-init-time." + c.Name + cmdTail := "&& echo $(date +%s) >> " + expectedTimestampPath + require.Contains(t, c.Args[0], cmdTail, "expected args to contain %s", cmdTail) + prefix, found := strings.CutSuffix(c.Args[0], cmdTail) + require.True(t, found, "expected args to end with %s ", cmdTail) + + if i == 0 { // inject container + require.Contains(t, prefix, "&& echo /opt/datadog-packages/datadog-apm-inject/stable/inject/launcher.preload.so > /datadog-etc/ld.so.preload") + } } - // two volume mounts + // three volume mounts mounts := tt.pod.Spec.Containers[0].VolumeMounts - require.Equal(t, 2, len(mounts), "expected 2 volume mounts in the application container") + require.Equal(t, 3, len(mounts), "expected 3 volume mounts in the application container") require.Equal(t, corev1.VolumeMount{ Name: volumeName, MountPath: "/opt/datadog-packages/datadog-apm-inject", SubPath: "opt/datadog-packages/datadog-apm-inject", ReadOnly: true, }, mounts[0], "expected first container volume mount to be the injector") + require.Equal(t, corev1.VolumeMount{ + Name: etcVolume.Name, + MountPath: "/etc/ld.so.preload", + SubPath: "ld.so.preload", + ReadOnly: true, + }, mounts[1], "expected first container volume mount to be the injector") require.Equal(t, corev1.VolumeMount{ Name: volumeName, MountPath: "/opt/datadog/apm/library", SubPath: "opt/datadog/apm/library", - }, mounts[1], "expected the second container volume mount to be the language libraries") + }, mounts[2], "expected the second container volume mount to be the language libraries") requireEnv(t, "LD_PRELOAD", true, "/opt/datadog-packages/datadog-apm-inject/stable/inject/launcher.preload.so") requireEnv(t, "DD_INJECT_SENDER_TYPE", true, "k8s") + + requireEnv(t, "DD_INSTRUMENTATION_INSTALL_TYPE", true, tt.expectedInstallType) + + if tt.libInfo.languageDetection == nil { + requireEnv(t, "DD_INSTRUMENTATION_LANGUAGES_DETECTED", false, "") + requireEnv(t, "DD_INSTRUMENTATION_LANGUAGE_DETECTION_INJECTION_ENABLED", false, "") + } else { + requireEnv(t, "DD_INSTRUMENTATION_LANGUAGES_DETECTED", true, tt.expectedLangsDetected) + requireEnv(t, "DD_INSTRUMENTATION_LANGUAGE_DETECTION_INJECTION_ENABLED", true, strconv.FormatBool(tt.libInfo.languageDetection.injectionEnabled)) + } }) } } @@ -423,14 +548,21 @@ func TestInjectAutoInstruConfig(t *testing.T) { wantErr: true, }, } - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + wmeta := fxutil.Test[workloadmeta.Component](t, + core.MockBundle(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), + ) + c := configmock.New(t) c.SetWithoutSource("apm_config.instrumentation.version", "v1") webhook := mustWebhook(t, wmeta) - err := webhook.injectAutoInstruConfig(tt.pod, tt.libsToInject, false, "") + err := webhook.injectAutoInstruConfig(tt.pod, extractedPodLibInfo{ + libs: tt.libsToInject, + source: libInfoSourceLibInjection, + }) if tt.wantErr { require.Error(t, err, "expected injectAutoInstruConfig to error") } else { @@ -560,18 +692,17 @@ func TestExtractLibInfo(t *testing.T) { containerRegistry: "registry", expectedPodEligible: pointer.Ptr(true), expectedLibsToInject: []libInfo{ - { - lang: "python", - image: "registry/dd-lib-python-init:v1", - }, + python.libInfo("", "registry/dd-lib-python-init:v1"), }, }, { - name: "python with unlabelled injection off", - pod: common.FakePodWithAnnotation("admission.datadoghq.com/python-lib.version", "v1"), - containerRegistry: "registry", - expectedPodEligible: pointer.Ptr(false), - expectedLibsToInject: []libInfo{}, + name: "python with unlabelled injection off", + pod: common.FakePodWithAnnotation("admission.datadoghq.com/python-lib.version", "v1"), + containerRegistry: "registry", + expectedPodEligible: pointer.Ptr(false), + expectedLibsToInject: []libInfo{ + python.libInfo("", "registry/dd-lib-python-init:v1"), + }, setupConfig: func() { mockConfig.SetWithoutSource("admission_controller.mutate_unlabelled", false) }, @@ -581,10 +712,7 @@ func TestExtractLibInfo(t *testing.T) { pod: common.FakePodWithAnnotation("admission.datadoghq.com/java-lib.custom-image", "custom/image"), containerRegistry: "registry", expectedLibsToInject: []libInfo{ - { - lang: "java", - image: "custom/image", - }, + java.libInfo("", "custom/image"), }, }, { @@ -852,8 +980,7 @@ func TestExtractLibInfo(t *testing.T) { wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), fx.Replace(configComp.MockParams{Overrides: overrides}), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), ) mockConfig = configmock.New(t) for k, v := range overrides { @@ -870,8 +997,8 @@ func TestExtractLibInfo(t *testing.T) { require.Equal(t, *tt.expectedPodEligible, webhook.isPodEligible(tt.pod)) } - libsToInject, _ := webhook.extractLibInfo(tt.pod) - require.ElementsMatch(t, tt.expectedLibsToInject, libsToInject) + extracted := webhook.extractLibInfo(tt.pod) + require.ElementsMatch(t, tt.expectedLibsToInject, extracted.libs) }) } } @@ -1075,9 +1202,13 @@ func TestInjectLibInitContainer(t *testing.T) { }, } - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + wmeta := fxutil.Test[workloadmeta.Component](t, + core.MockBundle(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), + ) + conf := configmock.New(t) if tt.cpu != "" { conf.SetWithoutSource("admission_controller.auto_instrumentation.init_resources.cpu", tt.cpu) @@ -2235,6 +2366,8 @@ func TestInjectAutoInstrumentation(t *testing.T) { wantWebhookInitErr: false, setupConfig: funcs{ wConfig("admission_controller.auto_instrumentation.inject_auto_detected_libraries", true), + wConfig("language_detection.enabled", true), + wConfig("language_detection.reporting.enabled", true), enableAPMInstrumentation, }, }, @@ -2874,7 +3007,7 @@ func TestShouldInject(t *testing.T) { want: false, }, { - name: "instrumentation on with disabled namespace, no label", + name: "instrumentation on with disabled namespace, no label ns", pod: common.FakePodWithNamespaceAndLabel("ns", "", ""), setupConfig: func() { mockConfig.SetWithoutSource("apm_config.instrumentation.enabled", true) @@ -2883,7 +3016,7 @@ func TestShouldInject(t *testing.T) { want: false, }, { - name: "instrumentation on with disabled namespace, no label", + name: "instrumentation on with disabled namespace, no label ns2", pod: common.FakePodWithNamespaceAndLabel("ns2", "", ""), setupConfig: func() { mockConfig.SetWithoutSource("apm_config.instrumentation.enabled", true) @@ -3026,9 +3159,13 @@ func TestShouldInject(t *testing.T) { want: false, }, } - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + wmeta := fxutil.Test[workloadmeta.Component](t, + core.MockBundle(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), + ) + mockConfig = configmock.New(t) tt.setupConfig() diff --git a/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_util.go b/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_util.go index 0dfd2fa786120..29d89b3702c4b 100644 --- a/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_util.go +++ b/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_util.go @@ -50,6 +50,12 @@ func getLibListFromDeploymentAnnotations(store workloadmeta.Component, deploymen var libList []libInfo for container, languages := range deployment.InjectableLanguages { for lang := range languages { + // There's a mismatch between language detection and auto-instrumentation. + // The Node language is a js lib. + if lang == "node" { + lang = "js" + } + l := language(lang) libList = append(libList, l.defaultLibInfo(registry, container.Name)) } diff --git a/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_util_test.go b/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_util_test.go index 1b9b6fb51d557..245a2e6594c34 100644 --- a/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_util_test.go +++ b/pkg/clusteragent/admission/mutate/autoinstrumentation/auto_instrumentation_util_test.go @@ -71,7 +71,6 @@ func TestGetOwnerNameAndKind(t *testing.T) { require.Equal(t, found, tt.wantFound) require.Equal(t, name, tt.expectedName) require.Equal(t, kind, tt.expectedKind) - }) } } @@ -97,8 +96,7 @@ func TestGetLibListFromDeploymentAnnotations(t *testing.T) { mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) //java, js, python, dotnet, ruby diff --git a/pkg/clusteragent/admission/mutate/autoinstrumentation/env_vars.go b/pkg/clusteragent/admission/mutate/autoinstrumentation/env_vars.go index 78b508f030b43..f59a97b912d25 100644 --- a/pkg/clusteragent/admission/mutate/autoinstrumentation/env_vars.go +++ b/pkg/clusteragent/admission/mutate/autoinstrumentation/env_vars.go @@ -60,18 +60,6 @@ const ( localLibraryInstrumentationInstallType = "k8s_lib_injection" ) -var ( - singleStepInstrumentationInstallTypeEnvVar = corev1.EnvVar{ - Name: instrumentationInstallTypeEnvVarName, - Value: singleStepInstrumentationInstallType, - } - - localLibraryInstrumentationInstallTypeEnvVar = corev1.EnvVar{ - Name: instrumentationInstallTypeEnvVarName, - Value: localLibraryInstrumentationInstallType, - } -) - type envVar struct { key string valFunc envValFunc diff --git a/pkg/clusteragent/admission/mutate/autoinstrumentation/injector.go b/pkg/clusteragent/admission/mutate/autoinstrumentation/injector.go index eaa5e1250e9c9..9bbb27efff578 100644 --- a/pkg/clusteragent/admission/mutate/autoinstrumentation/injector.go +++ b/pkg/clusteragent/admission/mutate/autoinstrumentation/injector.go @@ -15,6 +15,19 @@ import ( corev1 "k8s.io/api/core/v1" ) +const ( + injectPackageDir = "opt/datadog-packages/datadog-apm-inject" + libraryPackagesDir = "opt/datadog/apm/library" +) + +func asAbs(path string) string { + return "/" + path +} + +func injectorFilePath(name string) string { + return injectPackageDir + "/stable/inject/" + name +} + var sourceVolume = volume{ Volume: corev1.Volume{ Name: volumeName, @@ -29,13 +42,32 @@ var v1VolumeMount = sourceVolume.mount(corev1.VolumeMount{ }) var v2VolumeMountInjector = sourceVolume.mount(corev1.VolumeMount{ - MountPath: "/opt/datadog-packages/datadog-apm-inject", - SubPath: "opt/datadog-packages/datadog-apm-inject", + MountPath: asAbs(injectPackageDir), + SubPath: injectPackageDir, }) var v2VolumeMountLibrary = sourceVolume.mount(corev1.VolumeMount{ - MountPath: "/opt/datadog/apm/library", - SubPath: "opt/datadog/apm/library", + MountPath: asAbs(libraryPackagesDir), + SubPath: libraryPackagesDir, +}) + +var etcVolume = volume{ + Volume: corev1.Volume{ + Name: "datadog-auto-instrumentation-etc", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, +} + +var volumeMountETCDPreloadInitContainer = etcVolume.mount(corev1.VolumeMount{ + MountPath: "/datadog-etc", +}) + +var volumeMountETCDPreloadAppContainer = etcVolume.mount(corev1.VolumeMount{ + MountPath: "/etc/ld.so.preload", + SubPath: "ld.so.preload", + ReadOnly: true, }) type injector struct { @@ -43,6 +75,7 @@ type injector struct { registry string injected bool injectTime time.Time + opts libRequirementOptions } func (i *injector) initContainer() initContainer { @@ -62,33 +95,44 @@ func (i *injector) initContainer() initContainer { Image: i.image, Command: []string{"/bin/sh", "-c", "--"}, Args: []string{ + // TODO: We should probably move this into either a script that's in the container _or_ + // something we can do with a go template because this is not great. fmt.Sprintf( - `cp -r /%s/* %s && echo $(date +%%s) >> %s`, - mount.SubPath, mount.MountPath, tsFilePath, + `cp -r /%s/* %s && echo %s > /datadog-etc/ld.so.preload && echo $(date +%%s) >> %s`, + mount.SubPath, + mount.MountPath, + asAbs(injectorFilePath("launcher.preload.so")), + tsFilePath, ), }, - VolumeMounts: []corev1.VolumeMount{mount}, + VolumeMounts: []corev1.VolumeMount{ + mount, + volumeMountETCDPreloadInitContainer.VolumeMount, + }, }, } } func (i *injector) requirements() libRequirement { return libRequirement{ - initContainers: []initContainer{i.initContainer()}, - volumes: []volume{sourceVolume}, - volumeMounts: []volumeMount{v2VolumeMountInjector.readOnly().prepended()}, + libRequirementOptions: i.opts, + initContainers: []initContainer{i.initContainer()}, + volumes: []volume{ + sourceVolume, + etcVolume, + }, + volumeMounts: []volumeMount{ + volumeMountETCDPreloadAppContainer.prepended(), + v2VolumeMountInjector.readOnly().prepended(), + }, envVars: []envVar{ { - key: "LD_PRELOAD", - valFunc: identityValFunc( - "/opt/datadog-packages/datadog-apm-inject/stable/inject/launcher.preload.so", - ), + key: "LD_PRELOAD", + valFunc: identityValFunc(asAbs(injectorFilePath("launcher.preload.so"))), }, { - key: "DD_INJECT_SENDER_TYPE", - valFunc: identityValFunc( - "k8s", - ), + key: "DD_INJECT_SENDER_TYPE", + valFunc: identityValFunc("k8s"), }, { key: "DD_INJECT_START_TIME", @@ -110,6 +154,12 @@ var injectorImageAnnotationExtractor = annotationExtractor[injectorOption]{ do: infallibleFn(injectorWithImageName), } +func injectorWithLibRequirementOptions(opts libRequirementOptions) injectorOption { + return func(i *injector) { + i.opts = opts + } +} + func injectorWithImageName(name string) injectorOption { return func(i *injector) { i.image = name diff --git a/pkg/clusteragent/admission/mutate/autoinstrumentation/injector_test.go b/pkg/clusteragent/admission/mutate/autoinstrumentation/injector_test.go index 0850fe53e7c2c..e9be85ef21ee4 100644 --- a/pkg/clusteragent/admission/mutate/autoinstrumentation/injector_test.go +++ b/pkg/clusteragent/admission/mutate/autoinstrumentation/injector_test.go @@ -11,10 +11,36 @@ import ( "testing" "time" + "github.com/DataDog/datadog-agent/pkg/util/pointer" "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" ) func TestInjectorOptions(t *testing.T) { i := newInjector(time.Now(), "registry", "1") require.Equal(t, "registry/apm-inject:1", i.image) } + +func TestInjectorLibRequirements(t *testing.T) { + mutators := containerMutators{ + containerSecurityContext{ + &corev1.SecurityContext{ + AllowPrivilegeEscalation: pointer.Ptr(false), + }, + }, + } + i := newInjector(time.Now(), "registry", "1", + injectorWithLibRequirementOptions(libRequirementOptions{initContainerMutators: mutators}), + ) + + opts := i.requirements().libRequirementOptions + require.Equal(t, 1, len(opts.initContainerMutators)) + + container := corev1.Container{} + err := opts.initContainerMutators[0].mutateContainer(&container) + require.NoError(t, err) + + require.Equal(t, &corev1.SecurityContext{ + AllowPrivilegeEscalation: pointer.Ptr(false), + }, container.SecurityContext) +} diff --git a/pkg/clusteragent/admission/mutate/autoinstrumentation/language_versions.go b/pkg/clusteragent/admission/mutate/autoinstrumentation/language_versions.go index 539057bccd0d2..dccaf9fa8c9f3 100644 --- a/pkg/clusteragent/admission/mutate/autoinstrumentation/language_versions.go +++ b/pkg/clusteragent/admission/mutate/autoinstrumentation/language_versions.go @@ -134,7 +134,7 @@ type libInfo struct { image string } -func (i libInfo) podMutator(v version, ics []containerMutator, ms []podMutator) podMutator { +func (i libInfo) podMutator(v version, opts libRequirementOptions) podMutator { return podMutatorFunc(func(pod *corev1.Pod) error { reqs, ok := i.libRequirement(v) if !ok { @@ -144,19 +144,12 @@ func (i libInfo) podMutator(v version, ics []containerMutator, ms []podMutator) ) } - // set the initContainerMutators on the requirements - reqs.initContainerMutators = ics + reqs.libRequirementOptions = opts if err := reqs.injectPod(pod, i.ctrName); err != nil { return err } - for _, m := range ms { - if err := m.mutatePod(pod); err != nil { - return err - } - } - return nil }) } diff --git a/pkg/clusteragent/admission/mutate/autoinstrumentation/lib_requirement.go b/pkg/clusteragent/admission/mutate/autoinstrumentation/lib_requirement.go index fa232aee5a60c..e3a372b70f31b 100644 --- a/pkg/clusteragent/admission/mutate/autoinstrumentation/lib_requirement.go +++ b/pkg/clusteragent/admission/mutate/autoinstrumentation/lib_requirement.go @@ -11,32 +11,42 @@ import ( corev1 "k8s.io/api/core/v1" ) +type libRequirementOptions struct { + initContainerMutators containerMutators + containerMutators containerMutators + podMutators []podMutator +} + type libRequirement struct { - envVars []envVar - volumeMounts []volumeMount - initContainers []initContainer - volumes []volume - initContainerMutators []containerMutator + envVars []envVar + volumeMounts []volumeMount + initContainers []initContainer + volumes []volume + + libRequirementOptions } func (reqs libRequirement) injectPod(pod *corev1.Pod, ctrName string) error { for i, ctr := range pod.Spec.Containers { - if ctrName != "" && ctrName != ctr.Name { - continue - } - for _, v := range reqs.envVars { - if err := v.mutateContainer(&ctr); err != nil { - return err + if ctrName == "" || ctrName == ctr.Name { + for _, v := range reqs.envVars { + if err := v.mutateContainer(&ctr); err != nil { + return err + } } - } - for _, v := range reqs.volumeMounts { - if err := v.mutateContainer(&ctr); err != nil { - return err + for _, v := range reqs.volumeMounts { + if err := v.mutateContainer(&ctr); err != nil { + return err + } } } + if err := reqs.containerMutators.mutateContainer(&ctr); err != nil { + return err + } + pod.Spec.Containers[i] = ctr } @@ -54,5 +64,11 @@ func (reqs libRequirement) injectPod(pod *corev1.Pod, ctrName string) error { } } + for _, m := range reqs.podMutators { + if err := m.mutatePod(pod); err != nil { + return err + } + } + return nil } diff --git a/pkg/clusteragent/admission/mutate/autoinstrumentation/mutators.go b/pkg/clusteragent/admission/mutate/autoinstrumentation/mutators.go index ce12f12d878fb..d113de8cf95e1 100644 --- a/pkg/clusteragent/admission/mutate/autoinstrumentation/mutators.go +++ b/pkg/clusteragent/admission/mutate/autoinstrumentation/mutators.go @@ -19,6 +19,26 @@ type containerMutator interface { mutateContainer(*corev1.Container) error } +// containerMutatorFunc is a containerMutator as a function. +type containerMutatorFunc func(*corev1.Container) error + +// mutateContainer implements containerMutator for containerMutatorFunc. +func (f containerMutatorFunc) mutateContainer(c *corev1.Container) error { + return f(c) +} + +type containerMutators []containerMutator + +func (mutators containerMutators) mutateContainer(c *corev1.Container) error { + for _, m := range mutators { + if err := m.mutateContainer(c); err != nil { + return err + } + } + + return nil +} + // podMutator describes something that can mutate a pod. type podMutator interface { mutatePod(*corev1.Pod) error @@ -40,7 +60,7 @@ func (f podMutatorFunc) mutatePod(pod *corev1.Pod) error { type initContainer struct { corev1.Container Prepend bool - Mutators []containerMutator + Mutators containerMutators } var _ podMutator = (*initContainer)(nil) @@ -48,10 +68,9 @@ var _ podMutator = (*initContainer)(nil) // mutatePod implements podMutator for initContainer. func (i initContainer) mutatePod(pod *corev1.Pod) error { container := i.Container - for _, m := range i.Mutators { - if err := m.mutateContainer(&container); err != nil { - return err - } + + if err := i.Mutators.mutateContainer(&container); err != nil { + return err } for idx, c := range pod.Spec.InitContainers { diff --git a/pkg/clusteragent/admission/mutate/common/common.go b/pkg/clusteragent/admission/mutate/common/common.go index d198b502f09ec..0a08038db49fc 100644 --- a/pkg/clusteragent/admission/mutate/common/common.go +++ b/pkg/clusteragent/admission/mutate/common/common.go @@ -64,31 +64,51 @@ func contains(envs []corev1.EnvVar, name string) bool { return false } -// InjectEnv injects an env var into a pod template if it doesn't exist -func InjectEnv(pod *corev1.Pod, env corev1.EnvVar) bool { - injected := false - podStr := PodString(pod) - log.Debugf("Injecting env var '%s' into pod %s", env.Name, podStr) - for i, ctr := range pod.Spec.Containers { - if contains(ctr.Env, env.Name) { - log.Debugf("Ignoring container '%s' in pod %s: env var '%s' already exist", ctr.Name, podStr, env.Name) - continue - } - // prepend rather than append so that our new vars precede container vars in the final list, so that they - // can be referenced in other env vars downstream. (see: Kubernetes dependent environment variables.) - pod.Spec.Containers[i].Env = append([]corev1.EnvVar{env}, pod.Spec.Containers[i].Env...) - injected = true +// InjectEnv injects an env var into a pod template. +func InjectEnv(pod *corev1.Pod, env corev1.EnvVar) (injected bool) { + log.Debugf("Injecting env var '%s' into pod %s", env.Name, PodString(pod)) + + return InjectDynamicEnv(pod, func(_ *corev1.Container, _ bool) (corev1.EnvVar, error) { + return env, nil + }) +} + +// injectEnvInContainer injects an env var into a container if it doesn't exist. +func injectEnvInContainer(container *corev1.Container, env corev1.EnvVar) (injected bool) { + if contains(container.Env, env.Name) { + log.Debugf("Ignoring container '%s': env var '%s' already exist", container.Name, env.Name) + return } - for i, ctr := range pod.Spec.InitContainers { - if contains(ctr.Env, env.Name) { - log.Debugf("Ignoring init container '%s' in pod %s: env var '%s' already exist", ctr.Name, podStr, env.Name) + + // Prepend rather than append the new variables so that they precede the previous ones in the final list, + // allowing them to be referenced in other environment variables downstream. + // (See: https://kubernetes.io/docs/tasks/inject-data-application/define-interdependent-environment-variables) + container.Env = append([]corev1.EnvVar{env}, container.Env...) + return true +} + +// BuildEnvVarFunc is a function that builds a dynamic env var. +type BuildEnvVarFunc func(container *corev1.Container, init bool) (corev1.EnvVar, error) + +// InjectDynamicEnv injects a dynamic env var into a pod template. +func InjectDynamicEnv(pod *corev1.Pod, fn BuildEnvVarFunc) (injected bool) { + log.Debugf("Injecting env var into pod %s", PodString(pod)) + injected = injectDynamicEnvInContainers(pod.Spec.Containers, fn, false) + injected = injectDynamicEnvInContainers(pod.Spec.InitContainers, fn, true) || injected + return +} + +// injectDynamicEnvInContainers injects a dynamic env var into a list of containers. +func injectDynamicEnvInContainers(containers []corev1.Container, fn BuildEnvVarFunc, init bool) (injected bool) { + for i := range containers { + env, err := fn(&containers[i], init) + if err != nil { + _ = log.Errorf("Error building env var: %v", err) continue } - // prepend rather than append so that our new vars precede container vars in the final list, so that they - // can be referenced in other env vars downstream. (see: Kubernetes dependent environment variables.) - pod.Spec.InitContainers[i].Env = append([]corev1.EnvVar{env}, pod.Spec.InitContainers[i].Env...) - injected = true + injected = injectEnvInContainer(&containers[i], env) || injected } + return injected } diff --git a/pkg/clusteragent/admission/mutate/common/test_utils.go b/pkg/clusteragent/admission/mutate/common/test_utils.go index 7c01072d7fba9..94f9e579934d2 100644 --- a/pkg/clusteragent/admission/mutate/common/test_utils.go +++ b/pkg/clusteragent/admission/mutate/common/test_utils.go @@ -259,9 +259,8 @@ func FakeStoreWithDeployment(t *testing.T, deployments []MockDeployment) workloa mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), coreconfig.MockModule(), - fx.Supply(workloadmeta.NewParams()), fx.Supply(context.Background()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) for _, d := range deployments { diff --git a/pkg/clusteragent/admission/mutate/config/config.go b/pkg/clusteragent/admission/mutate/config/config.go index 1ff34841b63e3..4da8680f2a2ae 100644 --- a/pkg/clusteragent/admission/mutate/config/config.go +++ b/pkg/clusteragent/admission/mutate/config/config.go @@ -218,49 +218,31 @@ func injectionMode(pod *corev1.Pod, globalMode string) string { return globalMode } +// buildExternalEnv generate an External Data environment variable. +func buildExternalEnv(container *corev1.Container, init bool) (corev1.EnvVar, error) { + return corev1.EnvVar{ + Name: ddExternalDataEnvVarName, + Value: fmt.Sprintf("%s%t,%s%s,%s$(%s)", externalDataInitPrefix, init, externalDataContainerNamePrefix, container.Name, externalDataPodUIDPrefix, podUIDEnvVarName), + }, nil +} + // injectExternalDataEnvVar injects the External Data environment variable. // The format is: it-,cn-,pu- func injectExternalDataEnvVar(pod *corev1.Pod) (injected bool) { - type containerInjection struct { - container *corev1.Container - init bool - } - var containerInjections []containerInjection - - // Collect all containers and init containers - for i := range pod.Spec.Containers { - containerInjections = append(containerInjections, containerInjection{&pod.Spec.Containers[i], false}) - } - for i := range pod.Spec.InitContainers { - containerInjections = append(containerInjections, containerInjection{&pod.Spec.InitContainers[i], true}) - } - - // Inject External Data Environment Variable for each container - for _, containerInjection := range containerInjections { - if containerInjection.container == nil { - _ = log.Errorf("Cannot inject identity into nil container") - continue - } + // Inject External Data Environment Variable for the pod + injected = common.InjectDynamicEnv(pod, buildExternalEnv) - containerInjection.container.Env = append([]corev1.EnvVar{ - { - Name: podUIDEnvVarName, - ValueFrom: &corev1.EnvVarSource{ - FieldRef: &corev1.ObjectFieldSelector{ - FieldPath: "metadata.uid", - }, - }, - }, - { - Name: ddExternalDataEnvVarName, - Value: fmt.Sprintf("%s%t,%s%s,%s$(%s)", externalDataInitPrefix, containerInjection.init, externalDataContainerNamePrefix, containerInjection.container.Name, externalDataPodUIDPrefix, podUIDEnvVarName), + // Inject Internal Pod UID + injected = common.InjectEnv(pod, corev1.EnvVar{ + Name: podUIDEnvVarName, + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "metadata.uid", }, - }, containerInjection.container.Env...) - - injected = true - } + }, + }) || injected - return injected + return } func buildVolume(volumeName, path string, readOnly bool) (corev1.Volume, corev1.VolumeMount) { diff --git a/pkg/clusteragent/admission/mutate/config/config_test.go b/pkg/clusteragent/admission/mutate/config/config_test.go index 4fade296b0ca1..049d103cffab9 100644 --- a/pkg/clusteragent/admission/mutate/config/config_test.go +++ b/pkg/clusteragent/admission/mutate/config/config_test.go @@ -75,7 +75,7 @@ func Test_injectionMode(t *testing.T) { func TestInjectHostIP(t *testing.T) { pod := mutatecommon.FakePodWithContainer("foo-pod", corev1.Container{}) pod = mutatecommon.WithLabels(pod, map[string]string{"admission.datadoghq.com/enabled": "true"}) - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) webhook := NewWebhook(wmeta, autoinstrumentation.GetInjectionFilter()) injected, err := webhook.inject(pod, "", nil) assert.Nil(t, err) @@ -86,7 +86,7 @@ func TestInjectHostIP(t *testing.T) { func TestInjectService(t *testing.T) { pod := mutatecommon.FakePodWithContainer("foo-pod", corev1.Container{}) pod = mutatecommon.WithLabels(pod, map[string]string{"admission.datadoghq.com/enabled": "true", "admission.datadoghq.com/config.mode": "service"}) - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) webhook := NewWebhook(wmeta, autoinstrumentation.GetInjectionFilter()) injected, err := webhook.inject(pod, "", nil) assert.Nil(t, err) @@ -113,8 +113,7 @@ func TestInjectEntityID(t *testing.T) { wmeta := fxutil.Test[workloadmeta.Component]( t, core.MockBundle(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), fx.Replace(config.MockParams{Overrides: tt.configOverrides}), ) webhook := NewWebhook(wmeta, autoinstrumentation.GetInjectionFilter()) @@ -303,7 +302,7 @@ func TestInjectExternalDataEnvVar(t *testing.T) { func TestInjectSocket(t *testing.T) { pod := mutatecommon.FakePodWithContainer("foo-pod", corev1.Container{}) pod = mutatecommon.WithLabels(pod, map[string]string{"admission.datadoghq.com/enabled": "true", "admission.datadoghq.com/config.mode": "socket"}) - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) webhook := NewWebhook(wmeta, autoinstrumentation.GetInjectionFilter()) injected, err := webhook.inject(pod, "", nil) assert.Nil(t, err) @@ -358,7 +357,7 @@ func TestInjectSocketWithConflictingVolumeAndInitContainer(t *testing.T) { }, } - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) webhook := NewWebhook(wmeta, autoinstrumentation.GetInjectionFilter()) injected, err := webhook.inject(pod, "", nil) assert.True(t, injected) @@ -395,8 +394,7 @@ func TestJSONPatchCorrectness(t *testing.T) { assert.NoError(t, err) wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), fx.Replace(config.MockParams{Overrides: tt.overrides}), ) webhook := NewWebhook(wmeta, autoinstrumentation.GetInjectionFilter()) diff --git a/pkg/clusteragent/admission/mutate/cwsinstrumentation/cws_instrumentation_test.go b/pkg/clusteragent/admission/mutate/cwsinstrumentation/cws_instrumentation_test.go index 0c19817e49c3d..2d3d1fa578eef 100644 --- a/pkg/clusteragent/admission/mutate/cwsinstrumentation/cws_instrumentation_test.go +++ b/pkg/clusteragent/admission/mutate/cwsinstrumentation/cws_instrumentation_test.go @@ -17,7 +17,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.uber.org/fx" authenticationv1 "k8s.io/api/authentication/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -475,7 +474,7 @@ func Test_injectCWSCommandInstrumentation(t *testing.T) { } // prepare the workload meta - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -830,7 +829,7 @@ func Test_injectCWSPodInstrumentation(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // prepare the workload meta - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) mockConfig := configmock.New(t) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.include", tt.args.include) diff --git a/pkg/clusteragent/admission/mutate/tagsfromlabels/tags_test.go b/pkg/clusteragent/admission/mutate/tagsfromlabels/tags_test.go index 40b75c805e533..dbe96b72504bb 100644 --- a/pkg/clusteragent/admission/mutate/tagsfromlabels/tags_test.go +++ b/pkg/clusteragent/admission/mutate/tagsfromlabels/tags_test.go @@ -12,7 +12,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - "go.uber.org/fx" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -171,7 +170,7 @@ func Test_injectTags(t *testing.T) { }, }, } - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { webhook := NewWebhook(wmeta, autoinstrumentation.GetInjectionFilter()) @@ -273,7 +272,7 @@ func TestGetAndCacheOwner(t *testing.T) { ownerInfo := dummyInfo() kubeObj := newUnstructuredWithSpec(map[string]interface{}{"foo": "bar"}) owner := newOwner(kubeObj) - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) webhook := NewWebhook(wmeta, autoinstrumentation.GetInjectionFilter()) // Cache hit diff --git a/pkg/clusteragent/autoscaling/externalmetrics/autoscaler_watcher.go b/pkg/clusteragent/autoscaling/externalmetrics/autoscaler_watcher.go index 3eb7400489933..5fdfc3ab690ef 100644 --- a/pkg/clusteragent/autoscaling/externalmetrics/autoscaler_watcher.go +++ b/pkg/clusteragent/autoscaling/externalmetrics/autoscaler_watcher.go @@ -144,6 +144,7 @@ func (w *AutoscalerWatcher) Run(stopCh <-chan struct{}) { log.Infof("AutoscalerWatcher started (cache sync finished)") tickerRefreshProcess := time.NewTicker(time.Duration(w.refreshPeriod) * time.Second) + defer tickerRefreshProcess.Stop() for { select { case <-tickerRefreshProcess.C: diff --git a/pkg/clusteragent/autoscaling/externalmetrics/metrics_retriever.go b/pkg/clusteragent/autoscaling/externalmetrics/metrics_retriever.go index 39597675561aa..3729985d90f77 100644 --- a/pkg/clusteragent/autoscaling/externalmetrics/metrics_retriever.go +++ b/pkg/clusteragent/autoscaling/externalmetrics/metrics_retriever.go @@ -58,6 +58,7 @@ func NewMetricsRetriever(refreshPeriod, metricsMaxAge int64, processor autoscale func (mr *MetricsRetriever) Run(stopCh <-chan struct{}) { log.Infof("Starting MetricsRetriever") tickerRefreshProcess := time.NewTicker(time.Duration(mr.refreshPeriod) * time.Second) + defer tickerRefreshProcess.Stop() for { select { case <-tickerRefreshProcess.C: diff --git a/pkg/clusteragent/autoscaling/workload/pod_watcher_test.go b/pkg/clusteragent/autoscaling/workload/pod_watcher_test.go index 5139cb8b1ac9e..114ec19b476ae 100644 --- a/pkg/clusteragent/autoscaling/workload/pod_watcher_test.go +++ b/pkg/clusteragent/autoscaling/workload/pod_watcher_test.go @@ -95,8 +95,7 @@ func TestPodWatcherStartStop(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) pw := newPodWatcher(wlm, nil) ctx, cancel := context.WithCancel(context.Background()) diff --git a/pkg/clusteragent/clusterchecks/dispatcher_test.go b/pkg/clusteragent/clusterchecks/dispatcher_test.go index eb8a989c711b8..12ffdb069206d 100644 --- a/pkg/clusteragent/clusterchecks/dispatcher_test.go +++ b/pkg/clusteragent/clusterchecks/dispatcher_test.go @@ -18,6 +18,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/pkg/clusteragent/clusterchecks/types" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" configmock "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/util/kubernetes/clustername" "github.com/DataDog/datadog-agent/pkg/version" @@ -468,7 +469,7 @@ func TestReset(t *testing.T) { } func TestPatchConfiguration(t *testing.T) { - config.SetFeatures(t, config.Kubernetes) + config.SetFeatures(t, env.Kubernetes) checkConfig := integration.Config{ Name: "test", @@ -506,7 +507,7 @@ func TestPatchConfiguration(t *testing.T) { } func TestPatchEndpointsConfiguration(t *testing.T) { - config.SetFeatures(t, config.Kubernetes) + config.SetFeatures(t, env.Kubernetes) checkConfig := integration.Config{ Name: "test", @@ -539,7 +540,7 @@ func TestPatchEndpointsConfiguration(t *testing.T) { } func TestExtraTags(t *testing.T) { - config.SetFeatures(t, config.Kubernetes) + config.SetFeatures(t, env.Kubernetes) for _, tc := range []struct { extraTagsConfig []string diff --git a/pkg/clusteragent/languagedetection/patcher_test.go b/pkg/clusteragent/languagedetection/patcher_test.go index b4f3feeacd396..de65deb6da7f5 100644 --- a/pkg/clusteragent/languagedetection/patcher_test.go +++ b/pkg/clusteragent/languagedetection/patcher_test.go @@ -64,8 +64,7 @@ func TestRun(t *testing.T) { mockK8sClient := dynamicfake.NewSimpleDynamicClient(runtime.NewScheme()) mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) mocklogger := logmock.New(t) @@ -299,8 +298,7 @@ func TestPatcherRetriesFailedPatches(t *testing.T) { mockK8sClient := dynamicfake.NewSimpleDynamicClient(runtime.NewScheme()) mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) mocklogger := logmock.New(t) diff --git a/pkg/collector/corechecks/cluster/kubernetesapiserver/unbundled_events_test.go b/pkg/collector/corechecks/cluster/kubernetesapiserver/unbundled_events_test.go index 8cafd44921e67..0c1e03893b675 100644 --- a/pkg/collector/corechecks/cluster/kubernetesapiserver/unbundled_events_test.go +++ b/pkg/collector/corechecks/cluster/kubernetesapiserver/unbundled_events_test.go @@ -535,9 +535,9 @@ func TestUnbundledEventsTransform(t *testing.T) { events, errors := transformer.Transform(incomingEvents) - // Sort events by title for easier comparison - sort.Slice(events, func(i, j int) bool { - return events[i].Title < events[j].Title + // Sort events by title and description for easier comparison + sort.SliceStable(events, func(i, j int) bool { + return events[i].Title+events[i].Text < events[j].Title+events[j].Text }) assert.Empty(t, errors) diff --git a/pkg/collector/corechecks/containerimage/check.go b/pkg/collector/corechecks/containerimage/check.go index 26da8511de1c7..bf953b83a8d2c 100644 --- a/pkg/collector/corechecks/containerimage/check.go +++ b/pkg/collector/corechecks/containerimage/check.go @@ -145,7 +145,7 @@ func (c *Check) Run() error { ) imgRefreshTicker := time.NewTicker(time.Duration(c.instance.PeriodicRefreshSeconds) * time.Second) - + defer imgRefreshTicker.Stop() defer c.processor.stop() for { select { diff --git a/pkg/collector/corechecks/containerlifecycle/check.go b/pkg/collector/corechecks/containerlifecycle/check.go index 428a1810dd8f5..05347475beb57 100644 --- a/pkg/collector/corechecks/containerlifecycle/check.go +++ b/pkg/collector/corechecks/containerlifecycle/check.go @@ -19,6 +19,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/collector/check" core "github.com/DataDog/datadog-agent/pkg/collector/corechecks" ddConfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/DataDog/datadog-agent/pkg/util/optional" ) @@ -186,7 +187,7 @@ func Factory(store workloadmeta.Component) optional.Option[func() check.Check] { // sendFargateTaskEvent sends Fargate task lifecycle event at the end of the check func (c *Check) sendFargateTaskEvent() { if !ddConfig.Datadog().GetBool("ecs_task_collection_enabled") || - !ddConfig.IsECSFargate() { + !env.IsECSFargate() { return } diff --git a/pkg/collector/corechecks/containerlifecycle/processor.go b/pkg/collector/corechecks/containerlifecycle/processor.go index f3eebfa521ffc..2f514329c091c 100644 --- a/pkg/collector/corechecks/containerlifecycle/processor.go +++ b/pkg/collector/corechecks/containerlifecycle/processor.go @@ -170,7 +170,7 @@ func (p *processor) processTask(task *workloadmeta.ECSTask) error { // processQueues consumes the data available in the queues func (p *processor) processQueues(ctx context.Context, pollInterval time.Duration) { ticker := time.NewTicker(pollInterval) - + defer ticker.Stop() for { select { case <-ticker.C: diff --git a/pkg/collector/corechecks/containers/docker/check_network.go b/pkg/collector/corechecks/containers/docker/check_network.go index 7c06c572126ff..e8dbc5133f49f 100644 --- a/pkg/collector/corechecks/containers/docker/check_network.go +++ b/pkg/collector/corechecks/containers/docker/check_network.go @@ -21,6 +21,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/aggregator/sender" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/containers/generic" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/containers/metrics" "github.com/DataDog/datadog-agent/pkg/util/docker" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -36,7 +37,7 @@ const ( func (d *DockerCheck) configureNetworkProcessor(processor *generic.Processor) { switch runtime.GOOS { case "linux": - if config.IsHostProcAvailable() { + if env.IsHostProcAvailable() { d.networkProcessorExtension = &dockerNetworkExtension{procPath: config.Datadog().GetString("container_proc_root")} } case "windows": diff --git a/pkg/collector/corechecks/containers/docker/check_test.go b/pkg/collector/corechecks/containers/docker/check_test.go index 4a74746b363e7..7f2c461a81137 100644 --- a/pkg/collector/corechecks/containers/docker/check_test.go +++ b/pkg/collector/corechecks/containers/docker/check_test.go @@ -14,7 +14,6 @@ import ( dockerTypes "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/image" "github.com/stretchr/testify/assert" - "go.uber.org/fx" "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/core/tagger/taggerimpl" @@ -211,7 +210,7 @@ func TestDockerCustomPart(t *testing.T) { Enabled: true, NameExcludeList: []*regexp.Regexp{regexp.MustCompile("agent-excluded")}, }, - store: fxutil.Test[workloadmetamock.Mock](t, core.MockBundle(), fx.Supply(workloadmeta.NewParams()), workloadmetafxmock.MockModule()), + store: fxutil.Test[workloadmetamock.Mock](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())), } err := check.runDockerCustom(mockSender, &dockerClient, dockerClient.FakeContainerList) @@ -290,7 +289,7 @@ func TestContainersRunning(t *testing.T) { instance: &DockerConfig{}, dockerHostname: "testhostname", containerFilter: &containers.Filter{}, - store: fxutil.Test[workloadmetamock.Mock](t, core.MockBundle(), fx.Supply(workloadmeta.NewParams()), workloadmetafxmock.MockModule()), + store: fxutil.Test[workloadmetamock.Mock](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())), } err := check.runDockerCustom(mockSender, &dockerClient, dockerClient.FakeContainerList) diff --git a/pkg/collector/corechecks/containers/kubelet/common/testing/utils.go b/pkg/collector/corechecks/containers/kubelet/common/testing/utils.go index e62a694ea6ac2..5054431177d18 100644 --- a/pkg/collector/corechecks/containers/kubelet/common/testing/utils.go +++ b/pkg/collector/corechecks/containers/kubelet/common/testing/utils.go @@ -147,7 +147,7 @@ func CreateKubeletMock(response EndpointResponse, endpoint string) (*mock.Kubele if response.filename != "" { content, err = os.ReadFile(response.filename) if err != nil { - return nil, fmt.Errorf(fmt.Sprintf("unable to read test file at: %s, Err: %v", response.filename, err)) + return nil, fmt.Errorf("unable to read test file at: %s, Err: %w", response.filename, err) } } kubeletMock.MockReplies[endpoint] = &mock.HTTPReplyMock{ @@ -166,12 +166,12 @@ func StorePopulatedFromFile(store workloadmetamock.Mock, filename string, podUti podList, err := os.ReadFile(filename) if err != nil { - return fmt.Errorf(fmt.Sprintf("unable to load pod list, Err: %v", err)) + return fmt.Errorf("unable to load pod list, Err: %w", err) } var pods *kubelet.PodList err = json.Unmarshal(podList, &pods) if err != nil { - return fmt.Errorf(fmt.Sprintf("unable to load pod list, Err: %v", err)) + return fmt.Errorf("unable to load pod list, Err: %w", err) } for _, pod := range pods.Items { diff --git a/pkg/collector/corechecks/containers/kubelet/provider/cadvisor/provider.go b/pkg/collector/corechecks/containers/kubelet/provider/cadvisor/provider.go index 6ada97910f928..2784dbc068f4a 100644 --- a/pkg/collector/corechecks/containers/kubelet/provider/cadvisor/provider.go +++ b/pkg/collector/corechecks/containers/kubelet/provider/cadvisor/provider.go @@ -143,7 +143,7 @@ func (p *Provider) processContainerMetric(metricType, metricName string, metricF return } - samples := p.sumValuesByContext(metricFam, p.getEntityIDIfContainerMetric) + samples := p.latestValueByContext(metricFam, p.getEntityIDIfContainerMetric) for containerID, sample := range samples { var tags []string diff --git a/pkg/collector/corechecks/containers/kubelet/provider/cadvisor/provider_test.go b/pkg/collector/corechecks/containers/kubelet/provider/cadvisor/provider_test.go index 0c70dcf3706c0..d49c6a29b0801 100644 --- a/pkg/collector/corechecks/containers/kubelet/provider/cadvisor/provider_test.go +++ b/pkg/collector/corechecks/containers/kubelet/provider/cadvisor/provider_test.go @@ -97,8 +97,7 @@ func (suite *ProviderTestSuite) SetupTest() { store := fxutil.Test[workloadmetamock.Mock](suite.T(), fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) mockSender := mocksender.NewMockSender(checkid.ID(suite.T().Name())) diff --git a/pkg/collector/corechecks/containers/kubelet/provider/kubelet/provider_test.go b/pkg/collector/corechecks/containers/kubelet/provider/kubelet/provider_test.go index e4b24b03e5a6f..dc00b58d4eaf7 100644 --- a/pkg/collector/corechecks/containers/kubelet/provider/kubelet/provider_test.go +++ b/pkg/collector/corechecks/containers/kubelet/provider/kubelet/provider_test.go @@ -128,8 +128,7 @@ func (suite *ProviderTestSuite) SetupTest() { store := fxutil.Test[workloadmetamock.Mock](suite.T(), fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) mockSender := mocksender.NewMockSender(checkid.ID(suite.T().Name())) diff --git a/pkg/collector/corechecks/containers/kubelet/provider/probe/provider_test.go b/pkg/collector/corechecks/containers/kubelet/provider/probe/provider_test.go index 2a771ed774a22..ac9d134faf7db 100644 --- a/pkg/collector/corechecks/containers/kubelet/provider/probe/provider_test.go +++ b/pkg/collector/corechecks/containers/kubelet/provider/probe/provider_test.go @@ -263,8 +263,7 @@ func TestProvider_Provide(t *testing.T) { store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) mockSender := mocksender.NewMockSender(checkid.ID(t.Name())) diff --git a/pkg/collector/corechecks/containers/kubelet/provider/slis/provider_test.go b/pkg/collector/corechecks/containers/kubelet/provider/slis/provider_test.go index 4cd21b9143a0f..47e1d6e11cb9c 100644 --- a/pkg/collector/corechecks/containers/kubelet/provider/slis/provider_test.go +++ b/pkg/collector/corechecks/containers/kubelet/provider/slis/provider_test.go @@ -164,8 +164,7 @@ func TestProvider_Provide(t *testing.T) { store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) mockSender := mocksender.NewMockSender(checkid.ID(t.Name())) @@ -231,8 +230,7 @@ func TestProvider_DisableProvider(t *testing.T) { store := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) mockSender := mocksender.NewMockSender(checkid.ID(t.Name())) diff --git a/pkg/collector/corechecks/containers/kubelet/provider/summary/provider_test.go b/pkg/collector/corechecks/containers/kubelet/provider/summary/provider_test.go index 62d3df1c6f3be..19ef1a9a51c07 100644 --- a/pkg/collector/corechecks/containers/kubelet/provider/summary/provider_test.go +++ b/pkg/collector/corechecks/containers/kubelet/provider/summary/provider_test.go @@ -386,8 +386,7 @@ func creatFakeStore(t *testing.T) workloadmetamock.Mock { fx.Provide(func() log.Component { return logmock.New(t) }), configcomp.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) podEntityID := workloadmeta.EntityID{ diff --git a/pkg/collector/corechecks/loader.go b/pkg/collector/corechecks/loader.go index eb09c0cefb49c..31eab283f1fe5 100644 --- a/pkg/collector/corechecks/loader.go +++ b/pkg/collector/corechecks/loader.go @@ -61,7 +61,7 @@ func (gl *GoCheckLoader) Load(senderManger sender.SenderManager, config integrat factory, found := catalog[config.Name] if !found { msg := fmt.Sprintf("Check %s not found in Catalog", config.Name) - return c, fmt.Errorf(msg) + return c, errors.New(msg) } c = factory() @@ -71,7 +71,7 @@ func (gl *GoCheckLoader) Load(senderManger sender.SenderManager, config integrat } log.Errorf("core.loader: could not configure check %s: %s", c, err) msg := fmt.Sprintf("Could not configure check %s: %s", c, err) - return c, fmt.Errorf(msg) + return c, errors.New(msg) } return c, nil diff --git a/pkg/collector/corechecks/network-devices/cisco-sdwan/payload/devices.go b/pkg/collector/corechecks/network-devices/cisco-sdwan/payload/devices.go index 9de0a4c9633de..43ba294592dd4 100644 --- a/pkg/collector/corechecks/network-devices/cisco-sdwan/payload/devices.go +++ b/pkg/collector/corechecks/network-devices/cisco-sdwan/payload/devices.go @@ -18,6 +18,9 @@ import ( // TimeNow useful for mocking var TimeNow = time.Now +// DeviceUserTagResourcePrefix contains the REDAPL table to store device user tags +const DeviceUserTagResourcePrefix = "dd.internal.resource:ndm_device_user_tags" + // GetDevicesMetadata process devices API payloads to build metadata func GetDevicesMetadata(namespace string, devices []client.Device) []devicemetadata.DeviceMetadata { var devicesMetadata []devicemetadata.DeviceMetadata @@ -32,6 +35,7 @@ func GetDevicesTags(namespace string, devices []client.Device) map[string][]stri deviceTags := make(map[string][]string) for _, device := range devices { deviceTags[device.SystemIP] = buildDeviceTags(namespace, device) + deviceTags[device.SystemIP] = append(deviceTags[device.SystemIP], fmt.Sprintf("%s:%s", DeviceUserTagResourcePrefix, buildDeviceID(namespace, device))) } return deviceTags } diff --git a/pkg/collector/corechecks/network-devices/cisco-sdwan/payload/devices_test.go b/pkg/collector/corechecks/network-devices/cisco-sdwan/payload/devices_test.go index 70c96a8dc2372..ceb4310f084d6 100644 --- a/pkg/collector/corechecks/network-devices/cisco-sdwan/payload/devices_test.go +++ b/pkg/collector/corechecks/network-devices/cisco-sdwan/payload/devices_test.go @@ -107,6 +107,7 @@ func TestProcessDevicesTags(t *testing.T) { "device_ip:10.0.0.1", "device_hostname:test-1", "device_id:test-ns:10.0.0.1", + "dd.internal.resource:ndm_device_user_tags:test-ns:10.0.0.1", }, "10.0.0.2": { "device_vendor:cisco", @@ -118,6 +119,7 @@ func TestProcessDevicesTags(t *testing.T) { "device_ip:10.0.0.2", "device_hostname:test-2", "device_id:test-ns:10.0.0.2", + "dd.internal.resource:ndm_device_user_tags:test-ns:10.0.0.2", }, }, tags) } diff --git a/pkg/collector/corechecks/network-devices/cisco-sdwan/report/metrics.go b/pkg/collector/corechecks/network-devices/cisco-sdwan/report/metrics.go index bad69fb5bc7e3..360d0586aa28f 100644 --- a/pkg/collector/corechecks/network-devices/cisco-sdwan/report/metrics.go +++ b/pkg/collector/corechecks/network-devices/cisco-sdwan/report/metrics.go @@ -21,6 +21,8 @@ import ( const ciscoSDWANMetricPrefix = "cisco_sdwan." const timestampExpiration = 6 * time.Hour +const interfaceUserTagResourcePrefix = "dd.internal.resource:ndm_interface_user_tags" + // SDWanSender implements methods for sending Cisco SD-Wan metrics and metadata type SDWanSender struct { sender sender.Sender @@ -74,12 +76,14 @@ func (ms *SDWanSender) SendInterfaceMetrics(interfaceStats []client.InterfaceSta for _, entry := range interfaceStats { deviceTags := ms.getDeviceTags(entry.VmanageSystemIP) + + itfID := fmt.Sprintf("%s:%s", entry.VmanageSystemIP, entry.Interface) + interfaceTags := []string{ "interface:" + entry.Interface, fmt.Sprintf("vpn_id:%d", int(entry.VpnID)), } - itfID := fmt.Sprintf("%s:%s", entry.VmanageSystemIP, entry.Interface) itf, foundInterface := interfacesMap[itfID] tags := append(deviceTags, interfaceTags...) @@ -88,6 +92,7 @@ func (ms *SDWanSender) SendInterfaceMetrics(interfaceStats []client.InterfaceSta index, err := itf.Index() if err == nil { tags = append(tags, fmt.Sprintf("interface_index:%d", index)) + tags = append(tags, fmt.Sprintf("%s:%s:%s:%d", interfaceUserTagResourcePrefix, ms.namespace, entry.VmanageSystemIP, index)) } statusTags := append(tags, "oper_status:"+itf.OperStatus().AsString(), "admin_status:"+itf.AdminStatus().AsString()) @@ -372,8 +377,8 @@ func (ms *SDWanSender) getPrefixedDeviceTags(prefix string, systemIP string) []s var remoteTags []string for _, tag := range tags { - if strings.HasPrefix(tag, "device_namespace") { - // No need to tag remote devices by namespace + if strings.HasPrefix(tag, "device_namespace") || strings.HasPrefix(tag, payload.DeviceUserTagResourcePrefix) || strings.HasPrefix(tag, interfaceUserTagResourcePrefix) { + // No need to tag remote devices by namespace or user tags continue } remoteTags = append(remoteTags, prefix+tag) diff --git a/pkg/collector/corechecks/network-devices/cisco-sdwan/report/metrics_test.go b/pkg/collector/corechecks/network-devices/cisco-sdwan/report/metrics_test.go index b4357af002246..2f7e4dc75c3a0 100644 --- a/pkg/collector/corechecks/network-devices/cisco-sdwan/report/metrics_test.go +++ b/pkg/collector/corechecks/network-devices/cisco-sdwan/report/metrics_test.go @@ -167,7 +167,7 @@ func TestSendInterfaceMetrics(t *testing.T) { mockSender.AssertMetricWithTimestamp(t, "CountWithTimestamp", ciscoSDWANMetricPrefix+"interface.rx_drops", 65, "", expectedTags, 10) mockSender.AssertMetricWithTimestamp(t, "CountWithTimestamp", ciscoSDWANMetricPrefix+"interface.tx_drops", 2, "", expectedTags, 10) require.Equal(t, map[string]float64{ - "interface_metrics:test:tag,test2:tag2,interface:interface-1,vpn_id:10,interface_index:10": 10000, + "interface_metrics:test:tag,test2:tag2,interface:interface-1,vpn_id:10,interface_index:10,dd.internal.resource:ndm_interface_user_tags:my-ns:10.0.0.1:10": 10000, }, sender.lastTimeSent) mockSender.ResetCalls() @@ -178,7 +178,7 @@ func TestSendInterfaceMetrics(t *testing.T) { mockSender.AssertNumberOfCalls(t, "GaugeWithTimestamp", 0) mockSender.AssertNumberOfCalls(t, "CountWithTimestamp", 0) require.Equal(t, map[string]float64{ - "interface_metrics:test:tag,test2:tag2,interface:interface-1,vpn_id:10,interface_index:10": 10000, + "interface_metrics:test:tag,test2:tag2,interface:interface-1,vpn_id:10,interface_index:10,dd.internal.resource:ndm_interface_user_tags:my-ns:10.0.0.1:10": 10000, }, sender.lastTimeSent) } diff --git a/pkg/collector/corechecks/networkpath/networkpath.go b/pkg/collector/corechecks/networkpath/networkpath.go index 5c850c763bc1b..b1e9b735e1eab 100644 --- a/pkg/collector/corechecks/networkpath/networkpath.go +++ b/pkg/collector/corechecks/networkpath/networkpath.go @@ -105,7 +105,7 @@ func (c *Check) submitTelemetry(metricSender metricsender.MetricSender, path pay c.lastCheckTime = startTime checkDuration := time.Since(startTime) - telemetry.SubmitNetworkPathTelemetry(metricSender, path, telemetry.CollectorTypeNetworkPathIntegration, checkDuration, checkInterval, metricTags) + telemetry.SubmitNetworkPathTelemetry(metricSender, path, checkDuration, checkInterval, metricTags) } // Interval returns the scheduling time for the check diff --git a/pkg/collector/corechecks/oracle/activity.go b/pkg/collector/corechecks/oracle/activity.go index b4540afd71333..9b3ce2fa3c134 100644 --- a/pkg/collector/corechecks/oracle/activity.go +++ b/pkg/collector/corechecks/oracle/activity.go @@ -95,6 +95,7 @@ type OracleActivityRow struct { //nolint:revive // TODO(DBM) Fix revive linter type OracleActivityRowDB struct { Now string `db:"NOW"` + UtcMs float64 `db:"UTC_MS"` SessionID uint64 `db:"SID"` SessionSerial uint64 `db:"SERIAL#"` User sql.NullString `db:"USERNAME"` @@ -161,8 +162,64 @@ func (c *Check) getSQLRow(SQLID sql.NullString, forceMatchingSignature *string, return SQLRow, nil } +func sendPayload(c *Check, sessionRows []OracleActivityRow, timestamp float64) error { + var collectionInterval float64 + if c.config.QuerySamples.ActiveSessionHistory { + collectionInterval = 1 + } else { + collectionInterval = float64(c.config.MinCollectionInterval) + } + var ts float64 + if timestamp > 0 { + ts = timestamp + } else { + ts = float64(c.clock.Now().UnixMilli()) + } + log.Debugf("%s STIMESTAMP FETCHED %f", c.logPrompt, timestamp) + log.Debugf("%s STIMESTAMP UNIX %f", c.logPrompt, float64(c.clock.Now().UnixMilli())) + payload := ActivitySnapshot{ + Metadata: Metadata{ + //Timestamp: float64(c.clock.Now().UnixMilli()), + Timestamp: ts, + Host: c.dbHostname, + Source: common.IntegrationName, + DBMType: "activity", + DDAgentVersion: c.agentVersion, + }, + CollectionInterval: collectionInterval, + Tags: c.tags, + OracleActivityRows: sessionRows, + } + + c.lastOracleActivityRows = make([]OracleActivityRow, len(sessionRows)) + copy(c.lastOracleActivityRows, sessionRows) + + payloadBytes, err := json.Marshal(payload) + if err != nil { + log.Errorf("%s Error marshalling activity payload: %s", c.logPrompt, err) + return err + } + + log.Debugf("%s Activity payload %s", c.logPrompt, strings.ReplaceAll(string(payloadBytes), "@", "XX")) + + sender, err := c.GetSender() + if err != nil { + log.Errorf("%s GetSender SampleSession %s", c.logPrompt, string(payloadBytes)) + return err + } + sender.EventPlatformEvent(payloadBytes, "dbm-activity") + sendMetric(c, count, "dd.oracle.activity.samples_count", float64(len(sessionRows)), append(c.tags, fmt.Sprintf("sql_substring_length:%d", c.sqlSubstringLength))) + + return nil +} + //nolint:revive // TODO(DBM) Fix revive linter func (c *Check) SampleSession() error { + activeSessionHistory := c.config.QuerySamples.ActiveSessionHistory + if activeSessionHistory && c.lastSampleId == 0 { + err := getWrapper(c, &c.lastSampleId, "SELECT /* DD */ MAX(sample_id) FROM v$active_session_history") + return err + } start := time.Now() copy(c.lastOracleActivityRows, []OracleActivityRow{}) @@ -170,7 +227,10 @@ func (c *Check) SampleSession() error { sessionSamples := []OracleActivityRowDB{} var activityQuery string maxSQLTextLength := c.sqlSubstringLength - if c.hostingType == selfManaged && !c.config.QuerySamples.ForceDirectQuery { + + if activeSessionHistory { + activityQuery = activityQueryActiveSessionHistory + } else if c.hostingType == selfManaged && !c.config.QuerySamples.ForceDirectQuery { if isDbVersionGreaterOrEqualThan(c, minMultitenantVersion) { activityQuery = activityQueryOnView12 } else { @@ -180,7 +240,7 @@ func (c *Check) SampleSession() error { activityQuery = activityQueryDirect } - if !c.config.QuerySamples.IncludeAllSessions { + if !c.config.QuerySamples.IncludeAllSessions && !activeSessionHistory { activityQuery = fmt.Sprintf("%s %s", activityQuery, ` AND ( NOT (state = 'WAITING' AND wait_class = 'Idle') OR state = 'WAITING' AND event = 'fbar timer' AND type = 'USER' @@ -188,7 +248,12 @@ func (c *Check) SampleSession() error { AND status = 'ACTIVE'`) } - err := selectWrapper(c, &sessionSamples, activityQuery, maxSQLTextLength, maxSQLTextLength) + var err error + if activeSessionHistory { + err = selectWrapper(c, &sessionSamples, activityQuery, maxSQLTextLength, c.lastSampleId) + } else { + err = selectWrapper(c, &sessionSamples, activityQuery, maxSQLTextLength, maxSQLTextLength) + } if err != nil { if strings.Contains(err.Error(), "ORA-06502") { @@ -203,10 +268,21 @@ AND status = 'ACTIVE'`) o := obfuscate.NewObfuscator(obfuscate.Config{SQL: c.config.ObfuscatorOptions}) defer o.Stop() + var payloadSent bool + var lastNow string for _, sample := range sessionSamples { var sessionRow OracleActivityRow sessionRow.Now = sample.Now + if lastNow != sessionRow.Now && lastNow != "" { + err = sendPayload(c, sessionRows, sample.UtcMs) + if err != nil { + log.Errorf("%s error sending payload %s", c.logPrompt, err) + } + payloadSent = true + } + lastNow = sessionRow.Now + sessionRow.SessionID = sample.SessionID sessionRow.SessionSerial = sample.SessionSerial if sample.User.Valid { @@ -381,38 +457,17 @@ AND status = 'ACTIVE'`) sessionRow.CdbName = c.cdbName sessionRows = append(sessionRows, sessionRow) } - - payload := ActivitySnapshot{ - Metadata: Metadata{ - Timestamp: float64(c.clock.Now().UnixMilli()), - Host: c.dbHostname, - Source: common.IntegrationName, - DBMType: "activity", - DDAgentVersion: c.agentVersion, - }, - CollectionInterval: c.checkInterval, - Tags: c.tags, - OracleActivityRows: sessionRows, - } - - c.lastOracleActivityRows = make([]OracleActivityRow, len(sessionRows)) - copy(c.lastOracleActivityRows, sessionRows) - - payloadBytes, err := json.Marshal(payload) - if err != nil { - log.Errorf("%s Error marshalling activity payload: %s", c.logPrompt, err) - return err + if !payloadSent { + err = sendPayload(c, sessionRows, 0) + if err != nil { + log.Errorf("%s error sending payload %s", c.logPrompt, err) + } } - - log.Debugf("%s Activity payload %s", c.logPrompt, strings.ReplaceAll(string(payloadBytes), "@", "XX")) - sender, err := c.GetSender() if err != nil { - log.Errorf("%s GetSender SampleSession %s", c.logPrompt, string(payloadBytes)) + log.Errorf("%s GetSender SampleSession", c.logPrompt) return err } - sender.EventPlatformEvent(payloadBytes, "dbm-activity") - sendMetric(c, count, "dd.oracle.activity.samples_count", float64(len(sessionRows)), append(c.tags, fmt.Sprintf("sql_substring_length:%d", c.sqlSubstringLength))) sendMetricWithDefaultTags(c, gauge, "dd.oracle.activity.time_ms", float64(time.Since(start).Milliseconds())) sender.Commit() diff --git a/pkg/collector/corechecks/oracle/activity_queries.go b/pkg/collector/corechecks/oracle/activity_queries.go index dd7062c1774b8..6c4c4694089bd 100644 --- a/pkg/collector/corechecks/oracle/activity_queries.go +++ b/pkg/collector/corechecks/oracle/activity_queries.go @@ -216,3 +216,62 @@ AND sq_prev.child_number(+) = s.prev_child_number AND ( sq.sql_text NOT LIKE '%DD_ACTIVITY_SAMPLING%' OR sq.sql_text is NULL ) AND s.con_id = c.con_id(+) AND s.command = comm.command_type(+)` + +const activityQueryActiveSessionHistory = `SELECT /*+ push_pred(sq) */ /* DD_ACTIVITY_SAMPLING */ + cast (sample_time as date) now, + (CAST(sample_time_utc AS DATE) - TO_DATE('1970-01-01', 'YYYY-MM-DD')) * 86400000 as utc_ms, + s.session_id sid, + s.session_serial# serial#, + sess.username, + 'ACTIVE' status, + sess.osuser, + sess.process, + s.machine, + s.port, + s.program, + s.session_type type, + s.sql_id, + sq.force_matching_signature as force_matching_signature, + sq.plan_hash_value sql_plan_hash_value, + s.sql_exec_start, + s.module, + s.action, + sess.logon_time, + s.client_id client_identifier, + CASE WHEN s.blocking_session_status = 'VALID' THEN + s.blocking_inst_id + ELSE + null + END blocking_instance, + CASE WHEN s.blocking_session_status = 'VALID' THEN + s.blocking_session + ELSE + null + END blocking_session, + CASE WHEN session_state = 'WAITING' THEN + s.event + ELSE + 'CPU' + END event, + CASE WHEN session_state = 'WAITING' THEN + s.wait_class + ELSE + 'CPU' + END wait_class, + s.wait_time * 10000 wait_time_micro, + c.name as pdb_name, + dbms_lob.substr(sq.sql_fulltext, :sql_substr_length, 1) sql_fulltext, + s.sql_opname command_name +FROM + v$active_session_history s, + v$session sess, + v$sql sq, + v$containers c +WHERE + sq.sql_id(+) = s.sql_id + AND sq.child_number(+) = s.sql_child_number + AND ( sq.sql_text NOT LIKE '%DD_ACTIVITY_SAMPLING%' OR sq.sql_text is NULL ) + AND s.con_id = c.con_id(+) + AND sess.sid(+) = s.session_id AND sess.serial#(+) = s.session_serial# + AND s.sample_id > :last_sample_id +ORDER BY s.sample_time` diff --git a/pkg/collector/corechecks/oracle/compose/README.md b/pkg/collector/corechecks/oracle/compose/README.md new file mode 100644 index 0000000000000..4320820f75a39 --- /dev/null +++ b/pkg/collector/corechecks/oracle/compose/README.md @@ -0,0 +1 @@ +Docker compose files for integration testing diff --git a/pkg/collector/corechecks/oracle/compose/docker-compose.yml b/pkg/collector/corechecks/oracle/compose/docker-compose.yml new file mode 100644 index 0000000000000..1d68e46cdece2 --- /dev/null +++ b/pkg/collector/corechecks/oracle/compose/docker-compose.yml @@ -0,0 +1,16 @@ +services: + oracle: + platform: linux/amd64 + image: "registry.ddbuild.io/images/mirror/oracle:${DBMS_VERSION:-21.3.0-xe}" + ports: + - "1521:1521" + healthcheck: + test: "echo 'select 123456789;' | sqlplus -s sys/datad0g@localhost as sysdba | grep 123456789" + interval: 5s + start_period: 15s + timeout: 5s + retries: 48 + # We could just mount init.db but we mimic Gitlab's limitations + # and rely on TestMain to run the relevant sql + environment: + ORACLE_PWD: datad0g diff --git a/pkg/collector/corechecks/oracle/compose/initdb.d/00-create-user.sql b/pkg/collector/corechecks/oracle/compose/initdb.d/00-create-user.sql new file mode 100644 index 0000000000000..17eef001e4cea --- /dev/null +++ b/pkg/collector/corechecks/oracle/compose/initdb.d/00-create-user.sql @@ -0,0 +1,2 @@ +CREATE USER c##datadog IDENTIFIED BY datadog CONTAINER=ALL; +ALTER USER c##datadog SET CONTAINER_DATA=ALL CONTAINER=CURRENT; \ No newline at end of file diff --git a/pkg/collector/corechecks/oracle/compose/initdb.d/01-create-function.nosplit.sql b/pkg/collector/corechecks/oracle/compose/initdb.d/01-create-function.nosplit.sql new file mode 100644 index 0000000000000..9f7cf23de294b --- /dev/null +++ b/pkg/collector/corechecks/oracle/compose/initdb.d/01-create-function.nosplit.sql @@ -0,0 +1,85 @@ +CREATE OR REPLACE VIEW dd_session AS +SELECT /*+ push_pred(sq) push_pred(sq_prev) */ + s.indx as sid, + s.ksuseser as serial#, + s.ksuudlna as username, + DECODE(BITAND(s.ksuseidl, 9), 1, 'ACTIVE', 0, DECODE(BITAND(s.ksuseflg, 4096), 0, 'INACTIVE', 'CACHED'), 'KILLED') as status, + s.ksuseunm as osuser, + s.ksusepid as process, + s.ksusemnm as machine, + s.ksusemnp as port, + s.ksusepnm as program, + DECODE(BITAND(s.ksuseflg, 19), 17, 'BACKGROUND', 1, 'USER', 2, 'RECURSIVE', '?') as type, + s.ksusesqi as sql_id, + sq.force_matching_signature as force_matching_signature, + s.ksusesph as sql_plan_hash_value, + s.ksusesesta as sql_exec_start, + s.ksusesql as sql_address, + CASE WHEN BITAND(s.ksusstmbv, POWER(2, 04)) = POWER(2, 04) THEN 'Y' ELSE 'N' END as in_parse, + CASE WHEN BITAND(s.ksusstmbv, POWER(2, 07)) = POWER(2, 07) THEN 'Y' ELSE 'N' END as in_hard_parse, + s.ksusepsi as prev_sql_id, + s.ksusepha as prev_sql_plan_hash_value, + s.ksusepesta as prev_sql_exec_start, + sq_prev.force_matching_signature as prev_force_matching_signature, + s.ksusepsq as prev_sql_address, + s.ksuseapp as module, + s.ksuseact as action, + s.ksusecli as client_info, + s.ksuseltm as logon_time, + s.ksuseclid as client_identifier, + s.ksusstmbv as op_flags, + decode(s.ksuseblocker, + 4294967295, 'UNKNOWN', 4294967294, 'UNKNOWN', 4294967293, 'UNKNOWN', 4294967292, 'NO HOLDER', 4294967291, 'NOT IN WAIT', + 'VALID' + ) as blocking_session_status, + DECODE(s.ksuseblocker, + 4294967295, TO_NUMBER(NULL), 4294967294, TO_NUMBER(NULL), 4294967293, TO_NUMBER(NULL), + 4294967292, TO_NUMBER(NULL), 4294967291, TO_NUMBER(NULL), BITAND(s.ksuseblocker, 2147418112) / 65536 + ) as blocking_instance, + DECODE(s.ksuseblocker, + 4294967295, TO_NUMBER(NULL), 4294967294, TO_NUMBER(NULL), 4294967293, TO_NUMBER(NULL), + 4294967292, TO_NUMBER(NULL), 4294967291, TO_NUMBER(NULL), BITAND(s.ksuseblocker, 65535) + ) as blocking_session, + DECODE(s.ksusefblocker, + 4294967295, 'UNKNOWN', 4294967294, 'UNKNOWN', 4294967293, 'UNKNOWN', 4294967292, 'NO HOLDER', 4294967291, 'NOT IN WAIT', 'VALID' + ) as final_blocking_session_status, + DECODE(s.ksusefblocker, + 4294967295, TO_NUMBER(NULL), 4294967294, TO_NUMBER(NULL), 4294967293, TO_NUMBER(NULL), 4294967292, TO_NUMBER(NULL), + 4294967291, TO_NUMBER(NULL), BITAND(s.ksusefblocker, 2147418112) / 65536 + ) as final_blocking_instance, + DECODE(s.ksusefblocker, + 4294967295, TO_NUMBER(NULL), 4294967294, TO_NUMBER(NULL), 4294967293, TO_NUMBER(NULL), 4294967292, TO_NUMBER(NULL), + 4294967291, TO_NUMBER(NULL), BITAND(s.ksusefblocker, 65535) + ) as final_blocking_session, + DECODE(w.kslwtinwait, + 1, 'WAITING', decode(bitand(w.kslwtflags, 256), 0, 'WAITED UNKNOWN TIME', + decode(round(w.kslwtstime / 10000), 0, 'WAITED SHORT TIME', 'WAITED KNOWN TIME')) + ) as STATE, + e.kslednam as event, + e.ksledclass as wait_class, + w.kslwtstime as wait_time_micro, + c.name as pdb_name, + sq.sql_text as sql_text, + sq.sql_fulltext as sql_fulltext, + sq_prev.sql_fulltext as prev_sql_fulltext, + comm.command_name +FROM + x$ksuse s, + x$kslwt w, + x$ksled e, + v$sql sq, + v$sql sq_prev, + v$containers c, + v$sqlcommand comm +WHERE + BITAND(s.ksspaflg, 1) != 0 + AND BITAND(s.ksuseflg, 1) != 0 + AND s.inst_id = USERENV('Instance') + AND s.indx = w.kslwtsid + AND w.kslwtevt = e.indx + AND s.ksusesqi = sq.sql_id(+) + AND decode(s.ksusesch, 65535, TO_NUMBER(NULL), s.ksusesch) = sq.child_number(+) + AND s.ksusepsi = sq_prev.sql_id(+) + AND decode(s.ksusepch, 65535, TO_NUMBER(NULL), s.ksusepch) = sq_prev.child_number(+) + AND s.con_id = c.con_id(+) + AND s.ksuudoct = comm.command_type(+) \ No newline at end of file diff --git a/pkg/collector/corechecks/oracle/compose/initdb.d/02-create-table.sql b/pkg/collector/corechecks/oracle/compose/initdb.d/02-create-table.sql new file mode 100644 index 0000000000000..a7b82e95b8b72 --- /dev/null +++ b/pkg/collector/corechecks/oracle/compose/initdb.d/02-create-table.sql @@ -0,0 +1,3 @@ +create table t(n number); +grant select,insert on t to c##datadog ; +insert into t values(18446744073709551615); diff --git a/pkg/collector/corechecks/oracle/compose/initdb.d/03-grants.sql b/pkg/collector/corechecks/oracle/compose/initdb.d/03-grants.sql new file mode 100644 index 0000000000000..a6b3362edbbff --- /dev/null +++ b/pkg/collector/corechecks/oracle/compose/initdb.d/03-grants.sql @@ -0,0 +1,38 @@ +-- Description: grant privileges to the Datadog user +grant create session to c##datadog ; +grant select on v_$session to c##datadog ; +grant select on v_$database to c##datadog ; +grant select on v_$containers to c##datadog; +grant select on v_$sqlstats to c##datadog ; +grant select on v_$instance to c##datadog ; +grant select on dba_feature_usage_statistics to c##datadog ; +grant select on V_$SQL_PLAN_STATISTICS_ALL to c##datadog ; +grant select on V_$PROCESS to c##datadog ; +grant select on V_$SESSION to c##datadog ; +grant select on V_$CON_SYSMETRIC to c##datadog ; +grant select on CDB_TABLESPACE_USAGE_METRICS to c##datadog ; +grant select on CDB_TABLESPACES to c##datadog ; +grant select on V_$SQLCOMMAND to c##datadog ; +grant select on V_$DATAFILE to c##datadog ; +grant select on V_$SYSMETRIC to c##datadog ; +grant select on V_$SGAINFO to c##datadog ; +grant select on V_$PDBS to c##datadog ; +grant select on CDB_SERVICES to c##datadog ; +grant select on V_$OSSTAT to c##datadog ; +grant select on V_$PARAMETER to c##datadog ; +grant select on V_$SQLSTATS to c##datadog ; +grant select on V_$CONTAINERS to c##datadog ; +grant select on V_$SQL_PLAN_STATISTICS_ALL to c##datadog ; +grant select on V_$SQL to c##datadog ; +grant select on V_$PGASTAT to c##datadog ; +grant select on v_$asm_diskgroup to c##datadog ; +grant select on v_$rsrcmgrmetric to c##datadog ; +grant select on v_$dataguard_config to c##datadog ; +grant select on v_$dataguard_stats to c##datadog ; +grant select on v_$transaction to c##datadog; +grant select on v_$locked_object to c##datadog; +grant select on dba_objects to c##datadog; +grant select on cdb_data_files to c##datadog; +grant select on dba_data_files to c##datadog; + +GRANT SELECT ON dd_session TO c##datadog; \ No newline at end of file diff --git a/pkg/collector/corechecks/oracle/compose/initdb.d/04-create-tablespace.nosplit.sql b/pkg/collector/corechecks/oracle/compose/initdb.d/04-create-tablespace.nosplit.sql new file mode 100644 index 0000000000000..c2c4db425e5cb --- /dev/null +++ b/pkg/collector/corechecks/oracle/compose/initdb.d/04-create-tablespace.nosplit.sql @@ -0,0 +1,19 @@ +declare + dir dba_data_files.file_name%type; + l_create_dir v$parameter.value%type; +begin + begin + select value into l_create_dir from v$parameter where name = 'db_create_file_dest'; + exception + when no_data_found then + l_create_dir := null; + end; + if l_create_dir is null then + select SUBSTR(file_name,1,(INSTR(file_name,'/',-1,1)-1)) into dir from dba_data_files where rownum = 1; + execute immediate 'create tablespace tbs_test datafile ''' || dir || '/tbs_test01.dbf'' size 100M'; + execute immediate 'create tablespace tbs_test_offline datafile ''' || dir || '/tbs_test_offline01.dbf'' size 10M'; + else + execute immediate 'create tablespace tbs_test datafile size 100M'; + execute immediate 'create tablespace tbs_test_offline datafile size 10M'; + end if; +end; diff --git a/pkg/collector/corechecks/oracle/config/config.go b/pkg/collector/corechecks/oracle/config/config.go index 05a6c3da1c40b..586e5e6f397b7 100644 --- a/pkg/collector/corechecks/oracle/config/config.go +++ b/pkg/collector/corechecks/oracle/config/config.go @@ -33,9 +33,10 @@ type InitConfig struct { //nolint:revive // TODO(DBM) Fix revive linter type QuerySamplesConfig struct { - Enabled bool `yaml:"enabled"` - IncludeAllSessions bool `yaml:"include_all_sessions"` - ForceDirectQuery bool `yaml:"force_direct_query"` + Enabled bool `yaml:"enabled"` + IncludeAllSessions bool `yaml:"include_all_sessions"` + ForceDirectQuery bool `yaml:"force_direct_query"` + ActiveSessionHistory bool `yaml:"active_session_history"` } type queryMetricsTrackerConfig struct { diff --git a/pkg/collector/corechecks/oracle/init_test.go b/pkg/collector/corechecks/oracle/init_test.go index 67be0f8b625b3..a7fde6e251185 100644 --- a/pkg/collector/corechecks/oracle/init_test.go +++ b/pkg/collector/corechecks/oracle/init_test.go @@ -8,6 +8,9 @@ package oracle import ( + "fmt" + "os" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -25,3 +28,67 @@ func TestTags(t *testing.T) { assert.Contains(t, c.tags, dbmsTag, "Static tag not merged") assert.Contains(t, c.tags, "foo1:bar1", "Config tag not in tags") } + +// This test is just used for debugging database init issues +// To use, set the assert to always fail then run the test +func TestNoop(t *testing.T) { + assert.True(t, true) +} + +func TestMain(m *testing.M) { + print("Running initdb.d sql files...") + // This is a bit of a hack to get a db connection without a testing.T + // Ideally we should pull the connection logic out + // to make it more accessible for testing + sysCheck, _ := newSysCheck(nil, "", "") + sysCheck.Run() + _, err := sysCheck.db.Exec("SELECT 1 FROM dual") + if err != nil { + fmt.Printf("Error executing select check: %s\n", err) + os.Exit(1) + } + + initDbPath := "./compose/initdb.d" + files, _ := os.ReadDir(initDbPath) + for _, file := range files { + if file.IsDir() { + continue + } + filename := file.Name() + bytes, err := os.ReadFile(initDbPath + "/" + filename) + if err != nil { + fmt.Printf("Error reading file %s: %s\n", filename, err) + os.Exit(1) + } + fmt.Printf("Executing %s\n", filename) + sql := string(bytes) + if strings.HasSuffix(filename, ".nosplit.sql") { + // For some inits we need to run functions without splitting + _, err = sysCheck.db.Exec(sql) + if err != nil { + fmt.Printf("Error executing as literal \n%s\n %s\n", sql, err) + } + } else { + // Oracle can't handle multiple SQL statements in a single exec + lines := strings.Split(sql, "\n") + for _, line := range lines { + if strings.HasPrefix(line, "--") { + continue + } + // It also hates semicolons + trimmed := strings.TrimSpace(strings.TrimSuffix(strings.TrimSpace(line), ";")) + if trimmed == "" { + continue + } + fmt.Printf("Executing %s\n", trimmed) + _, err = sysCheck.db.Exec(trimmed) + if err != nil { + fmt.Printf("Error executing \n%s\n %s\n", trimmed, err) + } + } + } + } + + code := m.Run() + os.Exit(code) +} diff --git a/pkg/collector/corechecks/oracle/oracle.go b/pkg/collector/corechecks/oracle/oracle.go index 6d5cac9051f34..733c9c2933f5c 100644 --- a/pkg/collector/corechecks/oracle/oracle.go +++ b/pkg/collector/corechecks/oracle/oracle.go @@ -115,6 +115,7 @@ type Check struct { openMode string legacyIntegrationCompatibilityMode bool clock clock.Clock + lastSampleId uint64 } type vDatabase struct { diff --git a/pkg/collector/corechecks/oracle/oracle_integration_test.go b/pkg/collector/corechecks/oracle/oracle_integration_test.go index 1293240c48703..ce673b3275930 100644 --- a/pkg/collector/corechecks/oracle/oracle_integration_test.go +++ b/pkg/collector/corechecks/oracle/oracle_integration_test.go @@ -306,6 +306,7 @@ func TestObfuscator(t *testing.T) { } func TestLegacyMode(t *testing.T) { + t.Skip() canConnectServiceCheckName := "oracle.can_query" for _, config := range []string{ diff --git a/pkg/collector/corechecks/oracle/sysmetrics_test.go b/pkg/collector/corechecks/oracle/sysmetrics_test.go index 426de5b05a213..57914e9fea75b 100644 --- a/pkg/collector/corechecks/oracle/sysmetrics_test.go +++ b/pkg/collector/corechecks/oracle/sysmetrics_test.go @@ -14,6 +14,8 @@ import ( ) func TestSysmetrics(t *testing.T) { + t.Skip("sysmetrics can take several minutes to return the correct number") + // TODO: Find a way to flush metrics manually c, _ := newDefaultCheck(t, "dbm: true", "") defer c.Teardown() c.Run() diff --git a/pkg/collector/corechecks/oracle/testutil.go b/pkg/collector/corechecks/oracle/testutil.go index efac221136879..f230b3afbfb0b 100644 --- a/pkg/collector/corechecks/oracle/testutil.go +++ b/pkg/collector/corechecks/oracle/testutil.go @@ -40,12 +40,9 @@ const ( func getConnectData(t *testing.T, userType int) config.ConnectionConfig { handleRealConnection := func(userType int) config.ConnectionConfig { - var username string - var password string - var server string - var serviceName string var userEnvVariable string var passwordEnvVariable string + serverEnvVariable := "ORACLE_TEST_SERVER" serviceNameEnvVariable := "ORACLE_TEST_SERVICE_NAME" portEnvVariable := "ORACLE_TEST_PORT" @@ -54,23 +51,40 @@ func getConnectData(t *testing.T, userType int) config.ConnectionConfig { case useDefaultUser: userEnvVariable = "ORACLE_TEST_USER" passwordEnvVariable = "ORACLE_TEST_PASSWORD" - server = os.Getenv(serverEnvVariable) - serviceName = os.Getenv(serviceNameEnvVariable) case useLegacyUser: userEnvVariable = "ORACLE_TEST_LEGACY_USER" passwordEnvVariable = "ORACLE_TEST_LEGACY_PASSWORD" - server = os.Getenv(serverEnvVariable) - serviceName = os.Getenv(serviceNameEnvVariable) case useSysUser: userEnvVariable = "ORACLE_TEST_SYS_USER" passwordEnvVariable = "ORACLE_TEST_SYS_PASSWORD" - server = os.Getenv(serverEnvVariable) - serviceName = os.Getenv(serviceNameEnvVariable) } - username = os.Getenv(userEnvVariable) - password = os.Getenv(passwordEnvVariable) - port, _ := strconv.Atoi(os.Getenv(portEnvVariable)) + server := os.Getenv(serverEnvVariable) + if server == "" { + server = "localhost" + } + serviceName := os.Getenv(serviceNameEnvVariable) + if serviceName == "" { + serviceName = "XE" + } + + username := os.Getenv(userEnvVariable) + password := os.Getenv(passwordEnvVariable) + if username == "" { + switch userType { + case useDefaultUser: + username = "c##datadog" + password = "datadog" + case useSysUser: + username = "sys" + password = "datad0g" + } + } + + port, err := strconv.Atoi(os.Getenv(portEnvVariable)) + if port == 0 || err != nil { + port = 1521 + } if t != nil { require.NotEqualf(t, "", username, "Please set the %s environment variable", userEnvVariable) @@ -113,7 +127,9 @@ func newTestCheck(t *testing.T, connectConfig config.ConnectionConfig, instanceC c := Check{} connectYaml, err := yaml.Marshal(connectConfig) - require.NoError(t, err) + if t != nil { + require.NoError(t, err) + } instanceConfig := string(connectYaml) if instanceConfigAddition != "" { instanceConfig = fmt.Sprintf("%s\n%s", instanceConfig, instanceConfigAddition) @@ -122,17 +138,20 @@ func newTestCheck(t *testing.T, connectConfig config.ConnectionConfig, instanceC rawInitConfig := []byte(initConfig) senderManager := mocksender.CreateDefaultDemultiplexer() err = c.Configure(senderManager, integration.FakeConfigHash, rawInstanceConfig, rawInitConfig, "oracle_test") - require.NoError(t, err) + if t != nil { + require.NoError(t, err) + } sender := mocksender.NewMockSenderWithSenderManager(c.ID(), senderManager) sender.SetupAcceptAll() - assert.Equal(t, c.config.InstanceConfig.Server, connectConfig.Server) - assert.Equal(t, c.config.InstanceConfig.Port, connectConfig.Port) - assert.Equal(t, c.config.InstanceConfig.Username, connectConfig.Username) - assert.Equal(t, c.config.InstanceConfig.Password, connectConfig.Password) - assert.Equal(t, c.config.InstanceConfig.ServiceName, connectConfig.ServiceName) - - assert.Contains(t, c.configTags, dbmsTag, "c.configTags doesn't contain static tags") + if t != nil { + assert.Equal(t, c.config.InstanceConfig.Server, connectConfig.Server) + assert.Equal(t, c.config.InstanceConfig.Port, connectConfig.Port) + assert.Equal(t, c.config.InstanceConfig.Username, connectConfig.Username) + assert.Equal(t, c.config.InstanceConfig.Password, connectConfig.Password) + assert.Equal(t, c.config.InstanceConfig.ServiceName, connectConfig.ServiceName) + assert.Contains(t, c.configTags, dbmsTag, "c.configTags doesn't contain static tags") + } return c, sender } @@ -147,6 +166,10 @@ func newDefaultCheck(t *testing.T, instanceConfigAddition string, initConfig str return newTestCheck(t, getConnectData(t, useDefaultUser), instanceConfigAddition, initConfig) } +func newSysCheck(t *testing.T, instanceConfigAddition string, initConfig string) (Check, *mocksender.MockSender) { + return newTestCheck(t, getConnectData(t, useSysUser), instanceConfigAddition, initConfig) +} + func newDbDoesNotExistCheck(t *testing.T, instanceConfigAddition string, initConfig string) (Check, *mocksender.MockSender) { return newTestCheck(t, getConnectData(t, useDoesNotExistUser), instanceConfigAddition, initConfig) } diff --git a/pkg/collector/corechecks/sbom/check_test.go b/pkg/collector/corechecks/sbom/check_test.go index 7fec369a05fd0..4134898f31473 100644 --- a/pkg/collector/corechecks/sbom/check_test.go +++ b/pkg/collector/corechecks/sbom/check_test.go @@ -108,11 +108,10 @@ host_heartbeat_validity_seconds: 1000000 } func TestFactory(t *testing.T) { - cfg := fxutil.Test[config.Component](t, config.MockModule()) + cfg := config.NewMock(t) mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) checkFactory := Factory(mockStore, cfg) assert.NotNil(t, checkFactory) @@ -164,11 +163,10 @@ func TestConfigure(t *testing.T) { }, }), core.MockBundle(), - fx.Supply(workloadmeta.Params{ + workloadmetafxmock.MockModule(workloadmeta.Params{ AgentType: workloadmeta.NodeAgent, InitHelper: common.GetWorkloadmetaInit(), }), - workloadmetafxmock.MockModule(), )) cfg := app.Cfg mockStore := app.Store diff --git a/pkg/collector/corechecks/sbom/processor.go b/pkg/collector/corechecks/sbom/processor.go index 6ce905f0798f4..b19aedf9e24d9 100644 --- a/pkg/collector/corechecks/sbom/processor.go +++ b/pkg/collector/corechecks/sbom/processor.go @@ -21,6 +21,7 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/comp/forwarder/eventplatform" "github.com/DataDog/datadog-agent/pkg/aggregator/sender" + "github.com/DataDog/datadog-agent/pkg/config/env" ddConfig "github.com/DataDog/datadog-agent/pkg/config" "github.com/DataDog/datadog-agent/pkg/sbom" @@ -250,7 +251,7 @@ func (p *processor) triggerHostScan() { log.Debugf("Triggering host SBOM refresh") scanPath := "/" - if hostRoot := os.Getenv("HOST_ROOT"); ddConfig.IsContainerized() && hostRoot != "" { + if hostRoot := os.Getenv("HOST_ROOT"); env.IsContainerized() && hostRoot != "" { scanPath = hostRoot } scanRequest := host.NewScanRequest(scanPath, newFS("/")) diff --git a/pkg/collector/corechecks/sbom/processor_test.go b/pkg/collector/corechecks/sbom/processor_test.go index 9a410b8508b95..ac96503f82048 100644 --- a/pkg/collector/corechecks/sbom/processor_test.go +++ b/pkg/collector/corechecks/sbom/processor_test.go @@ -598,8 +598,7 @@ func TestProcessEvents(t *testing.T) { cfg := configmock.New(t) wmeta := fxutil.Test[optional.Option[workloadmeta.Component]](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), fx.Replace(configcomp.MockParams{ Overrides: map[string]interface{}{ "sbom.cache_directory": cacheDir, @@ -618,8 +617,7 @@ func TestProcessEvents(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), configcomp.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) sender := mocksender.NewMockSender("") diff --git a/pkg/collector/corechecks/servicediscovery/apm/detect.go b/pkg/collector/corechecks/servicediscovery/apm/detect.go index d367c9fa9e0d1..da956a347f1e4 100644 --- a/pkg/collector/corechecks/servicediscovery/apm/detect.go +++ b/pkg/collector/corechecks/servicediscovery/apm/detect.go @@ -3,23 +3,24 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. +//go:build linux + // Package apm provides functionality to detect the type of APM instrumentation a service is using. package apm import ( - "bytes" - "errors" + "bufio" "io" - "io/fs" "os" - "os/exec" "path/filepath" + "regexp" + "strconv" "strings" - "go.uber.org/zap" - "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/language" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/language/reader" + "github.com/DataDog/datadog-agent/pkg/util/kernel" + "github.com/DataDog/datadog-agent/pkg/util/log" ) // Instrumentation represents the state of APM instrumentation for a service. @@ -34,7 +35,7 @@ const ( Injected Instrumentation = "injected" ) -type detector func(logger *zap.Logger, args []string, envs []string) Instrumentation +type detector func(pid int, args []string, envs map[string]string) Instrumentation var ( detectorMap = map[language.Language]detector{ @@ -42,31 +43,38 @@ var ( language.Java: javaDetector, language.Node: nodeDetector, language.Python: pythonDetector, - language.Ruby: rubyDetector, } + // For now, only allow a subset of the above detectors to actually run. + allowedLangs = map[language.Language]struct{}{ + language.Java: {}, + language.Node: {}, + language.Python: {}, + } + + nodeAPMCheckRegex = regexp.MustCompile(`"dd-trace"`) ) // Detect attempts to detect the type of APM instrumentation for the given service. -func Detect(logger *zap.Logger, args []string, envs []string, lang language.Language) Instrumentation { +func Detect(pid int, args []string, envs map[string]string, lang language.Language) Instrumentation { // first check to see if the DD_INJECTION_ENABLED is set to tracer if isInjected(envs) { return Injected } + if _, ok := allowedLangs[lang]; !ok { + return None + } + // different detection for provided instrumentation for each if detect, ok := detectorMap[lang]; ok { - return detect(logger, args, envs) + return detect(pid, args, envs) } return None } -func isInjected(envs []string) bool { - for _, env := range envs { - if !strings.HasPrefix(env, "DD_INJECTION_ENABLED=") { - continue - } - _, val, _ := strings.Cut(env, "=") +func isInjected(envs map[string]string) bool { + if val, ok := envs["DD_INJECTION_ENABLED"]; ok { parts := strings.Split(val, ",") for _, v := range parts { if v == "tracer" { @@ -77,124 +85,100 @@ func isInjected(envs []string) bool { return false } -func rubyDetector(_ *zap.Logger, _ []string, _ []string) Instrumentation { - return None -} +func pythonDetectorFromMapsReader(reader io.Reader) Instrumentation { + scanner := bufio.NewScanner(bufio.NewReader(reader)) + for scanner.Scan() { + line := scanner.Text() -func pythonDetector(logger *zap.Logger, args []string, envs []string) Instrumentation { - /* - Check for VIRTUAL_ENV env var - if it's there, use $VIRTUAL_ENV/lib/python{}/site-packages/ and see if ddtrace is inside - if so, return PROVIDED - if it's not there, - exec args[0] -c "import sys; print(':'.join(sys.path))" - split on : - for each part - see if it ends in site-packages - if so, check if ddtrace is inside - if so, return PROVIDED - return NONE - */ - for _, env := range envs { - if strings.HasPrefix(env, "VIRTUAL_ENV=") { - _, path, _ := strings.Cut(env, "=") - venv := os.DirFS(path) - libContents, err := fs.ReadDir(venv, "lib") - if err != nil { - continue - } - for _, v := range libContents { - if strings.HasPrefix(v.Name(), "python") && v.IsDir() { - tracedir, err := fs.Stat(venv, "lib/"+v.Name()+"/site-packages/ddtrace") - if err != nil { - continue - } - if tracedir.IsDir() { - return Provided - } - } - } - // the virtual env didn't have ddtrace, can exit - return None + if strings.Contains(line, "/ddtrace/") { + return Provided } } - // slow option... - results, err := exec.Command(args[0], `-c`, `"import sys; print(':'.join(sys.path))"`).Output() + + return None +} + +// pythonDetector detects the use of the ddtrace package in the process. Since +// the ddtrace package uses native libraries, the paths of these libraries will +// show up in /proc/$PID/maps. +// +// It looks for the "/ddtrace/" part of the path. It doesn not look for the +// "/site-packages/" part since some environments (such as pyinstaller) may not +// use that exact name. +// +// For example: +// 7aef453fc000-7aef453ff000 rw-p 0004c000 fc:06 7895473 /home/foo/.local/lib/python3.10/site-packages/ddtrace/internal/_encoding.cpython-310-x86_64-linux-gnu.so +// 7aef45400000-7aef45459000 r--p 00000000 fc:06 7895588 /home/foo/.local/lib/python3.10/site-packages/ddtrace/internal/datadog/profiling/libdd_wrapper.so +func pythonDetector(pid int, _ []string, _ map[string]string) Instrumentation { + mapsPath := kernel.HostProc(strconv.Itoa(pid), "maps") + mapsFile, err := os.Open(mapsPath) if err != nil { - logger.Warn("Failed to execute command", zap.Error(err)) return None } + defer mapsFile.Close() - results = bytes.TrimSpace(results) - parts := strings.Split(string(results), ":") - logger.Debug("parts", zap.Strings("parts", parts)) - for _, v := range parts { - if strings.HasSuffix(v, "/site-packages") { - _, err := os.Stat(v + "/ddtrace") - if err == nil { - return Provided - } - } - } - return None + return pythonDetectorFromMapsReader(mapsFile) } -func nodeDetector(logger *zap.Logger, _ []string, envs []string) Instrumentation { - // check package.json, see if it has dd-trace in it. - // first find it - wd := "" - for _, v := range envs { - if strings.HasPrefix(v, "PWD=") { - _, wd, _ = strings.Cut(v, "=") - break - } +// isNodeInstrumented parses the provided `os.File` trying to find an +// entry for APM NodeJS instrumentation. Returns true if finding such +// an entry, false otherwise. +func isNodeInstrumented(f *os.File) bool { + // Don't try to read a non-regular file. + if fi, err := f.Stat(); err != nil || !fi.Mode().IsRegular() { + return false } - if wd == "" { - // don't know the working directory, just quit - logger.Debug("unable to determine working directory, assuming uninstrumented") + + const readLimit = 1 * 1024 * 1024 // Read 1MiB max + + limitReader := io.LimitReader(f, readLimit) + bufferedReader := bufio.NewReader(limitReader) + + return nodeAPMCheckRegex.MatchReader(bufferedReader) +} + +// nodeDetector checks if a service has APM NodeJS instrumentation. +// +// To check for APM instrumentation, we try to find a package.json in +// the parent directories of the service. If found, we then check for a +// `dd-trace` entry to be present. +func nodeDetector(_ int, _ []string, envs map[string]string) Instrumentation { + processWorkingDirectory := "" + if val, ok := envs["PWD"]; ok { + processWorkingDirectory = filepath.Clean(val) + } else { + log.Debug("unable to determine working directory, assuming uninstrumented") return None } - // find package.json, see if already instrumented - // whatever is the first package.json that we find, we use - // we keep checking up to the root of the file system - for curWD := filepath.Clean(wd); len(curWD) > 1; curWD = filepath.Dir(curWD) { - curPkgJSON := curWD + string(filepath.Separator) + "package.json" - f, err := os.Open(curPkgJSON) - // this error means the file isn't there, so check parent directory + for curDir := processWorkingDirectory; len(curDir) > 1; curDir = filepath.Dir(curDir) { + pkgJSONPath := filepath.Join(curDir, "package.json") + pkgJSONFile, err := os.Open(pkgJSONPath) if err != nil { - if errors.Is(err, os.ErrNotExist) { - logger.Debug("package.json not found", zap.String("path", curPkgJSON)) - } else { - logger.Debug("error opening package.json", zap.String("path", curPkgJSON), zap.Error(err)) - } - continue - } - offset, err := reader.Index(f, `"dd-trace"`) - if err != nil { - logger.Debug("error reading package.json", zap.String("path", curPkgJSON), zap.Error(err)) - _ = f.Close() + log.Debugf("could not open package.json: %s", err) continue } - if offset != -1 { - _ = f.Close() + log.Debugf("found package.json: %s", pkgJSONPath) + + isInstrumented := isNodeInstrumented(pkgJSONFile) + _ = pkgJSONFile.Close() + + if isInstrumented { return Provided } - // intentionally ignoring error here - _ = f.Close() - return None } + return None } -func javaDetector(_ *zap.Logger, args []string, envs []string) Instrumentation { +func javaDetector(_ int, args []string, envs map[string]string) Instrumentation { ignoreArgs := map[string]bool{ "-version": true, "-Xshare:dump": true, "/usr/share/ca-certificates-java/ca-certificates-java.jar": true, } - //Check simple args on builtIn list. + // Check simple args on builtIn list. for _, v := range args { if ignoreArgs[v] { return None @@ -205,20 +189,19 @@ func javaDetector(_ *zap.Logger, args []string, envs []string) Instrumentation { } } // also don't instrument if the javaagent is there in the environment variable JAVA_TOOL_OPTIONS and friends - toolOptionEnvs := map[string]bool{ + toolOptionEnvs := []string{ // These are the environment variables that are used to pass options to the JVM - "JAVA_TOOL_OPTIONS": true, - "_JAVA_OPTIONS": true, - "JDK_JAVA_OPTIONS": true, + "JAVA_TOOL_OPTIONS", + "_JAVA_OPTIONS", + "JDK_JAVA_OPTIONS", // I'm pretty sure these won't be necessary, as they should be parsed before the JVM sees them // but there's no harm in including them - "JAVA_OPTIONS": true, - "CATALINA_OPTS": true, - "JDPA_OPTS": true, + "JAVA_OPTIONS", + "CATALINA_OPTS", + "JDPA_OPTS", } - for _, v := range envs { - name, val, _ := strings.Cut(v, "=") - if toolOptionEnvs[name] { + for _, name := range toolOptionEnvs { + if val, ok := envs[name]; ok { if strings.Contains(val, "-javaagent:") && strings.Contains(val, "dd-java-agent.jar") { return Provided } @@ -237,7 +220,7 @@ func findFile(fileName string) (io.ReadCloser, bool) { const datadogDotNetInstrumented = "Datadog.Trace.ClrProfiler.Native" -func dotNetDetector(_ *zap.Logger, args []string, envs []string) Instrumentation { +func dotNetDetector(_ int, args []string, envs map[string]string) Instrumentation { // if it's just the word `dotnet` by itself, don't instrument if len(args) == 1 && args[0] == "dotnet" { return None @@ -251,13 +234,11 @@ func dotNetDetector(_ *zap.Logger, args []string, envs []string) Instrumentation */ // don't instrument if the tracer is already installed foundFlags := 0 - for _, v := range envs { - if strings.HasPrefix(v, "CORECLR_PROFILER_PATH") { - foundFlags |= 1 - } - if v == "CORECLR_ENABLE_PROFILING=1" { - foundFlags |= 2 - } + if _, ok := envs["CORECLR_PROFILER_PATH"]; ok { + foundFlags |= 1 + } + if val, ok := envs["CORECLR_ENABLE_PROFILING"]; ok && val == "1" { + foundFlags |= 2 } if foundFlags == 3 { return Provided diff --git a/pkg/collector/corechecks/servicediscovery/apm/detect_nix_test.go b/pkg/collector/corechecks/servicediscovery/apm/detect_nix_test.go index 20a43aad5f16c..e3ce1a6934344 100644 --- a/pkg/collector/corechecks/servicediscovery/apm/detect_nix_test.go +++ b/pkg/collector/corechecks/servicediscovery/apm/detect_nix_test.go @@ -3,41 +3,91 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build !windows +//go:build linux package apm import ( - "os" + "path/filepath" "strings" "testing" - "go.uber.org/zap" + "github.com/DataDog/datadog-agent/pkg/network/protocols/http/testutil" + "github.com/stretchr/testify/assert" ) +func TestInjected(t *testing.T) { + data := []struct { + name string + envs map[string]string + result bool + }{ + { + name: "injected", + envs: map[string]string{ + "DD_INJECTION_ENABLED": "tracer", + }, + result: true, + }, + { + name: "one of injected", + envs: map[string]string{ + "DD_INJECTION_ENABLED": "service_name,tracer", + }, + result: true, + }, + { + name: "not injected but with env variable", + envs: map[string]string{ + "DD_INJECTION_ENABLED": "service_name", + }, + }, + { + name: "not injected, no env variable", + }, + } + for _, d := range data { + t.Run(d.name, func(t *testing.T) { + result := isInjected(d.envs) + assert.Equal(t, d.result, result) + }) + } +} + func Test_javaDetector(t *testing.T) { data := []struct { name string args []string - envs []string + envs map[string]string result Instrumentation }{ { name: "not there", args: strings.Split("java -jar Foo.jar Foo", " "), - envs: nil, result: None, }, { name: "version", args: strings.Split("java -version", " "), - envs: nil, result: None, }, + { + name: "cmdline", + args: []string{"java", "-foo", "-javaagent:/path/to/data dog/dd-java-agent.jar", "-Ddd.profiling.enabled=true"}, + result: Provided, + }, + { + name: "CATALINA_OPTS", + args: []string{"java"}, + envs: map[string]string{ + "CATALINA_OPTS": "-javaagent:dd-java-agent.jar", + }, + result: Provided, + }, } for _, d := range data { t.Run(d.name, func(t *testing.T) { - result := javaDetector(zap.NewNop(), d.args, d.envs) + result := javaDetector(0, d.args, d.envs) if result != d.result { t.Errorf("expected %s got %s", d.result, result) } @@ -45,54 +95,72 @@ func Test_javaDetector(t *testing.T) { } } -func Test_pythonDetector(t *testing.T) { - tmpDir := t.TempDir() - err := os.MkdirAll(tmpDir+"/lib/python3.11/site-packages/ddtrace", 0700) - if err != nil { - t.Fatal(err) - } - tmpDir2 := t.TempDir() - err = os.MkdirAll(tmpDir2+"/lib/python3.11/site-packages/notddtrace", 0700) - if err != nil { - t.Fatal(err) - } +func Test_nodeDetector(t *testing.T) { + curDir, err := testutil.CurDir() + assert.NoError(t, err) + data := []struct { name string - args []string - envs []string + envs map[string]string result Instrumentation }{ { - name: "venv_provided", - args: []string{"./echoer.sh", "nope"}, - envs: []string{"VIRTUAL_ENV=" + tmpDir}, + name: "not instrumented", + envs: map[string]string{ + "PWD": filepath.Join(curDir, "testdata/node/not_instrumented"), + }, + result: None, + }, + { + name: "instrumented", + envs: map[string]string{ + "PWD": filepath.Join(curDir, "testdata/node/instrumented"), + }, result: Provided, }, + } + + for _, d := range data { + t.Run(d.name, func(t *testing.T) { + result := nodeDetector(0, nil, d.envs) + assert.Equal(t, d.result, result) + }) + } +} + +func Test_pythonDetector(t *testing.T) { + data := []struct { + name string + maps string + result Instrumentation + }{ { - name: "venv_none", - args: []string{"./testdata/echoer.sh", "nope"}, - envs: []string{"VIRTUAL_ENV=" + tmpDir2}, + name: "empty maps", + maps: "", result: None, }, { - name: "cmd_provided", - args: []string{"./testdata/cmd_works.sh"}, - envs: []string{}, - result: Provided, + name: "not in maps", + maps: ` +79f6cd47d000-79f6cd47f000 r--p 00000000 fc:04 793163 /usr/lib/python3.10/lib-dynload/_bz2.cpython-310-x86_64-linux-gnu.so +79f6cd479000-79f6cd47a000 r-xp 00001000 fc:06 5507018 /home/foo/.local/lib/python3.10/site-packages/ddtrace_fake/md.cpython-310-x86_64-linux-gnu.so + `, + result: None, }, { - name: "cmd_none", - args: []string{"./testdata/cmd_fails.sh"}, - envs: []string{}, - result: None, + name: "in maps", + maps: ` +79f6cd47d000-79f6cd47f000 r--p 00000000 fc:04 793163 /usr/lib/python3.10/lib-dynload/_bz2.cpython-310-x86_64-linux-gnu.so +79f6cd482000-79f6cd484000 r--p 00005000 fc:04 793163 /usr/lib/python3.10/lib-dynload/_bz2.cpython-310-x86_64-linux-gnu.so +79f6cd438000-79f6cd441000 r-xp 00004000 fc:06 7895596 /home/foo/.local/lib/python3.10/site-packages-internal/ddtrace/internal/datadog/profiling/crashtracker/_crashtracker.cpython-310-x86_64-linux-gnu.so + `, + result: Provided, }, } for _, d := range data { t.Run(d.name, func(t *testing.T) { - result := pythonDetector(zap.NewNop(), d.args, d.envs) - if result != d.result { - t.Errorf("expected %s got %s", d.result, result) - } + result := pythonDetectorFromMapsReader(strings.NewReader(d.maps)) + assert.Equal(t, d.result, result) }) } } diff --git a/pkg/collector/corechecks/servicediscovery/apm/testdata/node/instrumented/package.json b/pkg/collector/corechecks/servicediscovery/apm/testdata/node/instrumented/package.json new file mode 100644 index 0000000000000..bdf13a51c6498 --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/apm/testdata/node/instrumented/package.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "bar": ">=1.9.0", + "dd-trace": "9.99.9", + "foo": "1.0.1" + } +} diff --git a/pkg/collector/corechecks/servicediscovery/apm/testdata/node/not_instrumented/package.json b/pkg/collector/corechecks/servicediscovery/apm/testdata/node/not_instrumented/package.json new file mode 100644 index 0000000000000..32aa2a8b642ed --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/apm/testdata/node/not_instrumented/package.json @@ -0,0 +1,7 @@ +{ + "name": "foopackage", + "dependencies": { + "bar": ">=1.9.0", + "foo": "1.0.1" + } +} diff --git a/pkg/collector/corechecks/servicediscovery/impl_linux.go b/pkg/collector/corechecks/servicediscovery/impl_linux.go index 7060c051493e3..3b5ac8452d451 100644 --- a/pkg/collector/corechecks/servicediscovery/impl_linux.go +++ b/pkg/collector/corechecks/servicediscovery/impl_linux.go @@ -13,7 +13,6 @@ import ( "github.com/prometheus/procfs" - "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/language" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/model" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/servicetype" ddconfig "github.com/DataDog/datadog-agent/pkg/config" @@ -49,8 +48,7 @@ type linuxImpl struct { time timer bootTime uint64 - serviceDetector *ServiceDetector - ignoreCfg map[string]bool + ignoreCfg map[string]bool ignoreProcs map[int]bool aliveServices map[int]*serviceInfo @@ -76,7 +74,6 @@ func newLinuxImpl(ignoreCfg map[string]bool) (osImpl, error) { bootTime: stat.BootTime, getSysProbeClient: getSysProbeClient, time: realTime{}, - serviceDetector: NewServiceDetector(), ignoreCfg: ignoreCfg, ignoreProcs: make(map[int]bool), aliveServices: make(map[int]*serviceInfo), @@ -251,8 +248,6 @@ func (li *linuxImpl) getServiceInfo(p proc, service model.Service) (*serviceInfo return nil, err } - lang := language.FindInArgs(cmdline) - stat, err := p.Stat() if err != nil { return nil, fmt.Errorf("failed to read /proc/{pid}/stat: %w", err) @@ -282,9 +277,11 @@ func (li *linuxImpl) getServiceInfo(p proc, service model.Service) (*serviceInfo serviceType := servicetype.Detect(service.Name, service.Ports) meta := ServiceMetadata{ - Name: service.Name, - Language: string(lang), - Type: string(serviceType), + Name: service.Name, + Language: service.Language, + Type: string(serviceType), + APMInstrumentation: service.APMInstrumentation, + NameSource: service.NameSource, } return &serviceInfo{ diff --git a/pkg/collector/corechecks/servicediscovery/impl_linux_test.go b/pkg/collector/corechecks/servicediscovery/impl_linux_test.go index 7ae84df2e98a2..d51004b64277b 100644 --- a/pkg/collector/corechecks/servicediscovery/impl_linux_test.go +++ b/pkg/collector/corechecks/servicediscovery/impl_linux_test.go @@ -24,6 +24,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/comp/core/hostname/hostnameinterface" "github.com/DataDog/datadog-agent/pkg/aggregator/mocksender" + "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/apm" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/model" ) @@ -119,14 +120,18 @@ var ( Ports: []uint16{22}, } portTCP8080 = model.Service{ - PID: procTestService1.pid, - Name: "test-service-1", - Ports: []uint16{8080}, + PID: procTestService1.pid, + Name: "test-service-1", + Ports: []uint16{8080}, + APMInstrumentation: string(apm.None), + NameSource: "provided", } portTCP8080DifferentPID = model.Service{ - PID: procTestService1DifferentPID.pid, - Name: "test-service-1", - Ports: []uint16{8080}, + PID: procTestService1DifferentPID.pid, + Name: "test-service-1", + Ports: []uint16{8080}, + APMInstrumentation: string(apm.Injected), + NameSource: "generated", } portTCP8081 = model.Service{ PID: procIgnoreService1.pid, @@ -134,9 +139,10 @@ var ( Ports: []uint16{8081}, } portTCP5000 = model.Service{ - PID: procPythonService.pid, - Name: "python-service", - Ports: []uint16{5000}, + PID: procPythonService.pid, + Name: "python-service", + Language: "python", + Ports: []uint16{5000}, } portTCP5432 = model.Service{ PID: procTestService1Repeat.pid, @@ -280,6 +286,8 @@ func Test_linuxImpl(t *testing.T) { Ports: []uint16{8080}, PID: 99, CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + ServiceNameSource: "provided", }, }, { @@ -296,6 +304,8 @@ func Test_linuxImpl(t *testing.T) { Ports: []uint16{8080}, PID: 99, CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + ServiceNameSource: "provided", }, }, { @@ -312,6 +322,8 @@ func Test_linuxImpl(t *testing.T) { Ports: []uint16{8080}, PID: 99, CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + ServiceNameSource: "provided", }, }, { @@ -441,6 +453,8 @@ func Test_linuxImpl(t *testing.T) { Ports: []uint16{8080}, PID: 99, CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + ServiceNameSource: "provided", }, }, { @@ -489,6 +503,8 @@ func Test_linuxImpl(t *testing.T) { Ports: []uint16{8080}, PID: 99, CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + ServiceNameSource: "provided", }, }, }, @@ -562,6 +578,8 @@ func Test_linuxImpl(t *testing.T) { Ports: []uint16{8080}, PID: 99, CommandLine: []string{"test-service-1"}, + APMInstrumentation: "none", + ServiceNameSource: "provided", }, }, { @@ -578,6 +596,8 @@ func Test_linuxImpl(t *testing.T) { Ports: []uint16{8080}, PID: 102, CommandLine: []string{"test-service-1"}, + APMInstrumentation: "injected", + ServiceNameSource: "generated", }, }, }, diff --git a/pkg/collector/corechecks/servicediscovery/language/language.go b/pkg/collector/corechecks/servicediscovery/language/language.go index 8f785390bc6c6..63e8378c116a9 100644 --- a/pkg/collector/corechecks/servicediscovery/language/language.go +++ b/pkg/collector/corechecks/servicediscovery/language/language.go @@ -3,17 +3,16 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. +//go:build linux + // Package language provides functionality to detect the programming language for a given process. package language import ( - "fmt" - "io" - "os" - "path" - "strings" - - "go.uber.org/zap" + "github.com/DataDog/datadog-agent/pkg/languagedetection" + "github.com/DataDog/datadog-agent/pkg/languagedetection/languagemodels" + "github.com/DataDog/datadog-agent/pkg/languagedetection/privileged" + "github.com/DataDog/datadog-agent/pkg/process/procutil" ) // Language represents programming languages. @@ -41,122 +40,65 @@ const ( ) var ( - procToLanguage = map[string]Language{ - "java": Java, - "node": Node, - "nodemon": Node, - "python": Python, - "python3": Python, - "dotnet": DotNet, - "ruby": Ruby, - "bundle": Ruby, + // languageNameToLanguageMap translates the constants rom the + // languagedetection package to the constants used in this file. The latter + // are shared with the backend, and at least java/jvm differs in the name + // from the languagedetection package. + languageNameToLanguageMap = map[languagemodels.LanguageName]Language{ + languagemodels.Go: Go, + languagemodels.Node: Node, + languagemodels.Dotnet: DotNet, + languagemodels.Python: Python, + languagemodels.Java: Java, + languagemodels.Ruby: Ruby, } ) -// Detect attempts to detect the Language from the provided process information. -func (lf Finder) Detect(args []string, envs []string) (Language, bool) { - lang := lf.findLang(ProcessInfo{ - Args: args, - Envs: envs, - }) - if lang == "" { - return Unknown, false - } - return lang, true -} - -func findFile(fileName string) (io.ReadCloser, bool) { - f, err := os.Open(fileName) - if err != nil { - return nil, false - } - return f, true -} - // ProcessInfo holds information about a process. type ProcessInfo struct { Args []string - Envs []string + Envs map[string]string } -// FileReader attempts to read the most representative file associated to a process. -func (pi ProcessInfo) FileReader() (io.ReadCloser, bool) { - if len(pi.Args) == 0 { - return nil, false - } - fileName := pi.Args[0] - // if it's an absolute path, use it - if strings.HasPrefix(fileName, "/") { - return findFile(fileName) - } - for _, env := range pi.Envs { - if key, val, _ := strings.Cut(env, "="); key == "PATH" { - paths := strings.Split(val, ":") - for _, path := range paths { - if r, found := findFile(path + string(os.PathSeparator) + fileName); found { - return r, true - } - } - } +// FindInArgs tries to detect the language only using the provided command line arguments. +func FindInArgs(args []string) Language { + // empty slice passed in + if len(args) == 0 { + return "" } - // well, just try it as a relative path, maybe it works - return findFile(fileName) -} -// Matcher allows to check if a process matches to a concrete language. -type Matcher interface { - Language() Language - Match(pi ProcessInfo) bool -} - -// New returns a new language Finder. -func New(l *zap.Logger) Finder { - return Finder{ - Logger: l, - Matchers: []Matcher{ - PythonScript{}, - RubyScript{}, - DotNetBinary{}, - }, + langs := languagedetection.DetectLanguage([]languagemodels.Process{&procutil.Process{ + // Pid doesn't matter since sysprobeConfig is nil + Pid: 0, + Cmdline: args, + Comm: args[0], + }}, nil) + if len(langs) == 0 { + return "" } -} - -// Finder allows to detect the language for a given process. -type Finder struct { - Logger *zap.Logger - Matchers []Matcher -} - -func (lf Finder) findLang(pi ProcessInfo) Language { - lang := FindInArgs(pi.Args) - lf.Logger.Debug("language found", zap.Any("lang", lang)) - // if we can't figure out a language from the command line, try alternate methods - if lang == "" { - lf.Logger.Debug("trying alternate methods") - for _, matcher := range lf.Matchers { - if matcher.Match(pi) { - lf.Logger.Debug(fmt.Sprintf("%T matched", matcher)) - lang = matcher.Language() - break - } - } + lang := langs[0] + if lang == nil { + return "" + } + if outLang, ok := languageNameToLanguageMap[lang.Name]; ok { + return outLang } - return lang + + return "" } -// FindInArgs trys to detect the language only using the provided command line arguments. -func FindInArgs(args []string) Language { - // empty slice passed in - if len(args) == 0 { +// FindUsingPrivilegedDetector tries to detect the language using the provided command line arguments +func FindUsingPrivilegedDetector(detector privileged.LanguageDetector, pid int32) Language { + langs := detector.DetectWithPrivileges([]languagemodels.Process{&procutil.Process{Pid: pid}}) + if len(langs) == 0 { return "" } - for i := 0; i < len(args); i++ { - procName := path.Base(args[i]) - // if procName is a known language, return the pos and the language - if lang, ok := procToLanguage[procName]; ok { - return lang - } + + lang := langs[0] + if outLang, ok := languageNameToLanguageMap[lang.Name]; ok { + return outLang } + return "" } diff --git a/pkg/collector/corechecks/servicediscovery/language/language_nix_test.go b/pkg/collector/corechecks/servicediscovery/language/language_nix_test.go index 96c2b0e1fb1f0..34de49f0d7ae1 100644 --- a/pkg/collector/corechecks/servicediscovery/language/language_nix_test.go +++ b/pkg/collector/corechecks/servicediscovery/language/language_nix_test.go @@ -3,39 +3,20 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build !windows +//go:build linux package language import ( "os" + "os/exec" "strings" "testing" - "go.uber.org/zap" -) + "github.com/stretchr/testify/require" -func TestNew(t *testing.T) { - f := New(zap.NewNop()) - // make sure all alternatives are registered - if f.Logger == nil { - t.Error("Logger is nil") - } - count := 0 - for _, v := range f.Matchers { - switch v.(type) { - case PythonScript: - count |= 1 - case RubyScript: - count |= 2 - case DotNetBinary: - count |= 4 - } - } - if count != 7 { - t.Error("Missing a matcher") - } -} + "github.com/DataDog/datadog-agent/pkg/languagedetection/privileged" +) func Test_findInArgs(t *testing.T) { data := []struct { @@ -58,11 +39,6 @@ func Test_findInArgs(t *testing.T) { args: strings.Split("/usr/bin/java -jar MyApp.jar MyApp", " "), lang: Java, }, - { - name: "extra_commands_path_java", - args: strings.Split("time /usr/bin/java -jar MyApp.jar MyApp", " "), - lang: Java, - }, { name: "just_command", args: strings.Split("./mybinary arg1 arg2 arg3", " "), @@ -79,156 +55,35 @@ func Test_findInArgs(t *testing.T) { } } -func TestFinder_findLang(t *testing.T) { - f := New(zap.NewNop()) - data := []struct { - name string - pi ProcessInfo - lang Language - }{ - { - name: "dotnet binary", - pi: ProcessInfo{ - Args: strings.Split("testdata/dotnet/linuxdotnettest a b c", " "), - Envs: []string{"PATH=/usr/bin"}, - }, - lang: DotNet, - }, - { - name: "dotnet", - pi: ProcessInfo{ - Args: strings.Split("dotnet run mydll.dll a b c", " "), - Envs: []string{"PATH=/usr/bin"}, - }, - lang: DotNet, - }, - { - name: "native", - pi: ProcessInfo{ - Args: strings.Split("./myproc a b c", " "), - Envs: []string{"PATH=/usr/bin"}, - }, - lang: "", - }, - } - for _, d := range data { - t.Run(d.name, func(t *testing.T) { - result := f.findLang(d.pi) - if result != d.lang { - t.Errorf("got %v, want %v", result, d.lang) - } - }) - } -} +func TestFindUsingPrivilegedDetector(t *testing.T) { + cmd := exec.Command("sh", "-c", "sleep -n 20") + require.NoError(t, cmd.Start()) + t.Cleanup(func() { + _ = cmd.Process.Kill() + }) -func TestProcessInfoFileReader(t *testing.T) { - // create a temp file - tempDir := t.TempDir() - fullPath := tempDir + "/" + "my_file" - err := os.WriteFile(fullPath, []byte("hello"), 0600) - if err != nil { - t.Fatal(err) - } - data := []struct { - name string - args []string - envs []string - success bool - }{ - { - name: "full", - args: []string{fullPath}, - envs: []string{"PATH=" + tempDir}, - success: true, - }, - { - name: "full_missing", - args: []string{tempDir + "/" + "not_my_file"}, - envs: []string{"PATH=" + tempDir}, - success: false, - }, - { - name: "relative_in_path", - args: []string{"my_file"}, - envs: []string{"PATH=" + tempDir}, - success: true, - }, - { - name: "relative_in_path_missing", - args: []string{"not_my_file"}, - envs: []string{"PATH=" + tempDir}, - success: false, - }, - { - name: "relative_not_in_path", - args: []string{"testdata/dotnet/linuxdotnettest"}, - envs: []string{"PATH=" + tempDir}, - success: true, - }, - { - name: "relative_not_in_path_missing", - args: []string{"testdata/dotnet/not_my_file"}, - envs: []string{"PATH=" + tempDir}, - success: false, - }, - } - for _, d := range data { - t.Run(d.name, func(t *testing.T) { - pi := ProcessInfo{ - Args: d.args, - Envs: d.envs, - } - rc, ok := pi.FileReader() - if ok != d.success { - t.Errorf("got %v, want %v", ok, d.success) - } - if rc != nil { - rc.Close() - } - }) - } -} - -func TestFinderDetect(t *testing.T) { - f := New(zap.NewNop()) data := []struct { name string - args []string - envs []string - lang Language - ok bool + pid int32 + res Language }{ { - name: "dotnet binary", - args: strings.Split("testdata/dotnet/linuxdotnettest a b c", " "), - envs: []string{"PATH=/usr/bin"}, - lang: DotNet, - ok: true, + name: "current proc", + pid: int32(os.Getpid()), + res: Go, }, { - name: "dotnet", - args: strings.Split("dotnet run mydll.dll a b c", " "), - envs: []string{"PATH=/usr/bin"}, - lang: DotNet, - ok: true, - }, - { - name: "native", - args: strings.Split("./myproc a b c", " "), - envs: []string{"PATH=/usr/bin"}, - lang: Unknown, - ok: false, + name: "not go", + pid: int32(cmd.Process.Pid), + res: "", }, } for _, d := range data { t.Run(d.name, func(t *testing.T) { - result, ok := f.Detect(d.args, d.envs) - if ok != d.ok { - t.Errorf("got %v, want %v", ok, d.ok) - } - if result != d.lang { - t.Errorf("got %v, want %v", result, d.lang) - } + detector := privileged.NewLanguageDetector() + lang := FindUsingPrivilegedDetector(detector, d.pid) + + require.Equal(t, d.res, lang) }) } } diff --git a/pkg/collector/corechecks/servicediscovery/language/language_processors.go b/pkg/collector/corechecks/servicediscovery/language/language_processors.go deleted file mode 100644 index be03acd49d1f6..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/language/language_processors.go +++ /dev/null @@ -1,89 +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 2016-present Datadog, Inc. - -package language - -import ( - "bytes" - "errors" - "io" - - "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/language/reader" -) - -func hasScript(r io.Reader, name string) bool { - buf := make([]byte, 512) - i, err := r.Read(buf) - buf = buf[:i] - if err != nil && !errors.Is(err, io.EOF) { - return false - } - if !bytes.HasPrefix(buf, []byte{'#', '!'}) { - return false - } - // clamp to first line - pos := bytes.IndexByte(buf, '\n') - if pos != -1 { - buf = buf[:pos] - } - return bytes.Contains(buf, []byte(name)) -} - -// PythonScript is a Matcher for Python. -type PythonScript struct{} - -// Match returns true if the language of the process is Python. -func (PythonScript) Match(pi ProcessInfo) bool { - f, found := pi.FileReader() - if !found { - return false - } - defer f.Close() - return hasScript(f, "python") -} - -// Language returns the Language of the launching process -func (PythonScript) Language() Language { - return Python -} - -// RubyScript is a Matcher for Ruby. -type RubyScript struct{} - -// Match returns true if the language of the process is Ruby. -func (RubyScript) Match(pi ProcessInfo) bool { - f, found := pi.FileReader() - if !found { - return false - } - defer f.Close() - return hasScript(f, "ruby") -} - -// Language returns the Language of the launching process -func (RubyScript) Language() Language { - return Ruby -} - -// DotNetBinary is a Matcher for DotNet. -type DotNetBinary struct{} - -// Match returns true if the language of the process is DotNet. -func (DotNetBinary) Match(pi ProcessInfo) bool { - f, found := pi.FileReader() - if !found { - return false - } - defer f.Close() - // scan the binary to see if it's a .net binary - // as far as I know, all .net binaries have the string "DOTNET_ROOT" in them - offset, err := reader.Index(f, "DOTNET_ROOT") - return offset > -1 && err == nil -} - -// Language returns the Language of the launching process -func (DotNetBinary) Language() Language { - return DotNet -} diff --git a/pkg/collector/corechecks/servicediscovery/language/language_processors_test.go b/pkg/collector/corechecks/servicediscovery/language/language_processors_test.go deleted file mode 100644 index 19925b2073079..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/language/language_processors_test.go +++ /dev/null @@ -1,154 +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 2016-present Datadog, Inc. - -package language - -import ( - "os" - "testing" -) - -func Test_hasScript(t *testing.T) { - data := []struct { - name string - file string - want bool - }{ - { - name: "works", - file: "yes_script.sh", - want: true, - }, - { - name: "fails", - file: "not_a_script.txt", - want: false, - }, - } - for _, d := range data { - t.Run(d.name, func(t *testing.T) { - r, err := os.Open("testdata/hasScript/" + d.file) - if err != nil { - t.Fatal(err) - } - defer r.Close() - result := hasScript(r, "bash") - if result != d.want { - t.Errorf("got %t, want %t", result, d.want) - } - }) - } -} - -func TestPythonScript(t *testing.T) { - p := PythonScript{} - if p.Language() != Python { - t.Errorf("got %s, want %s", p.Language(), Python) - } - data := []struct { - name string - pi ProcessInfo - want bool - }{ - { - name: "works", - pi: ProcessInfo{ - Args: []string{"testdata/python/yes_script.sh"}, - Envs: []string{"PATH=/usr/bin"}, - }, - want: true, - }, - { - name: "fails", - pi: ProcessInfo{ - Args: []string{"testdata/python/not_a_script.sh"}, - Envs: []string{"PATH=/usr/bin"}, - }, - want: false, - }, - } - for _, d := range data { - t.Run(d.name, func(t *testing.T) { - found := p.Match(d.pi) - if found != d.want { - t.Errorf("got %t, want %t", found, d.want) - } - }) - } -} - -func TestRubyScript(t *testing.T) { - p := RubyScript{} - if p.Language() != Ruby { - t.Errorf("got %s, want %s", p.Language(), Ruby) - } - data := []struct { - name string - pi ProcessInfo - want bool - }{ - { - name: "works", - pi: ProcessInfo{ - Args: []string{"testdata/ruby/yes_script.sh"}, - Envs: []string{"PATH=/usr/bin"}, - }, - want: true, - }, - { - name: "fails", - pi: ProcessInfo{ - Args: []string{"testdata/ruby/not_a_script.sh"}, - Envs: []string{"PATH=/usr/bin"}, - }, - want: false, - }, - } - for _, d := range data { - t.Run(d.name, func(t *testing.T) { - found := p.Match(d.pi) - if found != d.want { - t.Errorf("got %t, want %t", found, d.want) - } - }) - } -} - -func TestDotNetBinary(t *testing.T) { - p := DotNetBinary{} - if p.Language() != DotNet { - t.Errorf("got %s, want %s", p.Language(), DotNet) - } - data := []struct { - name string - pi ProcessInfo - want bool - }{ - { - name: "works", - pi: ProcessInfo{ - Args: []string{"testdata/dotnet/linuxdotnettest"}, - Envs: []string{"PATH=/usr/bin"}, - }, - want: true, - }, - { - name: "fails", - pi: ProcessInfo{ - Args: []string{"testdata/dotnet/not_a_script.sh"}, - Envs: []string{"PATH=/usr/bin"}, - }, - want: false, - }, - } - for _, d := range data { - t.Run(d.name, func(t *testing.T) { - found := p.Match(d.pi) - if found != d.want { - t.Errorf("got %t, want %t", found, d.want) - } - }) - } -} diff --git a/pkg/collector/corechecks/servicediscovery/language/testdata/dotnet/linuxdotnettest b/pkg/collector/corechecks/servicediscovery/language/testdata/dotnet/linuxdotnettest deleted file mode 100644 index eb576c9bda92b..0000000000000 Binary files a/pkg/collector/corechecks/servicediscovery/language/testdata/dotnet/linuxdotnettest and /dev/null differ diff --git a/pkg/collector/corechecks/servicediscovery/language/testdata/dotnet/not_a_script.txt b/pkg/collector/corechecks/servicediscovery/language/testdata/dotnet/not_a_script.txt deleted file mode 100644 index bf4ad98da26bc..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/language/testdata/dotnet/not_a_script.txt +++ /dev/null @@ -1 +0,0 @@ -I am not a .net executable. \ No newline at end of file diff --git a/pkg/collector/corechecks/servicediscovery/language/testdata/hasScript/not_a_script.txt b/pkg/collector/corechecks/servicediscovery/language/testdata/hasScript/not_a_script.txt deleted file mode 100644 index 95ee8a995ed72..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/language/testdata/hasScript/not_a_script.txt +++ /dev/null @@ -1,2 +0,0 @@ -I am not a shell script -But I have the word bash in me diff --git a/pkg/collector/corechecks/servicediscovery/language/testdata/hasScript/yes_script.sh b/pkg/collector/corechecks/servicediscovery/language/testdata/hasScript/yes_script.sh deleted file mode 100644 index b77d509d63261..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/language/testdata/hasScript/yes_script.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -echo "Hello, world!" \ No newline at end of file diff --git a/pkg/collector/corechecks/servicediscovery/language/testdata/python/not_a_script.txt b/pkg/collector/corechecks/servicediscovery/language/testdata/python/not_a_script.txt deleted file mode 100644 index 7ea400d9f11e8..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/language/testdata/python/not_a_script.txt +++ /dev/null @@ -1,2 +0,0 @@ -I am not a shell script -But I have the word python in me diff --git a/pkg/collector/corechecks/servicediscovery/language/testdata/python/yes_script.sh b/pkg/collector/corechecks/servicediscovery/language/testdata/python/yes_script.sh deleted file mode 100644 index 54b8bbc2cade9..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/language/testdata/python/yes_script.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env python - -print("hello, world") \ No newline at end of file diff --git a/pkg/collector/corechecks/servicediscovery/language/testdata/ruby/not_a_script.txt b/pkg/collector/corechecks/servicediscovery/language/testdata/ruby/not_a_script.txt deleted file mode 100644 index d20c4efe62e5a..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/language/testdata/ruby/not_a_script.txt +++ /dev/null @@ -1,2 +0,0 @@ -I am not a shell script -But I have the word ruby in me diff --git a/pkg/collector/corechecks/servicediscovery/language/testdata/ruby/yes_script.sh b/pkg/collector/corechecks/servicediscovery/language/testdata/ruby/yes_script.sh deleted file mode 100644 index c5ff8c742a1c4..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/language/testdata/ruby/yes_script.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby - -print("hello, world\n") \ No newline at end of file diff --git a/pkg/collector/corechecks/servicediscovery/model/model.go b/pkg/collector/corechecks/servicediscovery/model/model.go index 3f80ea27aded1..2c27e9e1379c9 100644 --- a/pkg/collector/corechecks/servicediscovery/model/model.go +++ b/pkg/collector/corechecks/servicediscovery/model/model.go @@ -8,9 +8,12 @@ package model // Service represents a listening process. type Service struct { - PID int `json:"pid"` - Name string `json:"name"` - Ports []uint16 `json:"ports"` + PID int `json:"pid"` + Name string `json:"name"` + NameSource string `json:"name_source"` + Ports []uint16 `json:"ports"` + APMInstrumentation string `json:"apm_instrumentation"` + Language string `json:"language"` } // ServicesResponse is the response for the system-probe /discovery/services endpoint. diff --git a/pkg/collector/corechecks/servicediscovery/module/envs.go b/pkg/collector/corechecks/servicediscovery/module/envs.go new file mode 100644 index 0000000000000..08f5c54994565 --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/module/envs.go @@ -0,0 +1,115 @@ +// 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 2024-present Datadog, Inc. + +//go:build linux + +package module + +import ( + "io" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/DataDog/datadog-agent/pkg/util/kernel" + "github.com/shirou/gopsutil/v3/process" +) + +const ( + // injectorMemFdName is the name the injector (Datadog/auto_inject) uses. + injectorMemFdName = "dd_environ" + injectorMemFdPath = "/memfd:" + injectorMemFdName + " (deleted)" + + // memFdMaxSize is used to limit the amount of data we read from the memfd. + // This is for safety to limit our memory usage in the case of a corrupt + // file. + memFdMaxSize = 4096 +) + +// readEnvsFile reads the env file created by the auto injector. The file +// contains the variables in a format similar to /proc/$PID/environ: ENV=VAL, +// separated by \000. +func readEnvsFile(path string) ([]string, error) { + reader, err := os.Open(path) + if err != nil { + return nil, err + } + defer reader.Close() + + data, err := io.ReadAll(io.LimitReader(reader, memFdMaxSize)) + if err != nil { + return nil, err + } + + return strings.Split(string(data), "\000"), nil +} + +// getInjectedEnvs gets environment variables injected by the auto injector, if +// present. The auto injector creates a memfd file with a specific name into which +// it writes the environment variables. In order to find the correct file, we +// need to iterate the list of files (named after file descriptor numbers) in +// /proc/$PID/fd and get the name from the target of the symbolic link. +// +// ``` +// $ ls -l /proc/1750097/fd/ +// total 0 +// lrwx------ 1 foo foo 64 Aug 13 14:24 0 -> /dev/pts/6 +// lrwx------ 1 foo foo 64 Aug 13 14:24 1 -> /dev/pts/6 +// lrwx------ 1 foo foo 64 Aug 13 14:24 2 -> /dev/pts/6 +// lrwx------ 1 foo foo 64 Aug 13 14:24 3 -> '/memfd:dd_environ (deleted)' +// ``` +func getInjectedEnvs(proc *process.Process) []string { + fdsPath := kernel.HostProc(strconv.Itoa(int(proc.Pid)), "fd") + entries, err := os.ReadDir(fdsPath) + if err != nil { + return nil + } + + for _, entry := range entries { + path := filepath.Join(fdsPath, entry.Name()) + name, err := os.Readlink(path) + if err != nil { + continue + } + + if name != injectorMemFdPath { + continue + } + + envs, _ := readEnvsFile(path) + return envs + } + + return nil +} + +// envsToMap splits a list of strings containing environment variables of the +// format NAME=VAL to a map. +func envsToMap(envs ...string) map[string]string { + envMap := make(map[string]string, len(envs)) + for _, env := range envs { + name, val, found := strings.Cut(env, "=") + if !found { + continue + } + + envMap[name] = val + } + + return envMap +} + +// getEnvs gets the environment variables for the process, both the initial +// ones, and if present, the ones injected via the auto injector. +func getEnvs(proc *process.Process) (map[string]string, error) { + envs, err := proc.Environ() + if err != nil { + return nil, err + } + + envs = append(envs, getInjectedEnvs(proc)...) + return envsToMap(envs...), nil +} diff --git a/pkg/collector/corechecks/servicediscovery/module/envs_test.go b/pkg/collector/corechecks/servicediscovery/module/envs_test.go new file mode 100644 index 0000000000000..7ef168b963f67 --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/module/envs_test.go @@ -0,0 +1,109 @@ +// 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 2024-present Datadog, Inc. + +//go:build linux + +package module + +import ( + "bytes" + "fmt" + "os" + "strings" + "testing" + + "github.com/shirou/gopsutil/v3/process" + "github.com/stretchr/testify/require" + "golang.org/x/sys/unix" +) + +func TestInjectedEnvBasic(t *testing.T) { + curPid := os.Getpid() + proc, err := process.NewProcess(int32(curPid)) + require.NoError(t, err) + envs := getInjectedEnvs(proc) + require.Nil(t, envs) + + // Provide an injected replacement for some already-present env variable + first := os.Environ()[0] + parts := strings.Split(first, "=") + key := parts[0] + + expected := []string{"key1=val1", "key2=val2", "key3=val3", fmt.Sprint(key, "=", "new")} + createEnvsMemfd(t, expected) + + envMap, err := getEnvs(proc) + require.NoError(t, err) + require.Subset(t, envMap, map[string]string{ + "key1": "val1", + "key2": "val2", + "key3": "val3", + key: "new", + }) +} + +func TestInjectedEnvLimit(t *testing.T) { + env := "A=" + strings.Repeat("A", memFdMaxSize*2) + full := []string{env} + createEnvsMemfd(t, full) + + expected := []string{full[0][:memFdMaxSize]} + + proc, err := process.NewProcess(int32(os.Getpid())) + require.NoError(t, err) + envs := getInjectedEnvs(proc) + require.Equal(t, expected, envs) +} + +// createEnvsMemfd creates an memfd in the current process with the specified +// environment variables in the same way as Datadog/auto_inject. +func createEnvsMemfd(t *testing.T, envs []string) { + t.Helper() + + var b bytes.Buffer + for _, env := range envs { + _, err := b.WriteString(env) + require.NoError(t, err) + + err = b.WriteByte(0) + require.NoError(t, err) + } + + memfd, err := memfile(injectorMemFdName, b.Bytes()) + require.NoError(t, err) + t.Cleanup(func() { unix.Close(memfd) }) +} + +// memfile takes a file name used, and the byte slice containing data the file +// should contain. +// +// name does not need to be unique, as it's used only for debugging purposes. +// +// It is up to the caller to close the returned descriptor. +func memfile(name string, b []byte) (int, error) { + fd, err := unix.MemfdCreate(name, 0) + if err != nil { + return 0, fmt.Errorf("MemfdCreate: %v", err) + } + + err = unix.Ftruncate(fd, int64(len(b))) + if err != nil { + return 0, fmt.Errorf("Ftruncate: %v", err) + } + + data, err := unix.Mmap(fd, 0, len(b), unix.PROT_READ|unix.PROT_WRITE, unix.MAP_SHARED) + if err != nil { + return 0, fmt.Errorf("Mmap: %v", err) + } + + copy(data, b) + + err = unix.Munmap(data) + if err != nil { + return 0, fmt.Errorf("Munmap: %v", err) + } + + return fd, nil +} diff --git a/pkg/collector/corechecks/servicediscovery/module/impl_linux.go b/pkg/collector/corechecks/servicediscovery/module/impl_linux.go index 02570487f41c1..6adc5982fed4e 100644 --- a/pkg/collector/corechecks/servicediscovery/module/impl_linux.go +++ b/pkg/collector/corechecks/servicediscovery/module/impl_linux.go @@ -14,17 +14,18 @@ import ( "github.com/prometheus/procfs" "github.com/shirou/gopsutil/v3/process" - "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery" - "github.com/DataDog/datadog-agent/cmd/system-probe/api/module" sysconfigtypes "github.com/DataDog/datadog-agent/cmd/system-probe/config/types" "github.com/DataDog/datadog-agent/cmd/system-probe/utils" "github.com/DataDog/datadog-agent/comp/core/telemetry" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery" + "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/apm" + "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/language" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/model" + "github.com/DataDog/datadog-agent/pkg/languagedetection/privileged" "github.com/DataDog/datadog-agent/pkg/util/kernel" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) const ( @@ -34,24 +35,29 @@ const ( // Ensure discovery implements the module.Module interface. var _ module.Module = &discovery{} -// cacheData holds process data that should be cached between calls to the +// serviceInfo holds process data that should be cached between calls to the // endpoint. -type cacheData struct { - serviceName string +type serviceInfo struct { + name string + nameFromDDService bool + language language.Language + apmInstrumentation apm.Instrumentation } // discovery is an implementation of the Module interface for the discovery module. type discovery struct { // cache maps pids to data that should be cached between calls to the endpoint. - cache map[int32]cacheData - serviceDetector servicediscovery.ServiceDetector + cache map[int32]*serviceInfo + + // privilegedDetector is used to detect the language of a process. + privilegedDetector privileged.LanguageDetector } // NewDiscoveryModule creates a new discovery system probe module. -func NewDiscoveryModule(*sysconfigtypes.Config, optional.Option[workloadmeta.Component], telemetry.Component) (module.Module, error) { +func NewDiscoveryModule(*sysconfigtypes.Config, workloadmeta.Component, telemetry.Component) (module.Module, error) { return &discovery{ - cache: make(map[int32]cacheData), - serviceDetector: *servicediscovery.NewServiceDetector(), + cache: make(map[int32]*serviceInfo), + privilegedDetector: privileged.NewLanguageDetector(), }, nil } @@ -199,20 +205,33 @@ type parsingContext struct { netNsInfo map[uint32]*namespaceInfo } -// getServiceName gets the service name for a process using the servicedetector -// module. -func (s *discovery) getServiceName(proc *process.Process) (string, error) { +// getServiceInfo gets the service information for a process using the +// servicedetector module. +func (s *discovery) getServiceInfo(proc *process.Process) (*serviceInfo, error) { cmdline, err := proc.CmdlineSlice() if err != nil { - return "", nil + return nil, err } - env, err := proc.Environ() + envs, err := getEnvs(proc) if err != nil { - return "", nil + return nil, err } - return s.serviceDetector.GetServiceName(cmdline, env), nil + root := kernel.HostProc(strconv.Itoa(int(proc.Pid)), "root") + name, fromDDService := servicediscovery.GetServiceName(cmdline, envs, root) + lang := language.FindInArgs(cmdline) + if lang == "" { + lang = language.FindUsingPrivilegedDetector(s.privilegedDetector, proc.Pid) + } + apmInstrumentation := apm.Detect(int(proc.Pid), cmdline, envs, lang) + + return &serviceInfo{ + name: name, + language: lang, + apmInstrumentation: apmInstrumentation, + nameFromDDService: fromDDService, + }, nil } // getService gets information for a single service. @@ -267,22 +286,30 @@ func (s *discovery) getService(context parsingContext, pid int32) *model.Service return nil } - var serviceName string + var info *serviceInfo if cached, ok := s.cache[pid]; ok { - serviceName = cached.serviceName + info = cached } else { - serviceName, err = s.getServiceName(proc) + info, err = s.getServiceInfo(proc) if err != nil { return nil } - s.cache[pid] = cacheData{serviceName: serviceName} + s.cache[pid] = info + } + + nameSource := "generated" + if info.nameFromDDService { + nameSource = "provided" } return &model.Service{ - PID: int(pid), - Name: serviceName, - Ports: ports, + PID: int(pid), + Name: info.name, + NameSource: nameSource, + Ports: ports, + APMInstrumentation: string(info.apmInstrumentation), + Language: string(info.language), } } diff --git a/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go b/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go index 8b50fb3988507..1bae866b28862 100644 --- a/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go +++ b/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go @@ -17,8 +17,10 @@ import ( "net/http" "os" "os/exec" + "path/filepath" "regexp" "runtime" + "strings" "syscall" "testing" "time" @@ -27,6 +29,7 @@ import ( gorillamux "github.com/gorilla/mux" "github.com/prometheus/procfs" + "github.com/shirou/gopsutil/v3/process" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/vishvananda/netns" @@ -34,17 +37,27 @@ import ( "github.com/DataDog/datadog-agent/cmd/system-probe/api/module" "github.com/DataDog/datadog-agent/cmd/system-probe/config" "github.com/DataDog/datadog-agent/cmd/system-probe/config/types" + "github.com/DataDog/datadog-agent/comp/core" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + wmmock "github.com/DataDog/datadog-agent/comp/core/workloadmeta/fx-mock" + "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/apm" + "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/language" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/model" "github.com/DataDog/datadog-agent/pkg/network/protocols/http/testutil" protocolUtils "github.com/DataDog/datadog-agent/pkg/network/protocols/testutil" - "github.com/DataDog/datadog-agent/pkg/util/optional" + "github.com/DataDog/datadog-agent/pkg/network/protocols/tls/nodejs" + fileopener "github.com/DataDog/datadog-agent/pkg/network/usm/sharedlibraries/testutil" + usmtestutil "github.com/DataDog/datadog-agent/pkg/network/usm/testutil" + "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) func setupDiscoveryModule(t *testing.T) string { t.Helper() - wmeta := optional.NewNoneOption[workloadmeta.Component]() + wmeta := fxutil.Test[workloadmeta.Component](t, + core.MockBundle(), + wmmock.MockModule(workloadmeta.NewParams()), + ) mux := gorillamux.NewRouter() cfg := &types.Config{ Enabled: true, @@ -278,7 +291,9 @@ func TestServiceName(t *testing.T) { cmd := exec.CommandContext(ctx, "sleep", "1000") cmd.Dir = "/tmp/" + cmd.Env = append(cmd.Env, "OTHER_ENV=test") cmd.Env = append(cmd.Env, "DD_SERVICE=foobar") + cmd.Env = append(cmd.Env, "YET_OTHER_ENV=test") err = cmd.Start() require.NoError(t, err) f.Close() @@ -289,6 +304,233 @@ func TestServiceName(t *testing.T) { portMap := getServicesMap(t, url) assert.Contains(collect, portMap, pid) assert.Equal(t, "foobar", portMap[pid].Name) + assert.Equal(t, "provided", portMap[pid].NameSource) + }, 30*time.Second, 100*time.Millisecond) +} + +func TestInjectedServiceName(t *testing.T) { + url := setupDiscoveryModule(t) + + createEnvsMemfd(t, []string{ + "OTHER_ENV=test", + "DD_SERVICE=injected-service-name", + "DD_INJECTION_ENABLED=service_name", + "YET_ANOTHER_ENV=test", + }) + + listener, err := net.Listen("tcp", "") + require.NoError(t, err) + t.Cleanup(func() { listener.Close() }) + + pid := os.Getpid() + portMap := getServicesMap(t, url) + require.Contains(t, portMap, pid) + require.Equal(t, "injected-service-name", portMap[pid].Name) + require.Equal(t, "generated", portMap[pid].NameSource) +} + +func TestAPMInstrumentationInjected(t *testing.T) { + url := setupDiscoveryModule(t) + + createEnvsMemfd(t, []string{ + "DD_INJECTION_ENABLED=service_name,tracer", + }) + + listener, err := net.Listen("tcp", "") + require.NoError(t, err) + t.Cleanup(func() { listener.Close() }) + + pid := os.Getpid() + portMap := getServicesMap(t, url) + require.Contains(t, portMap, pid) + require.Equal(t, string(apm.Injected), portMap[pid].APMInstrumentation) +} + +func makeAlias(t *testing.T, alias string, serverBin string) string { + binDir := filepath.Dir(serverBin) + aliasPath := filepath.Join(binDir, alias) + + target, err := os.Readlink(aliasPath) + if err == nil && target == serverBin { + return aliasPath + } + + os.Remove(aliasPath) + err = os.Symlink(serverBin, aliasPath) + require.NoError(t, err) + + return aliasPath +} + +func buildFakeServer(t *testing.T) string { + curDir, err := testutil.CurDir() + require.NoError(t, err) + serverBin, err := usmtestutil.BuildGoBinaryWrapper(filepath.Join(curDir, "testutil"), "fake_server") + require.NoError(t, err) + + for _, alias := range []string{"java", "node"} { + makeAlias(t, alias, serverBin) + } + + return filepath.Dir(serverBin) +} + +func TestPythonFromBashScript(t *testing.T) { + curDir, err := testutil.CurDir() + require.NoError(t, err) + pythonScriptPath := filepath.Join(curDir, "testdata", "script.py") + + t.Run("PythonFromBashScript", func(t *testing.T) { + testCaptureWrappedCommands(t, pythonScriptPath, []string{"sh", "-c"}, func(service model.Service) bool { + return service.Language == string(language.Python) + }) + }) + t.Run("DirectPythonScript", func(t *testing.T) { + testCaptureWrappedCommands(t, pythonScriptPath, nil, func(service model.Service) bool { + return service.Language == string(language.Python) + }) + }) +} + +func testCaptureWrappedCommands(t *testing.T, script string, commandWrapper []string, validator func(service model.Service) bool) { + // Changing permissions + require.NoError(t, os.Chmod(script, 0755)) + + commandLineArgs := append(commandWrapper, script) + cmd := exec.Command(commandLineArgs[0], commandLineArgs[1:]...) + // Running the binary in the background + require.NoError(t, cmd.Start()) + + var proc *process.Process + var err error + require.EventuallyWithT(t, func(collect *assert.CollectT) { + proc, err = process.NewProcess(int32(cmd.Process.Pid)) + assert.NoError(collect, err) + }, 10*time.Second, 100*time.Millisecond) + + cmdline, err := proc.Cmdline() + require.NoError(t, err) + // If we wrap the script with `sh -c`, we can have differences between a local run and a kmt run, as for + // kmt `sh` is symbolic link to bash, while locally it can be a symbolic link to dash. In the dash case, we will + // see 2 processes `sh -c script.py` and a sub-process `python3 script.py`, while in the bash case we will see + // only `python3 script.py`. We need to check for the command line arguments of the process to make sure we + // are looking at the right process. + if cmdline == strings.Join(commandLineArgs, " ") && len(commandWrapper) > 0 { + var children []*process.Process + require.EventuallyWithT(t, func(collect *assert.CollectT) { + children, err = proc.Children() + assert.NoError(collect, err) + assert.Len(collect, children, 1) + }, 10*time.Second, 100*time.Millisecond) + proc = children[0] + } + t.Cleanup(func() { _ = proc.Kill() }) + + url := setupDiscoveryModule(t) + pid := int(proc.Pid) + require.EventuallyWithT(t, func(collect *assert.CollectT) { + svcMap := getServicesMap(t, url) + assert.Contains(collect, svcMap, pid) + assert.True(collect, validator(svcMap[pid])) + }, 30*time.Second, 100*time.Millisecond) +} + +func TestAPMInstrumentationProvided(t *testing.T) { + curDir, err := testutil.CurDir() + assert.NoError(t, err) + + testCases := map[string]struct { + commandline []string // The command line of the fake server + workingDirectory string // Optional: The working directory to use for the server. + language language.Language + }{ + "java": { + commandline: []string{"java", "-javaagent:/path/to/dd-java-agent.jar", "-jar", "foo.jar"}, + language: language.Java, + }, + "node": { + commandline: []string{"node"}, + workingDirectory: filepath.Join(curDir, "testdata"), + language: language.Node, + }, + } + + serverDir := buildFakeServer(t) + url := setupDiscoveryModule(t) + + for name, test := range testCases { + t.Run(name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + t.Cleanup(func() { cancel() }) + + bin := filepath.Join(serverDir, test.commandline[0]) + cmd := exec.CommandContext(ctx, bin, test.commandline[1:]...) + cmd.Dir = test.workingDirectory + err := cmd.Start() + require.NoError(t, err) + + pid := cmd.Process.Pid + + require.EventuallyWithT(t, func(collect *assert.CollectT) { + portMap := getServicesMap(t, url) + assert.Contains(collect, portMap, pid) + assert.Equal(collect, string(test.language), portMap[pid].Language) + assert.Equal(collect, string(apm.Provided), portMap[pid].APMInstrumentation) + }, 30*time.Second, 100*time.Millisecond) + }) + } +} + +func TestNodeDocker(t *testing.T) { + cert, key, err := testutil.GetCertsPaths() + require.NoError(t, err) + + require.NoError(t, nodejs.RunServerNodeJS(t, key, cert, "4444")) + nodeJSPID, err := nodejs.GetNodeJSDockerPID() + require.NoError(t, err) + + url := setupDiscoveryModule(t) + pid := int(nodeJSPID) + + require.EventuallyWithT(t, func(collect *assert.CollectT) { + svcMap := getServicesMap(t, url) + assert.Contains(collect, svcMap, pid) + assert.Equal(collect, "nodejs-https-server", svcMap[pid].Name) + }, 30*time.Second, 100*time.Millisecond) +} + +func TestAPMInstrumentationProvidedPython(t *testing.T) { + curDir, err := testutil.CurDir() + require.NoError(t, err) + + fmapper := fileopener.BuildFmapper(t) + fakePython := makeAlias(t, "python", fmapper) + + // We need the process to map something in a directory called + // "site-packages/ddtrace". The actual mapped file does not matter. + ddtrace := filepath.Join(curDir, "..", "..", "..", "..", "network", "usm", "testdata", "site-packages", "ddtrace") + lib := filepath.Join(ddtrace, fmt.Sprintf("libssl.so.%s", runtime.GOARCH)) + + // Give the process a listening socket + listener, err := net.Listen("tcp", "") + require.NoError(t, err) + f, err := listener.(*net.TCPListener).File() + listener.Close() + require.NoError(t, err) + t.Cleanup(func() { f.Close() }) + disableCloseOnExec(t, f) + + cmd, err := fileopener.OpenFromProcess(t, fakePython, lib) + require.NoError(t, err) + + url := setupDiscoveryModule(t) + + pid := cmd.Process.Pid + require.EventuallyWithT(t, func(collect *assert.CollectT) { + portMap := getServicesMap(t, url) + assert.Contains(collect, portMap, pid) + assert.Equal(collect, string(language.Python), portMap[pid].Language) + assert.Equal(collect, string(apm.Provided), portMap[pid].APMInstrumentation) }, 30*time.Second, 100*time.Millisecond) } @@ -390,7 +632,11 @@ func TestDocker(t *testing.T) { // Check that the cache is cleaned when procceses die. func TestCache(t *testing.T) { - module, err := NewDiscoveryModule(nil, optional.NewNoneOption[workloadmeta.Component](), nil) + wmeta := fxutil.Test[workloadmeta.Component](t, + core.MockBundle(), + wmmock.MockModule(workloadmeta.NewParams()), + ) + module, err := NewDiscoveryModule(nil, wmeta, nil) require.NoError(t, err) discovery := module.(*discovery) @@ -430,7 +676,8 @@ func TestCache(t *testing.T) { for i, cmd := range cmds { pid := int32(cmd.Process.Pid) - require.Contains(t, discovery.cache[pid].serviceName, serviceNames[i]) + require.Contains(t, discovery.cache[pid].name, serviceNames[i]) + require.True(t, discovery.cache[pid].nameFromDDService) } cancel() diff --git a/pkg/collector/corechecks/servicediscovery/module/testdata/package.json b/pkg/collector/corechecks/servicediscovery/module/testdata/package.json new file mode 100644 index 0000000000000..bdf13a51c6498 --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/module/testdata/package.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "bar": ">=1.9.0", + "dd-trace": "9.99.9", + "foo": "1.0.1" + } +} diff --git a/pkg/collector/corechecks/servicediscovery/module/testdata/script.py b/pkg/collector/corechecks/servicediscovery/module/testdata/script.py new file mode 100755 index 0000000000000..bf4c3e02912c5 --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/module/testdata/script.py @@ -0,0 +1,12 @@ +#! /usr/bin/env python3 + +import socket +import time + +HOST = '127.0.0.1' +PORT = 0 # Empty port + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.bind((HOST, PORT)) +s.listen() +time.sleep(30) diff --git a/pkg/collector/corechecks/servicediscovery/module/testutil/fake_server/.gitignore b/pkg/collector/corechecks/servicediscovery/module/testutil/fake_server/.gitignore new file mode 100644 index 0000000000000..0463fd64b64eb --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/module/testutil/fake_server/.gitignore @@ -0,0 +1,3 @@ +fake_server +java +node diff --git a/pkg/collector/corechecks/servicediscovery/module/testutil/fake_server/fake_server.go b/pkg/collector/corechecks/servicediscovery/module/testutil/fake_server/fake_server.go new file mode 100644 index 0000000000000..40c71c81b783b --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/module/testutil/fake_server/fake_server.go @@ -0,0 +1,31 @@ +// 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 2024-present Datadog, Inc. + +// Package main is a simple TCP server which accepts any command line arguments, +// in order to test service discovery which uses the command line for detection. +package main + +import ( + "fmt" + "net" + "os" + "os/signal" + "syscall" +) + +func main() { + listener, err := net.Listen("tcp", "") + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer listener.Close() + + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + fmt.Println("awaiting signal") + <-sigs + fmt.Println("exiting") +} diff --git a/pkg/collector/corechecks/servicediscovery/portlist/port.go b/pkg/collector/corechecks/servicediscovery/portlist/port.go deleted file mode 100644 index 3567962826afa..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/portlist/port.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2014-present Datadog, Inc. - -package portlist - -import ( - "fmt" - "sort" - "strings" -) - -// Port is a listening port on the machine. -type Port struct { - Proto string // "tcp" or "udp" - Port uint16 // port number - Process string // optional process name, if found (requires suitable permissions) - Pid int // process ID, if known (requires suitable permissions) -} - -func (a *Port) equal(b *Port) bool { - return a.Port == b.Port && - a.Proto == b.Proto && - a.Process == b.Process -} - -func (a *Port) lessThan(b *Port) bool { - if a.Port != b.Port { - return a.Port < b.Port - } - if a.Proto != b.Proto { - return a.Proto < b.Proto - } - return a.Process < b.Process -} - -// List is a list of Ports. -type List []Port - -func (pl List) String() string { - out := make([]string, len(pl)) - for i, v := range pl { - out[i] = fmt.Sprintf("[%s]%s:%d", v.Process, v.Proto, v.Port) - } - return strings.Join(out, ",") -} - -// sortAndDedup sorts ps in place (by Port.lessThan) and then returns -// a subset of it with duplicate (Proto, Port) removed. -func sortAndDedup(ps List) List { - sort.Slice(ps, func(i, j int) bool { - return (&ps[i]).lessThan(&ps[j]) - }) - out := ps[:0] - var last Port - for _, p := range ps { - if last.Proto == p.Proto && last.Port == p.Port { - continue - } - out = append(out, p) - last = p - } - return out -} diff --git a/pkg/collector/corechecks/servicediscovery/portlist/port_test.go b/pkg/collector/corechecks/servicediscovery/portlist/port_test.go deleted file mode 100644 index 6a26c6b1858c5..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/portlist/port_test.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2014-present Datadog, Inc. - -package portlist - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/google/go-cmp/cmp" -) - -func TestPortEqualLessThan(t *testing.T) { - tests := []struct { - name string - a, b Port - want bool - }{ - { - "Port a < b", - Port{Proto: "tcp", Port: 100, Process: "proc1"}, - Port{Proto: "tcp", Port: 101, Process: "proc1"}, - true, - }, - { - "Port a > b", - Port{Proto: "tcp", Port: 101, Process: "proc1"}, - Port{Proto: "tcp", Port: 100, Process: "proc1"}, - false, - }, - { - "Proto a < b", - Port{Proto: "tcp", Port: 100, Process: "proc1"}, - Port{Proto: "udp", Port: 100, Process: "proc1"}, - true, - }, - { - "Proto a < b", - Port{Proto: "udp", Port: 100, Process: "proc1"}, - Port{Proto: "tcp", Port: 100, Process: "proc1"}, - false, - }, - { - "Process a < b", - Port{Proto: "tcp", Port: 100, Process: "proc1"}, - Port{Proto: "tcp", Port: 100, Process: "proc2"}, - true, - }, - { - "Process a > b", - Port{Proto: "tcp", Port: 100, Process: "proc2"}, - Port{Proto: "tcp", Port: 100, Process: "proc1"}, - false, - }, - { - "Port evaluated first", - Port{Proto: "udp", Port: 100, Process: "proc2"}, - Port{Proto: "tcp", Port: 101, Process: "proc1"}, - true, - }, - { - "Proto evaluated second", - Port{Proto: "tcp", Port: 100, Process: "proc2"}, - Port{Proto: "udp", Port: 100, Process: "proc1"}, - true, - }, - { - "Process evaluated fourth", - Port{Proto: "tcp", Port: 100, Process: "proc1"}, - Port{Proto: "tcp", Port: 100, Process: "proc2"}, - true, - }, - { - "equal", - Port{Proto: "tcp", Port: 100, Process: "proc1"}, - Port{Proto: "tcp", Port: 100, Process: "proc1"}, - false, - }, - } - - for _, tt := range tests { - got := tt.a.lessThan(&tt.b) - assert.Equal(t, got, tt.want) - - lessBack := tt.b.lessThan(&tt.a) - if got && lessBack { - t.Errorf("%s: both a and b report being less than each other", tt.name) - } - - wantEqual := !got && !lessBack - gotEqual := tt.a.equal(&tt.b) - assert.Equal(t, gotEqual, wantEqual) - } -} - -func Test_sortAndDedup(t *testing.T) { - pl := List{ - {Proto: "tcp", Port: 100, Process: "proc1"}, - {Proto: "udp", Port: 100, Process: "proc2"}, - {Proto: "udp", Port: 100, Process: "proc2"}, - {Proto: "tcp", Port: 101, Process: "proc3"}, - } - - want := List{ - {Proto: "tcp", Port: 100, Process: "proc1"}, - {Proto: "udp", Port: 100, Process: "proc2"}, - {Proto: "tcp", Port: 101, Process: "proc3"}, - } - got := sortAndDedup(pl) - - if diff := cmp.Diff(want, got); diff != "" { - t.Errorf("sortAndDedup mismatch (-want +got):\n%s", diff) - } -} diff --git a/pkg/collector/corechecks/servicediscovery/portlist/portlist.go b/pkg/collector/corechecks/servicediscovery/portlist/portlist.go deleted file mode 100644 index 75f205f6123c5..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/portlist/portlist.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2014-present Datadog, Inc. - -// Package portlist provides functionality to fetch open ports in the current machine. -package portlist - -import ( - "errors" - "github.com/DataDog/datadog-agent/pkg/util/log" - "path/filepath" - "runtime" -) - -var ( - newOSImpl func(cfg *config) osImpl -) - -// Poller scans the systems for listening ports. -type Poller struct { - // os, if non-nil, is an OS-specific implementation of the portlist getting - // code. When non-nil, it's responsible for getting the complete list of - // cached ports complete with the process name. That is, when set, - // addProcesses is not used. - // A nil values means we don't have code for getting the list on the current - // operating system. - os osImpl -} - -type config struct { - includeLocalhost bool - procMountPoint string -} - -func newDefaultConfig() *config { - return &config{ - includeLocalhost: false, - procMountPoint: "/proc", - } -} - -// NewPoller initializes a new Poller. -func NewPoller(opts ...Option) (*Poller, error) { - if newOSImpl == nil { - return nil, errors.New("poller not implemented on " + runtime.GOOS) - } - cfg := newDefaultConfig() - for _, opt := range opts { - opt(cfg) - } - return &Poller{ - os: newOSImpl(cfg), - }, nil -} - -// osImpl is the OS-specific implementation of getting the open listening ports. -type osImpl interface { - Init() - Close() error - - // OpenPorts returns the list of open ports. The Port struct should be - // populated as completely as possible. - OpenPorts() ([]Port, error) -} - -// OpenPorts returns the list of currently listening ports. -func (p *Poller) OpenPorts() (List, error) { - p.os.Init() - defer func() { - if err := p.os.Close(); err != nil { - log.Warnf("failed to close port poller: %v", err) - } - }() - return p.os.OpenPorts() -} - -// Option is used to configure the Poller. -type Option func(cfg *config) - -// WithIncludeLocalhost allows to include/exclude localhost ports (false by default). -func WithIncludeLocalhost(includeLocalhost bool) Option { - return func(cfg *config) { - cfg.includeLocalhost = includeLocalhost - } -} - -// WithProcMountPoint allows to change the proc filesystem mount point (this is used mainly in tests). -func WithProcMountPoint(mountPoint string) Option { - return func(cfg *config) { - cfg.procMountPoint = filepath.Clean(mountPoint) - } -} diff --git a/pkg/collector/corechecks/servicediscovery/portlist/portlist_linux.go b/pkg/collector/corechecks/servicediscovery/portlist/portlist_linux.go deleted file mode 100644 index 918d9e6fc7a36..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/portlist/portlist_linux.go +++ /dev/null @@ -1,450 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2014-present Datadog, Inc. - -//go:build linux - -package portlist - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "io/fs" - "os" - "path" - "path/filepath" - "runtime" - "strings" - "syscall" - "unsafe" - - "go4.org/mem" - "golang.org/x/sys/unix" - - "github.com/DataDog/datadog-agent/pkg/util/log" -) - -func init() { - newOSImpl = newLinuxImpl -} - -type linuxImpl struct { - procMountPath string - procNetFiles []*os.File // seeked to start & reused between calls - readlinkPathBuf []byte - - known map[string]*portMeta // inode string => metadata - br *bufio.Reader - includeLocalhost bool -} - -type portMeta struct { - port Port - pid int - keep bool - needsProcName bool -} - -func newLinuxImplBase(includeLocalhost bool) *linuxImpl { - return &linuxImpl{ - br: bufio.NewReader(eofReader), - known: map[string]*portMeta{}, - includeLocalhost: includeLocalhost, - procMountPath: "/proc", - } -} - -func newLinuxImpl(cfg *config) osImpl { - li := newLinuxImplBase(cfg.includeLocalhost) - li.procMountPath = cfg.procMountPoint - - for _, name := range []string{ - "/net/tcp", - "/net/tcp6", - "/net/udp", - "/net/udp6", - } { - f, err := os.Open(path.Join(cfg.procMountPoint, name)) - if err != nil { - if os.IsNotExist(err) { - continue - } - log.Warnf("failed to open proc file, ignoring: %v", err) - continue - } - li.procNetFiles = append(li.procNetFiles, f) - } - return li -} - -func (li *linuxImpl) Init() { - for _, name := range []string{ - "/net/tcp", - "/net/tcp6", - "/net/udp", - "/net/udp6", - } { - f, err := os.Open(path.Join(li.procMountPath, name)) - if err != nil { - if os.IsNotExist(err) { - continue - } - log.Warnf("failed to open proc file, ignoring: %v", err) - continue - } - li.procNetFiles = append(li.procNetFiles, f) - } -} - -func (li *linuxImpl) Close() error { - for _, f := range li.procNetFiles { - f.Close() - } - li.procNetFiles = nil - return nil -} - -const ( - v6Localhost = "00000000000000000000000001000000:" - v6Any = "00000000000000000000000000000000:0000" - v4Localhost = "0100007F:" - v4Any = "00000000:0000" -) - -var eofReader = bytes.NewReader(nil) - -func (li *linuxImpl) OpenPorts() ([]Port, error) { - br := li.br - defer br.Reset(eofReader) - - // Start by marking all previous known ports as gone. If this mark - // bit is still false later, we'll remove them. - for _, pm := range li.known { - pm.keep = false - } - - for _, f := range li.procNetFiles { - name := f.Name() - _, err := f.Seek(0, io.SeekStart) - if err != nil { - return nil, err - } - br.Reset(f) - err = li.parseProcNetFile(br, filepath.Base(name)) - if err != nil { - return nil, fmt.Errorf("parsing %q: %w", name, err) - } - } - - // Delete ports that aren't open any longer. - // And see if there are any process names we need to look for. - var needProc map[string]*portMeta - for inode, pm := range li.known { - if !pm.keep { - delete(li.known, inode) - continue - } - if pm.needsProcName { - setOrCreateMap(&needProc, inode, pm) - } - } - err := li.findProcessNames(needProc) - if err != nil { - return nil, err - } - - var ret []Port - for _, pm := range li.known { - ret = append(ret, pm.port) - } - return sortAndDedup(ret), nil -} - -// fileBase is one of "tcp", "tcp6", "udp", "udp6". -func (li *linuxImpl) parseProcNetFile(r *bufio.Reader, fileBase string) error { - proto := strings.TrimSuffix(fileBase, "6") - - // skip header row - _, err := r.ReadSlice('\n') - if err != nil { - return err - } - - fields := make([]mem.RO, 0, 20) // 17 current fields + some future slop - - wantRemote := mem.S(v4Any) - if strings.HasSuffix(fileBase, "6") { - wantRemote = mem.S(v6Any) - } - - // remoteIndex is the index within a line to the remote address field. - // -1 means not yet found. - remoteIndex := -1 - - // Add an upper bound on how many rows we'll attempt to read just - // to make sure this doesn't consume too much of their CPU. - const maxRows = 1e6 - rows := 0 - - // Scratch buffer for making inode strings. - inoBuf := make([]byte, 0, 50) - - for { - line, err := r.ReadSlice('\n') - if err == io.EOF { - break - } - if err != nil { - return err - } - rows++ - if rows >= maxRows { - break - } - if len(line) == 0 { - continue - } - - // On the first row of output, find the index of the 3rd field (index 2), - // the remote address. All the rows are aligned, at least until 4 billion open - // TCP connections, per the Linux get_tcp4_sock's "%4d: " on an int i. - if remoteIndex == -1 { - remoteIndex = fieldIndex(line, 2) - if remoteIndex == -1 { - break - } - } - - if len(line) < remoteIndex || !mem.HasPrefix(mem.B(line).SliceFrom(remoteIndex), wantRemote) { - // Fast path for not being a listener port. - continue - } - - // sl local rem ... inode - fields = mem.AppendFields(fields[:0], mem.B(line)) - local := fields[1] - rem := fields[2] - inode := fields[9] - - if !rem.Equal(wantRemote) { - // not a "listener" port - continue - } - - // If a port is bound to localhost, ignore it. - // TODO: localhost is bigger than 1 IP, we need to ignore - // more things. - if !li.includeLocalhost && (mem.HasPrefix(local, mem.S(v4Localhost)) || mem.HasPrefix(local, mem.S(v6Localhost))) { - continue - } - - // Don't use strings.Split here, because it causes - // allocations significant enough to show up in profiles. - i := mem.IndexByte(local, ':') - if i == -1 { - return fmt.Errorf("%q unexpectedly didn't have a colon", local.StringCopy()) - } - portv, err := mem.ParseUint(local.SliceFrom(i+1), 16, 16) - if err != nil { - return fmt.Errorf("%#v: %s", local.SliceFrom(9).StringCopy(), err) - } - inoBuf = append(inoBuf[:0], "socket:["...) - inoBuf = mem.Append(inoBuf, inode) - inoBuf = append(inoBuf, ']') - - if pm, ok := li.known[string(inoBuf)]; ok { - pm.keep = true - // Rest should be unchanged. - } else { - li.known[string(inoBuf)] = &portMeta{ - needsProcName: true, - keep: true, - port: Port{ - Proto: proto, - Port: uint16(portv), - }, - } - } - } - - return nil -} - -// errDone is an internal sentinel error that we found everything we were looking for. -var errDone = errors.New("done") - -// need is keyed by inode string. -func (li *linuxImpl) findProcessNames(need map[string]*portMeta) error { - if len(need) == 0 { - return nil - } - defer func() { - // Anything we didn't find, give up on and don't try to look for it later. - for _, pm := range need { - pm.needsProcName = false - } - }() - - err := li.foreachPID(func(pid mem.RO) error { - var procBuf [128]byte - fdPath := mem.Append(procBuf[:0], mem.S(li.procMountPath+"/")) - fdPath = mem.Append(fdPath, pid) - fdPath = mem.Append(fdPath, mem.S("/fd")) - - // Android logs a bunch of audit violations in logcat - // if we try to open things we don't have access - // to. So on Android only, ask if we have permission - // rather than just trying it to determine whether we - // have permission. - if runtime.GOOS == "android" && syscall.Access(string(fdPath), unix.R_OK) != nil { - return nil - } - - _ = dirWalkShallow(mem.B(fdPath), func(fd mem.RO, _ fs.DirEntry) error { - targetBuf := make([]byte, 64) // plenty big for "socket:[165614651]" - - linkPath := li.readlinkPathBuf[:0] - linkPath = fmt.Appendf(linkPath, li.procMountPath+"/") - linkPath = mem.Append(linkPath, pid) - linkPath = append(linkPath, "/fd/"...) - linkPath = mem.Append(linkPath, fd) - linkPath = append(linkPath, 0) // terminating NUL - li.readlinkPathBuf = linkPath // to reuse its buffer next time - n, ok := readlink(linkPath, targetBuf) - if !ok { - // Not a symlink or no permission. - // Skip it. - return nil - } - - pe := need[string(targetBuf[:n])] // m[string([]byte)] avoids alloc - if pe == nil { - return nil - } - bs, err := os.ReadFile(fmt.Sprintf("%s/%s/cmdline", li.procMountPath, pid.StringCopy())) - if err != nil { - // Usually shouldn't happen. One possibility is - // the process has gone away, so let's skip it. - return nil - } - - argv := strings.Split(strings.TrimSuffix(string(bs), "\x00"), "\x00") - if p, err := mem.ParseInt(pid, 10, 0); err == nil { - pe.pid = int(p) - } - pe.port.Process = argvSubject(argv...) - pid64, _ := mem.ParseInt(pid, 10, 0) - pe.port.Pid = int(pid64) - pe.needsProcName = false - delete(need, string(targetBuf[:n])) - if len(need) == 0 { - return errDone - } - return nil - }) - return nil - }) - if errors.Is(err, errDone) { - return nil - } - return err -} - -func (li *linuxImpl) foreachPID(fn func(pidStr mem.RO) error) error { - err := dirWalkShallow(mem.S(li.procMountPath), func(name mem.RO, _ fs.DirEntry) error { - if !isNumeric(name) { - return nil - } - return fn(name) - }) - if os.IsNotExist(err) { - // This can happen if the directory we're - // reading disappears during the run. No big - // deal. - return nil - } - return err -} - -func isNumeric(s mem.RO) bool { - for i, n := 0, s.Len(); i < n; i++ { - b := s.At(i) - if b < '0' || b > '9' { - return false - } - } - return s.Len() > 0 -} - -// fieldIndex returns the offset in line where the Nth field (0-based) begins, or -1 -// if there aren't that many fields. Fields are separated by 1 or more spaces. -func fieldIndex(line []byte, n int) int { - skip := 0 - for i := 0; i <= n; i++ { - // Skip spaces. - for skip < len(line) && line[skip] == ' ' { - skip++ - } - if skip == len(line) { - return -1 - } - if i == n { - break - } - // Skip non-space. - for skip < len(line) && line[skip] != ' ' { - skip++ - } - } - return skip -} - -// path must be null terminated. -func readlink(path, buf []byte) (n int, ok bool) { - if len(buf) == 0 || len(path) < 2 || path[len(path)-1] != 0 { - return 0, false - } - var dirfd int = unix.AT_FDCWD - r0, _, e1 := unix.Syscall6(unix.SYS_READLINKAT, - uintptr(dirfd), - uintptr(unsafe.Pointer(&path[0])), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(len(buf)), - 0, 0) - n = int(r0) - if e1 != 0 { - return 0, false - } - return n, true -} - -// argvSubject takes a command and its flags, and returns the -// short/pretty name for the process. This is usually the basename of -// the binary being executed, but can sometimes vary (e.g. so that we -// don't report all Java programs as "java"). -func argvSubject(argv ...string) string { - if len(argv) == 0 { - return "" - } - ret := filepath.Base(argv[0]) - - // Handle special cases. - switch { - case ret == "mono" && len(argv) >= 2: - // .Net programs execute as `mono actualProgram.exe`. - ret = filepath.Base(argv[1]) - } - - // Handle space separated argv - ret, _, _ = strings.Cut(ret, " ") - - // Remove common noise. - ret = strings.TrimSpace(ret) - ret = strings.TrimSuffix(ret, ".exe") - - return ret -} diff --git a/pkg/collector/corechecks/servicediscovery/portlist/portlist_linux_test.go b/pkg/collector/corechecks/servicediscovery/portlist/portlist_linux_test.go deleted file mode 100644 index 5e1656d45cbcd..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/portlist/portlist_linux_test.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2014-present Datadog, Inc. - -//go:build linux - -package portlist - -import ( - "bufio" - "bytes" - "io" - "testing" - - "github.com/google/go-cmp/cmp" -) - -func TestFieldIndex(t *testing.T) { - tests := []struct { - in string - field int - want int - }{ - {"foo", 0, 0}, - {" foo", 0, 2}, - {"foo bar", 1, 5}, - {" foo bar", 1, 6}, - {" foo bar", 2, -1}, - {" foo bar ", 2, -1}, - {" foo bar x", 2, 10}, - {" 1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 34062 1 0000000000000000 100 0 0 10 0", - 2, 19}, - } - for _, tt := range tests { - if got := fieldIndex([]byte(tt.in), tt.field); got != tt.want { - t.Errorf("fieldIndex(%q, %v) = %v; want %v", tt.in, tt.field, got, tt.want) - } - } -} - -func TestParsePorts(t *testing.T) { - tests := []struct { - name string - in string - file string - want map[string]*portMeta - }{ - { - name: "empty", - in: "header line (ignored)\n", - want: map[string]*portMeta{}, - }, - { - name: "ipv4", - file: "tcp", - in: `header line - 0: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 22303 1 0000000000000000 100 0 0 10 0 - 1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 34062 1 0000000000000000 100 0 0 10 0 - 2: 5501A8C0:ADD4 B25E9536:01BB 01 00000000:00000000 02:00000B2B 00000000 1000 0 155276677 2 0000000000000000 22 4 30 10 -1 -`, - want: map[string]*portMeta{ - "socket:[34062]": { - port: Port{Proto: "tcp", Port: 22}, - }, - }, - }, - { - name: "ipv6", - file: "tcp6", - in: ` sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode - 0: 00000000000000000000000001000000:0277 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 35720 1 0000000000000000 100 0 0 10 0 - 1: 00000000000000000000000000000000:1F91 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 142240557 1 0000000000000000 100 0 0 10 0 - 2: 00000000000000000000000000000000:0016 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 34064 1 0000000000000000 100 0 0 10 0 - 3: 69050120005716BC64906EBE009ECD4D:D506 0047062600000000000000006E171268:01BB 01 00000000:00000000 02:0000009E 00000000 1000 0 151042856 2 0000000000000000 21 4 28 10 -1 -`, - want: map[string]*portMeta{ - "socket:[142240557]": { - port: Port{Proto: "tcp", Port: 8081}, - }, - "socket:[34064]": { - port: Port{Proto: "tcp", Port: 22}, - }, - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - buf := bytes.NewBufferString(tt.in) - r := bufio.NewReader(buf) - file := "tcp" - if tt.file != "" { - file = tt.file - } - li := newLinuxImplBase(false) - err := li.parseProcNetFile(r, file) - if err != nil { - t.Fatal(err) - } - for _, pm := range tt.want { - pm.keep = true - pm.needsProcName = true - } - if diff := cmp.Diff(li.known, tt.want, cmp.AllowUnexported(Port{}), cmp.AllowUnexported(portMeta{})); diff != "" { - t.Errorf("unexpected parsed ports (-got+want):\n%s", diff) - } - }) - } -} - -func BenchmarkParsePorts(b *testing.B) { - b.ReportAllocs() - - var contents bytes.Buffer - contents.WriteString(` sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode - 0: 00000000000000000000000001000000:0277 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 35720 1 0000000000000000 100 0 0 10 0 - 1: 00000000000000000000000000000000:1F91 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 142240557 1 0000000000000000 100 0 0 10 0 - 2: 00000000000000000000000000000000:0016 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 34064 1 0000000000000000 100 0 0 10 0 -`) - for i := 0; i < 50000; i++ { - contents.WriteString(" 3: 69050120005716BC64906EBE009ECD4D:D506 0047062600000000000000006E171268:01BB 01 00000000:00000000 02:0000009E 00000000 1000 0 151042856 2 0000000000000000 21 4 28 10 -1\n") - } - - li := newLinuxImplBase(false) - - r := bytes.NewReader(contents.Bytes()) - br := bufio.NewReader(&contents) - b.ResetTimer() - for i := 0; i < b.N; i++ { - r.Seek(0, io.SeekStart) - br.Reset(r) - err := li.parseProcNetFile(br, "tcp6") - if err != nil { - b.Fatal(err) - } - if len(li.known) != 2 { - b.Fatalf("wrong results; want 2 parsed got %d", len(li.known)) - } - } -} - -func BenchmarkFindProcessNames(b *testing.B) { - b.ReportAllocs() - li := &linuxImpl{} - need := map[string]*portMeta{ - "something-we'll-never-find": new(portMeta), - } - for i := 0; i < b.N; i++ { - if err := li.findProcessNames(need); err != nil { - b.Fatal(err) - } - } -} diff --git a/pkg/collector/corechecks/servicediscovery/portlist/portlist_test.go b/pkg/collector/corechecks/servicediscovery/portlist/portlist_test.go deleted file mode 100644 index 9efb7dd111139..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/portlist/portlist_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2014-present Datadog, Inc. - -package portlist - -import ( - "runtime" - "slices" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestPoller(t *testing.T) { - currentOs := runtime.GOOS - implOs := []string{ - "linux", - } - - p, err := NewPoller( - WithIncludeLocalhost(true), - WithProcMountPoint("/proc"), - ) - if !slices.Contains(implOs, currentOs) { - require.ErrorContains(t, err, "poller not implemented") - return - } - require.NoError(t, err) - - pl, err := p.OpenPorts() - require.NoError(t, err) - - for i, p := range pl { - t.Logf("[%d] %+v", i, p) - } - t.Logf("As String: %s", pl) -} diff --git a/pkg/collector/corechecks/servicediscovery/portlist/util.go b/pkg/collector/corechecks/servicediscovery/portlist/util.go deleted file mode 100644 index 68c8c11b08996..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/portlist/util.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2014-present Datadog, Inc. - -package portlist - -import ( - "io" - "io/fs" - "os" - - "go4.org/mem" -) - -func setOrCreateMap[K comparable, V any, T ~map[K]V](m *T, k K, v V) { - if *m == nil { - *m = make(map[K]V) - } - (*m)[k] = v -} - -var osWalkShallow func(name mem.RO, fn walkFunc) error - -// walkFunc is the callback type used with WalkShallow. -// -// The name and de are only valid for the duration of func's call -// and should not be retained. -type walkFunc func(name mem.RO, de fs.DirEntry) error - -// dirWalkShallow reads the entries in the named directory and calls fn for each. -// It does not recurse into subdirectories. -// -// If fn returns an error, iteration stops and WalkShallow returns that value. -// -// On Linux, dirWalkShallow does not allocate, so long as certain methods on the -// walkFunc's DirEntry are not called which necessarily allocate. -func dirWalkShallow(dirName mem.RO, fn walkFunc) error { - if f := osWalkShallow; f != nil { - return f(dirName, fn) - } - of, err := os.Open(dirName.StringCopy()) - if err != nil { - return err - } - defer of.Close() - for { - fis, err := of.ReadDir(100) - for _, de := range fis { - if err := fn(mem.S(de.Name()), de); err != nil { - return err - } - } - if err != nil { - if err == io.EOF { - return nil - } - return err - } - } -} diff --git a/pkg/collector/corechecks/servicediscovery/portlist/util_linux.go b/pkg/collector/corechecks/servicediscovery/portlist/util_linux.go deleted file mode 100644 index 0880542a9a472..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/portlist/util_linux.go +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2014-present Datadog, Inc. - -//go:build linux - -package portlist - -import ( - "fmt" - "io/fs" - "os" - "path/filepath" - "syscall" - "unsafe" - - "go4.org/mem" - "golang.org/x/sys/unix" - - ddsync "github.com/DataDog/datadog-agent/pkg/util/sync" -) - -func init() { - osWalkShallow = linuxWalkShallow -} - -var dirEntPool = ddsync.NewDefaultTypedPool[linuxDirEnt]() - -func linuxWalkShallow(dirName mem.RO, fn walkFunc) error { - const blockSize = 8 << 10 - buf := make([]byte, blockSize) // stack-allocated; doesn't escape - - nameb := mem.Append(buf[:0], dirName) - nameb = append(nameb, 0) - - fd, err := sysOpen(nameb) - if err != nil { - return err - } - defer syscall.Close(fd) - - bufp := 0 // starting read position in buf - nbuf := 0 // end valid data in buf - - de := dirEntPool.Get() - defer de.cleanAndPutInPool() - de.root = dirName - - for { - if bufp >= nbuf { - bufp = 0 - nbuf, err = readDirent(fd, buf) - if err != nil { - return err - } - if nbuf <= 0 { - return nil - } - } - consumed, name := parseDirEnt(&de.d, buf[bufp:nbuf]) - bufp += consumed - if len(name) == 0 || string(name) == "." || string(name) == ".." { - continue - } - de.name = mem.B(name) - if err := fn(de.name, de); err != nil { - return err - } - } -} - -type linuxDirEnt struct { - root mem.RO - d syscall.Dirent - name mem.RO -} - -func (de *linuxDirEnt) cleanAndPutInPool() { - de.root = mem.RO{} - de.name = mem.RO{} - dirEntPool.Put(de) -} - -func (de *linuxDirEnt) Name() string { return de.name.StringCopy() } -func (de *linuxDirEnt) Info() (fs.FileInfo, error) { - return os.Lstat(filepath.Join(de.root.StringCopy(), de.name.StringCopy())) -} -func (de *linuxDirEnt) IsDir() bool { - return de.d.Type == syscall.DT_DIR -} -func (de *linuxDirEnt) Type() fs.FileMode { - switch de.d.Type { - case syscall.DT_BLK: - return fs.ModeDevice // shrug - case syscall.DT_CHR: - return fs.ModeCharDevice - case syscall.DT_DIR: - return fs.ModeDir - case syscall.DT_FIFO: - return fs.ModeNamedPipe - case syscall.DT_LNK: - return fs.ModeSymlink - case syscall.DT_REG: - return 0 - case syscall.DT_SOCK: - return fs.ModeSocket - default: - return fs.ModeIrregular // shrug - } -} - -func direntNamlen(dirent *syscall.Dirent) int { - const fixedHdr = uint16(unsafe.Offsetof(syscall.Dirent{}.Name)) - limit := dirent.Reclen - fixedHdr - const dirNameLen = 256 // sizeof syscall.Dirent.Name - if limit > dirNameLen { - limit = dirNameLen - } - for i := uint16(0); i < limit; i++ { - if dirent.Name[i] == 0 { - return int(i) - } - } - panic("failed to find terminating 0 byte in dirent") -} - -func parseDirEnt(dirent *syscall.Dirent, buf []byte) (consumed int, name []byte) { - // golang.org/issue/37269 - copy(unsafe.Slice((*byte)(unsafe.Pointer(dirent)), unsafe.Sizeof(syscall.Dirent{})), buf) - if v := unsafe.Offsetof(dirent.Reclen) + unsafe.Sizeof(dirent.Reclen); uintptr(len(buf)) < v { - panic(fmt.Sprintf("buf size of %d smaller than dirent header size %d", len(buf), v)) - } - if len(buf) < int(dirent.Reclen) { - panic(fmt.Sprintf("buf size %d < record length %d", len(buf), dirent.Reclen)) - } - consumed = int(dirent.Reclen) - if dirent.Ino == 0 { // File absent in directory. - return - } - name = unsafe.Slice((*byte)(unsafe.Pointer(&dirent.Name[0])), direntNamlen(dirent)) - return -} - -func sysOpen(name []byte) (fd int, err error) { - if len(name) == 0 || name[len(name)-1] != 0 { - return 0, syscall.EINVAL - } - var dirfd int = unix.AT_FDCWD - for { - r0, _, e1 := syscall.Syscall(unix.SYS_OPENAT, uintptr(dirfd), - uintptr(unsafe.Pointer(&name[0])), 0) - if e1 == 0 { - return int(r0), nil - } - if e1 == syscall.EINTR { - // Since https://golang.org/doc/go1.14#runtime we - // need to loop on EINTR on more places. - continue - } - return 0, syscall.Errno(e1) - } -} - -func readDirent(fd int, buf []byte) (n int, err error) { - for { - nbuf, err := syscall.ReadDirent(fd, buf) - if err != syscall.EINTR { - return nbuf, err - } - } -} diff --git a/pkg/collector/corechecks/servicediscovery/portlist/util_test.go b/pkg/collector/corechecks/servicediscovery/portlist/util_test.go deleted file mode 100644 index 0fc07a1c6e20a..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/portlist/util_test.go +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2014-present Datadog, Inc. - -package portlist - -import ( - "fmt" - "os" - "path/filepath" - "reflect" - "runtime" - "sort" - "testing" - - "go4.org/mem" -) - -// replaceImpl replaces the value of target with val. -// The old value is restored when the test ends. -func replaceImpl[T any](t testing.TB, target *T, val T) { - t.Helper() - if target == nil { - t.Fatalf("Replace: nil pointer") - return - } - old := *target - t.Cleanup(func() { - *target = old - }) - - *target = val -} - -func Test_setOrCreateMap(t *testing.T) { - t.Run("unnamed", func(t *testing.T) { - var m map[string]int - setOrCreateMap(&m, "foo", 42) - setOrCreateMap(&m, "bar", 1) - setOrCreateMap(&m, "bar", 2) - want := map[string]int{ - "foo": 42, - "bar": 2, - } - if got := m; !reflect.DeepEqual(got, want) { - t.Errorf("got %v; want %v", got, want) - } - }) - t.Run("named", func(t *testing.T) { - type M map[string]int - var m M - setOrCreateMap(&m, "foo", 1) - setOrCreateMap(&m, "bar", 1) - setOrCreateMap(&m, "bar", 2) - want := M{ - "foo": 1, - "bar": 2, - } - if got := m; !reflect.DeepEqual(got, want) { - t.Errorf("got %v; want %v", got, want) - } - }) -} - -func Test_dirWalkShallowOSSpecific(t *testing.T) { - if osWalkShallow == nil { - t.Skip("no OS-specific implementation") - } - testDirWalkShallow(t, false) -} - -func Test_dirWalkShallowPortable(t *testing.T) { - testDirWalkShallow(t, true) -} - -func testDirWalkShallow(t *testing.T, portable bool) { - if portable { - replaceImpl(t, &osWalkShallow, nil) - } - d := t.TempDir() - - t.Run("basics", func(t *testing.T) { - if err := os.WriteFile(filepath.Join(d, "foo"), []byte("1"), 0600); err != nil { - t.Fatal(err) - } - if err := os.WriteFile(filepath.Join(d, "bar"), []byte("22"), 0400); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(filepath.Join(d, "baz"), 0777); err != nil { - t.Fatal(err) - } - - var got []string - if err := dirWalkShallow(mem.S(d), func(name mem.RO, de os.DirEntry) error { - var size int64 - if fi, err := de.Info(); err != nil { - t.Errorf("Info stat error on %q: %v", de.Name(), err) - } else if !fi.IsDir() { - size = fi.Size() - } - got = append(got, fmt.Sprintf("%q %q dir=%v type=%d size=%v", name.StringCopy(), de.Name(), de.IsDir(), de.Type(), size)) - return nil - }); err != nil { - t.Fatal(err) - } - sort.Strings(got) - want := []string{ - `"bar" "bar" dir=false type=0 size=2`, - `"baz" "baz" dir=true type=2147483648 size=0`, - `"foo" "foo" dir=false type=0 size=1`, - } - if !reflect.DeepEqual(got, want) { - t.Errorf("mismatch:\n got %#q\nwant %#q", got, want) - } - }) - - t.Run("err_not_exist", func(t *testing.T) { - err := dirWalkShallow(mem.S(filepath.Join(d, "not_exist")), func(_ mem.RO, _ os.DirEntry) error { - return nil - }) - if !os.IsNotExist(err) { - t.Errorf("unexpected error: %v", err) - } - }) - - t.Run("allocs", func(t *testing.T) { - allocs := int(testing.AllocsPerRun(1000, func() { - if err := dirWalkShallow(mem.S(d), func(_ mem.RO, _ os.DirEntry) error { return nil }); err != nil { - t.Fatal(err) - } - })) - t.Logf("allocs = %v", allocs) - if !portable && runtime.GOOS == "linux" && allocs != 0 { - t.Errorf("unexpected allocs: got %v, want 0", allocs) - } - }) -} diff --git a/pkg/collector/corechecks/servicediscovery/service_detector.go b/pkg/collector/corechecks/servicediscovery/service_detector.go index 44dd6ca95e7c4..b3647f87411de 100644 --- a/pkg/collector/corechecks/servicediscovery/service_detector.go +++ b/pkg/collector/corechecks/servicediscovery/service_detector.go @@ -9,30 +9,9 @@ import ( "slices" "strings" - "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/apm" - "go.uber.org/zap" - - "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/language" - "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/servicetype" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/servicediscovery/usm" - agentzap "github.com/DataDog/datadog-agent/pkg/util/log/zap" ) -// ServiceDetector defines the service detector to get metadata about services. -type ServiceDetector struct { - logger *zap.Logger - langFinder language.Finder -} - -// NewServiceDetector creates a new ServiceDetector object. -func NewServiceDetector() *ServiceDetector { - logger := zap.New(agentzap.NewZapCore()) - return &ServiceDetector{ - logger: logger, - langFinder: language.New(logger), - } -} - // ServiceMetadata stores metadata about a service. type ServiceMetadata struct { Name string @@ -64,30 +43,8 @@ func makeFinalName(meta usm.ServiceMetadata) string { // GetServiceName gets the service name based on the command line arguments and // the list of environment variables. -func (sd *ServiceDetector) GetServiceName(cmdline []string, env []string) string { - meta, _ := usm.ExtractServiceMetadata(sd.logger, cmdline, env) - return makeFinalName(meta) -} - -// Detect gets metadata for a service. -func (sd *ServiceDetector) Detect(p processInfo) ServiceMetadata { - meta, _ := usm.ExtractServiceMetadata(sd.logger, p.CmdLine, p.Env) - lang, _ := sd.langFinder.Detect(p.CmdLine, p.Env) - svcType := servicetype.Detect(meta.Name, p.Ports) - apmInstr := apm.Detect(sd.logger, p.CmdLine, p.Env, lang) - - sd.logger.Debug("name info", zap.String("name", meta.Name), zap.Strings("additional names", meta.AdditionalNames)) - - nameSource := "generated" - if meta.FromDDService { - nameSource = "provided" - } - - return ServiceMetadata{ - Name: makeFinalName(meta), - Language: string(lang), - Type: string(svcType), - APMInstrumentation: string(apmInstr), - NameSource: nameSource, - } +func GetServiceName(cmdline []string, env map[string]string, root string) (string, bool) { + fs := usm.NewSubDirFS(root) + meta, _ := usm.ExtractServiceMetadata(cmdline, env, fs) + return makeFinalName(meta), meta.FromDDService } diff --git a/pkg/collector/corechecks/servicediscovery/service_detector_test.go b/pkg/collector/corechecks/servicediscovery/service_detector_test.go deleted file mode 100644 index 703c02578dc0b..0000000000000 --- a/pkg/collector/corechecks/servicediscovery/service_detector_test.go +++ /dev/null @@ -1,53 +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 2016-present Datadog, Inc. - -package servicediscovery - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func Test_serviceDetector(t *testing.T) { - sd := NewServiceDetector() - - // no need to test many cases here, just ensuring the process data is properly passed down is enough. - pInfo := processInfo{ - PID: 100, - CmdLine: []string{"my-service.py"}, - Env: []string{"PATH=testdata/test-bin", "DD_INJECTION_ENABLED=tracer"}, - Stat: procStat{}, - Ports: []uint16{5432}, - } - - want := ServiceMetadata{ - Name: "my-service", - Language: "python", - Type: "db", - APMInstrumentation: "injected", - NameSource: "generated", - } - got := sd.Detect(pInfo) - assert.Equal(t, want, got) - - // pass in nil slices and see if anything blows up - pInfoEmpty := processInfo{ - PID: 0, - CmdLine: nil, - Env: nil, - Stat: procStat{}, - Ports: nil, - } - wantEmpty := ServiceMetadata{ - Name: "", - Language: "UNKNOWN", - Type: "web_service", - APMInstrumentation: "none", - NameSource: "generated", - } - gotEmpty := sd.Detect(pInfoEmpty) - assert.Equal(t, wantEmpty, gotEmpty) -} diff --git a/pkg/collector/corechecks/servicediscovery/servicediscovery.go b/pkg/collector/corechecks/servicediscovery/servicediscovery.go index fefec0cae9e1f..9578aa783ea47 100644 --- a/pkg/collector/corechecks/servicediscovery/servicediscovery.go +++ b/pkg/collector/corechecks/servicediscovery/servicediscovery.go @@ -46,7 +46,7 @@ type procStat struct { type processInfo struct { PID int CmdLine []string - Env []string + Env map[string]string Stat procStat Ports []uint16 } diff --git a/pkg/collector/corechecks/servicediscovery/usm/jboss.go b/pkg/collector/corechecks/servicediscovery/usm/jboss.go index d1dcde09f6e26..f54a28dc9db60 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/jboss.go +++ b/pkg/collector/corechecks/servicediscovery/usm/jboss.go @@ -13,7 +13,7 @@ import ( "path" "strings" - "go.uber.org/zap" + "github.com/DataDog/datadog-agent/pkg/util/log" ) const ( @@ -95,12 +95,19 @@ func newJbossExtractor(ctx DetectionContext) vendorExtractor { func (j jbossExtractor) findDeployedApps(domainHome string) ([]jeeDeployment, bool) { baseDir, ok := extractJavaPropertyFromArgs(j.cxt.args, jbossHomeDirSysProp) if !ok { - j.cxt.logger.Debug("jboss: unable to extract the home directory") + log.Debug("jboss: unable to extract the home directory") return nil, false } + // Add cwd if jboss.home.dir is relative. It's unclear if this is likely in + // real life, but the tests do do it. JBoss/WildFly docs imply that this is + // normally an absolute path (since it's set to JBOSS_HOME by default and a + // lot of other paths are resolved relative to this one). + if cwd, ok := workingDirFromEnvs(j.cxt.envs); ok { + baseDir = abs(baseDir, cwd) + } serverName, domainMode := jbossExtractServerName(j.cxt.args) if domainMode && len(serverName) == 0 { - j.cxt.logger.Debug("jboss: domain mode with missing server name") + log.Debug("jboss: domain mode with missing server name") return nil, false } configFile := jbossExtractConfigFileName(j.cxt.args, domainMode) @@ -111,7 +118,7 @@ func (j jbossExtractor) findDeployedApps(domainHome string) ([]jeeDeployment, bo baseDir = path.Join(baseDir, jbossDomainBase) sub, err = j.cxt.fs.Sub(baseDir) if err != nil { - j.cxt.logger.Debug("jboss: cannot open jboss home", zap.String("path", baseDir), zap.Error(err)) + log.Debugf("jboss: cannot open jboss home %q. Err: %v", baseDir, err) return nil, false } deployments, err = jbossDomainFindDeployments(sub, configFile, serverName) @@ -120,13 +127,13 @@ func (j jbossExtractor) findDeployedApps(domainHome string) ([]jeeDeployment, bo baseDir = path.Join(baseDir, jbossStandaloneBase) sub, err = j.cxt.fs.Sub(baseDir) if err != nil { - j.cxt.logger.Debug("jboss: cannot open jboss home", zap.String("path", baseDir), zap.Error(err)) + log.Debugf("jboss: cannot open jboss home %q. Err: %v", baseDir, err) return nil, false } deployments, err = jbossStandaloneFindDeployments(sub, configFile) } if err != nil || len(deployments) == 0 { - j.cxt.logger.Debug("jboss: cannot find deployments", zap.Error(err)) + log.Debugf("jboss: cannot find deployments. Err: %v", err) return nil, false } diff --git a/pkg/collector/corechecks/servicediscovery/usm/jboss_test.go b/pkg/collector/corechecks/servicediscovery/usm/jboss_test.go index 1c551985d0819..cb2bf610d214d 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/jboss_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/jboss_test.go @@ -3,6 +3,8 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. +//go:build !windows + package usm import ( @@ -10,8 +12,6 @@ import ( "testing" "testing/fstest" - "go.uber.org/zap" - "github.com/stretchr/testify/require" ) @@ -209,7 +209,7 @@ func TestJbossExtractWarContextRoot(t *testing.T) { if len(tt.location) > 0 { memFs[tt.location] = &fstest.MapFile{Data: []byte(tt.jbossWebXML)} } - value, ok := newJbossExtractor(NewDetectionContext(zap.NewNop(), nil, nil, nil)).customExtractWarContextRoot(memFs) + value, ok := newJbossExtractor(NewDetectionContext(nil, nil, nil)).customExtractWarContextRoot(memFs) require.Equal(t, tt.expected, value) require.Equal(t, len(value) > 0, ok) }) @@ -217,6 +217,7 @@ func TestJbossExtractWarContextRoot(t *testing.T) { } func TestJbossFindDeployedApps(t *testing.T) { + sub := MakeTestSubDirFS(t) tests := []struct { name string args []string @@ -229,22 +230,22 @@ func TestJbossFindDeployedApps(t *testing.T) { args: []string{ "-Djboss.home.dir=" + jbossTestAppRoot, }, - domainHome: "" + jbossTestAppRoot + "/standalone", + domainHome: jbossTestAppRootAbsolute + "/standalone", expected: []jeeDeployment{ { name: "app.ear", - path: "" + jbossTestAppRoot + "/standalone/data/content/38/e/content", + path: jbossTestAppRootAbsolute + "/standalone/data/content/38/e/content", }, { name: "web3.war", - path: "" + jbossTestAppRoot + "/standalone/data/content/8b/e62d23ec32e3956fecf9b5c35e8405510a825f/content", + path: jbossTestAppRootAbsolute + "/standalone/data/content/8b/e62d23ec32e3956fecf9b5c35e8405510a825f/content", }, { name: "web4.war", - path: "" + jbossTestAppRoot + "/standalone/data/content/f0/c/content", + path: jbossTestAppRootAbsolute + "/standalone/data/content/f0/c/content", }, }, - fs: RealFs{}, + fs: sub, }, { name: "standalone - missing home", @@ -290,7 +291,7 @@ func TestJbossFindDeployedApps(t *testing.T) { path: "" + jbossTestAppRoot + "/domain/servers/server-one/data/content/f0/c/content", }, }, - fs: RealFs{}, + fs: sub, }, { name: "domain- other server group", @@ -305,7 +306,7 @@ func TestJbossFindDeployedApps(t *testing.T) { path: "" + jbossTestAppRoot + "/domain/servers/server-three/data/content/f0/c/content", }, }, - fs: RealFs{}, + fs: sub, }, { name: "domain- server not found", @@ -315,7 +316,7 @@ func TestJbossFindDeployedApps(t *testing.T) { }, domainHome: "" + jbossTestAppRoot + "/domain/servers/server-four", expected: nil, - fs: RealFs{}, + fs: sub, }, { name: "domain- malformed server", @@ -325,7 +326,7 @@ func TestJbossFindDeployedApps(t *testing.T) { }, domainHome: "" + jbossTestAppRoot + "/domain/servers/server-four", expected: nil, - fs: RealFs{}, + fs: sub, }, { name: "domain- missing dir", @@ -394,7 +395,12 @@ func TestJbossFindDeployedApps(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - value, ok := newJbossExtractor(NewDetectionContext(zap.NewNop(), tt.args, nil, tt.fs)).findDeployedApps(tt.domainHome) + // A sibling directory is used as PWD since the tests uses relative + // paths to the app root (../testdata/a). + envs := map[string]string{ + "PWD": "/sibling", + } + value, ok := newJbossExtractor(NewDetectionContext(tt.args, envs, tt.fs)).findDeployedApps(tt.domainHome) require.Equal(t, tt.expected, value) require.Equal(t, len(value) > 0, ok) }) diff --git a/pkg/collector/corechecks/servicediscovery/usm/jee.go b/pkg/collector/corechecks/servicediscovery/usm/jee.go index d971c2a1fd03a..48a822508a71e 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/jee.go +++ b/pkg/collector/corechecks/servicediscovery/usm/jee.go @@ -14,7 +14,7 @@ import ( "path" "strings" - "go.uber.org/zap" + "github.com/DataDog/datadog-agent/pkg/util/log" ) // appserver is an enumeration of application server types @@ -245,14 +245,13 @@ func normalizeContextRoot(contextRoots ...string) []string { // doExtractContextRoots tries to extract context roots for an app, given the vendor and the fs. func (je jeeExtractor) doExtractContextRoots(extractor vendorExtractor, app *jeeDeployment) []string { - je.ctx.logger.Debug("extracting context root for a jee application", zap.String("name", app.name), - zap.String("path", app.path)) + log.Debugf("extracting context root (%q) for a jee application (%q)", app.path, app.name) if len(app.contextRoot) > 0 { return []string{app.contextRoot} } fsCloser, dt, err := vfsAndTypeFromAppPath(app, je.ctx.fs) if err != nil { - je.ctx.logger.Debug("error locating the deployment", zap.Error(err)) + log.Debugf("error locating the deployment: %v", err) if dt == ear { return nil } @@ -268,7 +267,7 @@ func (je jeeExtractor) doExtractContextRoots(extractor vendorExtractor, app *jee if dt == ear { value, err := extractContextRootFromApplicationXML(fsCloser.fs) if err != nil { - je.ctx.logger.Debug("unable to extract context roots from application.xml", zap.Error(err)) + log.Debugf("unable to extract context roots from application.xml: %v", err) return nil } return value @@ -291,7 +290,7 @@ func (je jeeExtractor) extractServiceNamesForJEEServer() []string { if vendor == unknown { return nil } - je.ctx.logger.Debug("running java enterprise service extraction", zap.Stringer("vendor", vendor)) + log.Debugf("running java enterprise service extraction - vendor %q", vendor) // check if able to find which applications are deployed extractorCreator, ok := extractors[vendor] if !ok { diff --git a/pkg/collector/corechecks/servicediscovery/usm/jee_test.go b/pkg/collector/corechecks/servicediscovery/usm/jee_test.go index 7a3e8623b1d27..cf0e94ac0e06d 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/jee_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/jee_test.go @@ -3,6 +3,8 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. +//go:build !windows + package usm import ( @@ -13,8 +15,6 @@ import ( "testing" "testing/fstest" - "go.uber.org/zap" - "github.com/stretchr/testify/require" ) @@ -110,7 +110,7 @@ com.ibm.wsspi.bootstrap.WSPreLauncher -nosplash -application com.ibm.ws.bootstra for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cmd := strings.Split(strings.ReplaceAll(tt.rawCmd, "\n", " "), " ") - vendor, home := jeeExtractor{NewDetectionContext(zap.NewNop(), cmd, nil, fstest.MapFS{})}.resolveAppServer() + vendor, home := jeeExtractor{NewDetectionContext(cmd, nil, fstest.MapFS{})}.resolveAppServer() require.Equal(t, tt.expectedVendor, vendor) // the base dir is making sense only when the vendor has been properly understood if tt.expectedVendor != unknown { @@ -228,10 +228,10 @@ func TestWeblogicExtractServiceNamesForJEEServer(t *testing.T) { require.NoError(t, writeFile(writer, weblogicXMLFile, weblogicXML)) require.NoError(t, writer.Close()) memfs := &fstest.MapFS{ - "wls/domain/config/config.xml": &fstest.MapFile{Data: []byte(wlsConfig)}, - "apps/app1.ear/" + applicationXMLPath: &fstest.MapFile{Data: []byte(appXML)}, - "apps/app2.war": &fstest.MapFile{Data: buf.Bytes()}, - "apps/app3.war": &fstest.MapFile{Mode: fs.ModeDir}, + "wls/domain/config/config.xml": &fstest.MapFile{Data: []byte(wlsConfig)}, + "wls/domain/apps/app1.ear/" + applicationXMLPath: &fstest.MapFile{Data: []byte(appXML)}, + "wls/domain/apps/app2.war": &fstest.MapFile{Data: buf.Bytes()}, + "wls/domain/apps/app3.war": &fstest.MapFile{Mode: fs.ModeDir}, } // simulate weblogic command line args @@ -240,8 +240,10 @@ func TestWeblogicExtractServiceNamesForJEEServer(t *testing.T) { wlsHomeSysProp + "/wls", wlsServerMainClass, } - envs := []string{"PWD=wls/domain"} - extractor := jeeExtractor{ctx: NewDetectionContext(zap.NewNop(), cmd, envs, memfs)} + envs := map[string]string{ + "PWD": "wls/domain", + } + extractor := jeeExtractor{ctx: NewDetectionContext(cmd, envs, memfs)} extractedContextRoots := extractor.extractServiceNamesForJEEServer() require.Equal(t, []string{ "app1_context", // taken from ear application.xml diff --git a/pkg/collector/corechecks/servicediscovery/usm/laravel_test.go b/pkg/collector/corechecks/servicediscovery/usm/laravel_test.go index 120c12f8a0158..8aa2b2af0e4b5 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/laravel_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/laravel_test.go @@ -11,7 +11,6 @@ import ( "testing/fstest" "github.com/stretchr/testify/require" - "go.uber.org/zap" ) func TestGetLaravelAppNameFromEnv(t *testing.T) { @@ -98,7 +97,7 @@ func TestGetLaravelAppNameFromEnv(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - name := newLaravelParser(NewDetectionContext(zap.NewExample(), nil, nil, tt.filesystem)).GetLaravelAppName("artisan") + name := newLaravelParser(NewDetectionContext(nil, nil, tt.filesystem)).GetLaravelAppName("artisan") require.Equal(t, tt.expected, name) }) } diff --git a/pkg/collector/corechecks/servicediscovery/usm/nodejs.go b/pkg/collector/corechecks/servicediscovery/usm/nodejs.go index 8d0fedf55ddc6..6a39be2b41dda 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/nodejs.go +++ b/pkg/collector/corechecks/servicediscovery/usm/nodejs.go @@ -7,13 +7,14 @@ package usm import ( "io" - "os" + "io/fs" "path" + "path/filepath" "strings" - "go.uber.org/zap" - "github.com/valyala/fastjson" + + "github.com/DataDog/datadog-agent/pkg/util/log" ) type nodeDetector struct { @@ -24,8 +25,13 @@ func newNodeDetector(ctx DetectionContext) detector { return &nodeDetector{ctx: ctx} } +func isJs(path string) bool { + return strings.HasSuffix(strings.ToLower(path), ".js") +} + func (n nodeDetector) detect(args []string) (ServiceMetadata, bool) { skipNext := false + cwd, _ := workingDirFromEnvs(n.ctx.envs) for _, a := range args { if skipNext { skipNext = false @@ -37,11 +43,23 @@ func (n nodeDetector) detect(args []string) (ServiceMetadata, bool) { skipNext = !strings.ContainsRune(a, '=') // in this case the value is already in this arg continue } - } else if strings.HasSuffix(strings.ToLower(a), ".js") { - cwd, _ := workingDirFromEnvs(n.ctx.envs) + } else { absFile := abs(path.Clean(a), cwd) - if _, err := os.Stat(absFile); err == nil { - value, ok := n.findNameFromNearestPackageJSON(absFile) + entryPoint := "" + if isJs(a) { + entryPoint = absFile + } else if target, err := ReadlinkFS(n.ctx.fs, absFile); err == nil { + if !isJs(target) { + continue + } + + entryPoint = abs(target, filepath.Dir(absFile)) + } else { + continue + } + + if _, err := fs.Stat(n.ctx.fs, absFile); err == nil { + value, ok := n.findNameFromNearestPackageJSON(entryPoint) if ok { return NewServiceMetadata(value), true } @@ -78,27 +96,24 @@ func (n nodeDetector) maybeExtractServiceName(filename string) (string, bool) { if err != nil { return "", false } + defer file.Close() ok, err := canSafelyParse(file) if err != nil { //file not accessible or don't exist. Continuing searching up return "", false } if !ok { - n.ctx.logger.Debug("skipping package.js because too large", zap.String("filename", filename)) + log.Debugf("skipping package.js (%q) because too large", filename) return "", true // stops here } bytes, err := io.ReadAll(file) if err != nil { - n.ctx.logger.Debug("unable to read a package.js file", - zap.String("filename", filename), - zap.Error(err)) + log.Debugf("unable to read a package.js file (%q). Err: %v", filename, err) return "", true } value, err := fastjson.ParseBytes(bytes) if err != nil { - n.ctx.logger.Debug("unable to parse a package.js file", - zap.String("filename", filename), - zap.Error(err)) + log.Debugf("unable to parse a package.js (%q) file. Err: %v", filename, err) return "", true } return string(value.GetStringBytes("name")), true diff --git a/pkg/collector/corechecks/servicediscovery/usm/nodejs_test.go b/pkg/collector/corechecks/servicediscovery/usm/nodejs_test.go index f75a1df9b86f6..8c328ed36e8b0 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/nodejs_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/nodejs_test.go @@ -3,14 +3,16 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. +//go:build !windows + package usm import ( + "path/filepath" "testing" - "go.uber.org/zap" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestFindNameFromNearestPackageJSON(t *testing.T) { @@ -35,7 +37,10 @@ func TestFindNameFromNearestPackageJSON(t *testing.T) { expected: "my-awesome-package", }, } - instance := &nodeDetector{ctx: DetectionContext{logger: zap.NewNop(), fs: &RealFs{}}} + full, err := filepath.Abs("testdata/root") + require.NoError(t, err) + sub := NewSubDirFS(full) + instance := &nodeDetector{ctx: DetectionContext{fs: sub}} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { value, ok := instance.findNameFromNearestPackageJSON(tt.path) diff --git a/pkg/collector/corechecks/servicediscovery/usm/php_test.go b/pkg/collector/corechecks/servicediscovery/usm/php_test.go index cc246a3d382d4..16260dc33b139 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/php_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/php_test.go @@ -7,8 +7,6 @@ package usm import ( "testing" - - "go.uber.org/zap" ) func TestServiceNameFromCLI(t *testing.T) { @@ -38,7 +36,7 @@ func TestServiceNameFromCLI(t *testing.T) { expected: "", }, } - instance := &phpDetector{ctx: NewDetectionContext(zap.NewExample(), nil, nil, nil)} + instance := &phpDetector{ctx: NewDetectionContext(nil, nil, nil)} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { value, ok := instance.detect(tt.args) diff --git a/pkg/collector/corechecks/servicediscovery/usm/python_test.go b/pkg/collector/corechecks/servicediscovery/usm/python_test.go index a42f761fedea5..953e5071cd539 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/python_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/python_test.go @@ -11,7 +11,6 @@ import ( "testing/fstest" "github.com/stretchr/testify/require" - "go.uber.org/zap" ) func TestPythonDetect(t *testing.T) { @@ -75,7 +74,7 @@ func TestPythonDetect(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - value, ok := newPythonDetector(NewDetectionContext(zap.NewNop(), nil, nil, memFs)).detect(strings.Split(tt.cmd, " ")[1:]) + value, ok := newPythonDetector(NewDetectionContext(nil, nil, memFs)).detect(strings.Split(tt.cmd, " ")[1:]) require.Equal(t, tt.expected, value.Name) require.Equal(t, len(value.Name) > 0, ok) }) diff --git a/pkg/collector/corechecks/servicediscovery/usm/service.go b/pkg/collector/corechecks/servicediscovery/usm/service.go index c66d65414118e..3f0d2f7f24b99 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/service.go +++ b/pkg/collector/corechecks/servicediscovery/usm/service.go @@ -14,8 +14,6 @@ import ( "slices" "strings" "unicode" - - "go.uber.org/zap" ) type detectorCreatorFn func(ctx DetectionContext) detector @@ -74,35 +72,29 @@ func newDotnetDetector(ctx DetectionContext) detector { // DetectionContext allows to detect ServiceMetadata. type DetectionContext struct { - logger *zap.Logger - args []string - envs []string - fs fs.SubFS + args []string + envs map[string]string + fs fs.SubFS } // NewDetectionContext initializes DetectionContext. -func NewDetectionContext(logger *zap.Logger, args []string, envs []string, fs fs.SubFS) DetectionContext { +func NewDetectionContext(args []string, envs map[string]string, fs fs.SubFS) DetectionContext { return DetectionContext{ - logger: logger, - args: args, - envs: envs, - fs: fs, + args: args, + envs: envs, + fs: fs, } } // workingDirFromEnvs returns the current working dir extracted from the PWD env -func workingDirFromEnvs(envs []string) (string, bool) { +func workingDirFromEnvs(envs map[string]string) (string, bool) { return extractEnvVar(envs, "PWD") } -func extractEnvVar(envs []string, name string) (string, bool) { - value := "" - prefix := name + "=" - for _, v := range envs { - if strings.HasPrefix(v, prefix) { - _, value, _ = strings.Cut(v, "=") - break - } +func extractEnvVar(envs map[string]string, name string) (string, bool) { + value, ok := envs[name] + if !ok { + return "", false } return value, len(value) > 0 } @@ -140,17 +132,14 @@ var binsWithContext = map[string]detectorCreatorFn{ "gunicorn": newGunicornDetector, } -func checkForInjectionNaming(envs []string) bool { +func checkForInjectionNaming(envs map[string]string) bool { fromDDService := true -outer: - for _, v := range envs { - if strings.HasPrefix(v, "DD_INJECTION_ENABLED=") { - values := strings.Split(v[len("DD_INJECTION_ENABLED="):], ",") - for _, v := range values { - if v == "service_name" { - fromDDService = false - break outer - } + if env, ok := envs["DD_INJECTION_ENABLED"]; ok { + values := strings.Split(env, ",") + for _, v := range values { + if v == "service_name" { + fromDDService = false + break } } } @@ -158,12 +147,11 @@ outer: } // ExtractServiceMetadata attempts to detect ServiceMetadata from the given process. -func ExtractServiceMetadata(logger *zap.Logger, args []string, envs []string) (ServiceMetadata, bool) { +func ExtractServiceMetadata(args []string, envs map[string]string, fs fs.SubFS) (ServiceMetadata, bool) { dc := DetectionContext{ - logger: logger, - args: args, - envs: envs, - fs: RealFs{}, + args: args, + envs: envs, + fs: fs, } cmd := dc.args if len(cmd) == 0 || len(cmd[0]) == 0 { @@ -271,20 +259,19 @@ func normalizeExeName(exe string) string { // chooseServiceNameFromEnvs extracts the service name from usual tracer env variables (DD_SERVICE, DD_TAGS). // returns the service name, true if found, otherwise "", false -func chooseServiceNameFromEnvs(envs []string) (string, bool) { - for _, env := range envs { - if strings.HasPrefix(env, "DD_SERVICE=") { - return strings.TrimPrefix(env, "DD_SERVICE="), true - } - if strings.HasPrefix(env, "DD_TAGS=") && strings.Contains(env, "service:") { - parts := strings.Split(strings.TrimPrefix(env, "DD_TAGS="), ",") - for _, p := range parts { - if strings.HasPrefix(p, "service:") { - return strings.TrimPrefix(p, "service:"), true - } +func chooseServiceNameFromEnvs(envs map[string]string) (string, bool) { + if val, ok := envs["DD_SERVICE"]; ok { + return val, true + } + if val, ok := envs["DD_TAGS"]; ok && strings.Contains(val, "service:") { + parts := strings.Split(val, ",") + for _, p := range parts { + if strings.HasPrefix(p, "service:") { + return strings.TrimPrefix(p, "service:"), true } } } + return "", false } @@ -338,3 +325,76 @@ func (RealFs) Open(name string) (fs.File, error) { func (RealFs) Sub(dir string) (fs.FS, error) { return os.DirFS(dir), nil } + +// SubDirFS is like the fs.FS implemented by os.DirFS, except that it allows +// absolute paths to be passed in the Open/Stat/etc, and attaches them to the +// root dir. It also implements SubFS, unlink the one implemented by os.DirFS. +type SubDirFS struct { + fs.FS + root string +} + +// NewSubDirFS creates a new SubDirFS rooted at the specified path. +func NewSubDirFS(root string) SubDirFS { + return SubDirFS{FS: os.DirFS(root), root: root} +} + +// fixPath ensures that the specified path is stripped of the leading slash (if +// any) and is cleaned so that it can be passed to normal fs.FS functions which +// do not allow absolute paths or paths which do not pass fs.ValidPath (which +// contain ./ or .. for example). +func (s SubDirFS) fixPath(path string) string { + path = filepath.Clean(path) + if filepath.IsAbs(path) { + return path[1:] + } + + return path +} + +// Readlink reads the specified symlink. +func (s SubDirFS) Readlink(name string) (string, error) { + name = s.fixPath(name) + return os.Readlink(filepath.Join(s.root, name)) +} + +// ReadlinkFS reads the symlink on the provided FS. There is no standard +// SymlinkFS interface yet https://github.com/golang/go/issues/49580. +func ReadlinkFS(fsfs fs.FS, name string) (string, error) { + if subDirFS, ok := fsfs.(SubDirFS); ok { + return subDirFS.Readlink(name) + } + + return "", fs.ErrInvalid +} + +// Sub provides a fs.FS for the specified subdirectory. +func (s SubDirFS) Sub(dir string) (fs.FS, error) { + dir = filepath.Join(s.root, s.fixPath(dir)) + return os.DirFS(dir), nil +} + +// ReadDir reads the specified subdirectory +func (s SubDirFS) ReadDir(name string) ([]fs.DirEntry, error) { + if readDirFS, ok := s.FS.(fs.ReadDirFS); ok { + name = s.fixPath(name) + return readDirFS.ReadDir(name) + } + + return nil, fs.ErrInvalid +} + +// Stat stats the specified file +func (s SubDirFS) Stat(name string) (fs.FileInfo, error) { + if statFS, ok := s.FS.(fs.StatFS); ok { + name = s.fixPath(name) + return statFS.Stat(name) + } + + return nil, fs.ErrInvalid +} + +// Open opens the specified file +func (s SubDirFS) Open(name string) (fs.File, error) { + return s.FS.Open(s.fixPath(name)) +} diff --git a/pkg/collector/corechecks/servicediscovery/usm/service_test.go b/pkg/collector/corechecks/servicediscovery/usm/service_test.go index 7c56bc9adcd2a..0355534aefa0e 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/service_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/service_test.go @@ -3,6 +3,8 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. +//go:build !windows + package usm import ( @@ -10,11 +12,12 @@ import ( "errors" "io/fs" "path" + "path/filepath" + "runtime" "testing" + "github.com/DataDog/datadog-agent/pkg/network/protocols/http/testutil" "github.com/stretchr/testify/require" - - "go.uber.org/zap" ) const ( @@ -22,19 +25,35 @@ const ( // we need to use these non-descriptive shorter folder names because of the filename_linting // CI check that limits the number of characters in a path to 255. - jbossTestAppRoot = "../testdata/a" - weblogicTestAppRoot = "../testdata/b" + jbossTestAppRoot = "../testdata/a" + jbossTestAppRootAbsolute = "/testdata/a" + weblogicTestAppRoot = "../testdata/b" + weblogicTestAppRootAbsolute = "/testdata/b" ) +func MakeTestSubDirFS(t *testing.T) SubDirFS { + curDir, err := testutil.CurDir() + require.NoError(t, err) + + full := filepath.Join(curDir, "..", "..", "..", "..", "discovery", "testdata", "root") + return NewSubDirFS(full) +} + func TestExtractServiceMetadata(t *testing.T) { springBootAppFullPath := createMockSpringBootApp(t) + sub := MakeTestSubDirFS(t) + usmFull, err := filepath.Abs("testdata/root") + require.NoError(t, err) + subUsmTestData := NewSubDirFS(usmFull) tests := []struct { name string cmdline []string - envs []string + envs map[string]string expectedServiceTag string expectedAdditionalServices []string fromDDService bool + fs *SubDirFS + skipOnWindows bool }{ { name: "empty", @@ -58,7 +77,7 @@ func TestExtractServiceMetadata(t *testing.T) { cmdline: []string{ "./my-server.sh", }, - envs: []string{"DD_SERVICE=my-service"}, + envs: map[string]string{"DD_SERVICE": "my-service"}, expectedServiceTag: "my-service", fromDDService: true, }, @@ -67,7 +86,7 @@ func TestExtractServiceMetadata(t *testing.T) { cmdline: []string{ "./my-server.sh", }, - envs: []string{"DD_TAGS=service:my-service"}, + envs: map[string]string{"DD_TAGS": "service:my-service"}, expectedServiceTag: "my-service", fromDDService: true, }, @@ -91,7 +110,8 @@ func TestExtractServiceMetadata(t *testing.T) { "/opt/python/2.7.11/bin/python2.7", "flask", "run", "--host=0.0.0.0", }, expectedServiceTag: "flask", - envs: []string{"PWD=testdata/python"}, + envs: map[string]string{"PWD": "testdata/python"}, + fs: &subUsmTestData, }, { name: "python - flask argument in path", @@ -99,14 +119,16 @@ func TestExtractServiceMetadata(t *testing.T) { "/opt/python/2.7.11/bin/python2.7", "testdata/python/flask", "run", "--host=0.0.0.0", "--without-threads", }, expectedServiceTag: "flask", + fs: &subUsmTestData, }, { name: "python flask in single argument", cmdline: []string{ "/opt/python/2.7.11/bin/python2.7 flask run --host=0.0.0.0", }, - envs: []string{"PWD=testdata/python"}, + envs: map[string]string{"PWD": "testdata/python"}, expectedServiceTag: "flask", + fs: &subUsmTestData, }, { name: "python - module hello", @@ -190,6 +212,21 @@ func TestExtractServiceMetadata(t *testing.T) { "./testdata/index.js", }, expectedServiceTag: "my-awesome-package", + fs: &subUsmTestData, + }, + { + name: "node js with a symlink to a .js file and valid package.json", + cmdline: []string{ + "/usr/bin/node", + "--foo", + "./testdata/bins/notjs", + "--bar", + "./testdata/bins/broken", + "./testdata/bins/json-server", + }, + expectedServiceTag: "json-server-package", + skipOnWindows: true, + fs: &subUsmTestData, }, { name: "node js with a valid nested package.json and cwd", @@ -201,7 +238,8 @@ func TestExtractServiceMetadata(t *testing.T) { "--", "index.js", }, - envs: []string{"PWD=testdata/deep"}, // it's relative but it's ok for testing purposes + envs: map[string]string{"PWD": "testdata/deep"}, // it's relative but it's ok for testing purposes + fs: &subUsmTestData, expectedServiceTag: "my-awesome-package", }, { @@ -239,6 +277,8 @@ func TestExtractServiceMetadata(t *testing.T) { "-Djboss.server.base.dir=" + jbossTestAppRoot + "/standalone"}, expectedServiceTag: "jboss-modules", expectedAdditionalServices: []string{"my-jboss-webapp", "some_context_root", "web3"}, + fs: &sub, + envs: map[string]string{"PWD": "/sibiling"}, }, { name: "wildfly 18 domain", @@ -269,9 +309,12 @@ func TestExtractServiceMetadata(t *testing.T) { "org.jboss.as.server"}, expectedServiceTag: "jboss-modules", expectedAdditionalServices: []string{"web3", "web4"}, + fs: &sub, + envs: map[string]string{"PWD": "/sibiling"}, }, { name: "weblogic 12", + fs: &sub, cmdline: []string{"/u01/jdk/bin/java", "-Djava.security.egd=file:/dev/./urandom", "-cp", @@ -285,7 +328,7 @@ func TestExtractServiceMetadata(t *testing.T) { "-Dwls.home=/u01/oracle/wlserver/server", "-Dweblogic.home=/u01/oracle/wlserver/server", "weblogic.Server"}, - envs: []string{"PWD=" + weblogicTestAppRoot}, + envs: map[string]string{"PWD": weblogicTestAppRootAbsolute}, expectedServiceTag: "Server", expectedAdditionalServices: []string{"my_context", "sample4", "some_context_root"}, }, @@ -321,6 +364,7 @@ func TestExtractServiceMetadata(t *testing.T) { }, expectedServiceTag: "catalina", expectedAdditionalServices: []string{"app2", "custom"}, + fs: &subUsmTestData, }, { name: "dotnet cmd with dll", @@ -397,21 +441,21 @@ func TestExtractServiceMetadata(t *testing.T) { { name: "DD_SERVICE_set_manually", cmdline: []string{"java", "-jar", "Foo.jar"}, - envs: []string{"DD_SERVICE=howdy"}, + envs: map[string]string{"DD_SERVICE": "howdy"}, expectedServiceTag: "howdy", fromDDService: true, }, { name: "DD_SERVICE_set_manually_tags", cmdline: []string{"java", "-jar", "Foo.jar"}, - envs: []string{"DD_TAGS=service:howdy"}, + envs: map[string]string{"DD_TAGS": "service:howdy"}, expectedServiceTag: "howdy", fromDDService: true, }, { name: "DD_SERVICE_set_manually_injection", cmdline: []string{"java", "-jar", "Foo.jar"}, - envs: []string{"DD_SERVICE=howdy", "DD_INJECTION_ENABLED=tracer,service_name"}, + envs: map[string]string{"DD_SERVICE": "howdy", "DD_INJECTION_ENABLED": "tracer,service_name"}, expectedServiceTag: "howdy", fromDDService: false, }, @@ -455,7 +499,7 @@ func TestExtractServiceMetadata(t *testing.T) { "gunicorn", "test:app", }, - envs: []string{"GUNICORN_CMD_ARGS=--bind=127.0.0.1:8080 --workers=3 -n dummy"}, + envs: map[string]string{"GUNICORN_CMD_ARGS": "--bind=127.0.0.1:8080 --workers=3 -n dummy"}, expectedServiceTag: "dummy", }, { @@ -463,7 +507,7 @@ func TestExtractServiceMetadata(t *testing.T) { cmdline: []string{ "gunicorn", }, - envs: []string{"GUNICORN_CMD_ARGS=--bind=127.0.0.1:8080 --workers=3"}, + envs: map[string]string{"GUNICORN_CMD_ARGS": "--bind=127.0.0.1:8080 --workers=3"}, expectedServiceTag: "gunicorn", }, { @@ -480,7 +524,7 @@ func TestExtractServiceMetadata(t *testing.T) { "gunicorn", "my.package", }, - envs: []string{"WSGI_APP="}, + envs: map[string]string{"WSGI_APP": ""}, expectedServiceTag: "my.package", }, { @@ -488,14 +532,23 @@ func TestExtractServiceMetadata(t *testing.T) { cmdline: []string{ "gunicorn", }, - envs: []string{"WSGI_APP=test:app"}, + envs: map[string]string{"WSGI_APP": "test:app"}, expectedServiceTag: "test", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - meta, ok := ExtractServiceMetadata(zap.NewNop(), tt.cmdline, tt.envs) + if tt.skipOnWindows && runtime.GOOS == "windows" { + t.Skip("Not supported on Windows") + } + + var fs fs.SubFS + fs = RealFs{} + if tt.fs != nil { + fs = *tt.fs + } + meta, ok := ExtractServiceMetadata(tt.cmdline, tt.envs, fs) if len(tt.expectedServiceTag) == 0 { require.False(t, ok) } else { @@ -574,3 +627,39 @@ func (s shadowFS) Sub(dir string) (fs.FS, error) { } return shadowFS{filesystem: fsys, parent: s}, nil } + +func TestSubDirFS(t *testing.T) { + fs := NewSubDirFS("testdata/root/") + _, err := fs.Stat("/testdata/index.js") + require.NoError(t, err) + + _, err = fs.Stat("testdata/index.js") + require.NoError(t, err) + + _, err = fs.Stat("../root") + require.Error(t, err) + + _, err = fs.Stat("/testdata/python/../index.js") + require.NoError(t, err) + + _, err = fs.Stat("testdata/python/../index.js") + require.NoError(t, err) + + f, err := fs.Open("testdata/python/../index.js") + require.NoError(t, err) + t.Cleanup(func() { f.Close() }) + + sub, err := fs.Sub("testdata") + require.NoError(t, err) + f2, err := sub.Open("index.js") + require.NoError(t, err) + t.Cleanup(func() { f2.Close() }) + + entries, err := fs.ReadDir("/testdata") + require.NoError(t, err) + names := make([]string, 0, len(entries)) + for _, e := range entries { + names = append(names, e.Name()) + } + require.Contains(t, names, "index.js") +} diff --git a/pkg/collector/corechecks/servicediscovery/usm/spring.go b/pkg/collector/corechecks/servicediscovery/usm/spring.go index 44940d8d8524c..4dab88aeaf008 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/spring.go +++ b/pkg/collector/corechecks/servicediscovery/usm/spring.go @@ -14,10 +14,10 @@ import ( "path/filepath" "strings" - "go.uber.org/zap" - "github.com/rickar/props" "github.com/vibrantbyte/go-antpath/antpath" + + "github.com/DataDog/datadog-agent/pkg/util/log" ) const ( @@ -82,8 +82,8 @@ func (y *environmentSource) Get(key string) (string, bool) { func (y *environmentSource) GetDefault(key string, defVal string) string { return y.m.GetDefault(strings.Map(normalizeEnv, key), defVal) } -func newEnvironmentSource(envs []string) props.PropertyGetter { - return &environmentSource{m: newArgumentSource(envs, "")} +func newEnvironmentSource(envs map[string]string) props.PropertyGetter { + return &environmentSource{m: &mapSource{m: envs}} } // normalizeEnv converts a rune into a suitable replacement for an environment variable name. @@ -224,7 +224,7 @@ func (s springBootParser) scanSourcesFromFileSystem(profilePatterns map[string][ // a match is found value, err := s.newPropertySourceFromFile(p) if err != nil { - s.ctx.logger.Debug("cannot parse a property source", zap.String("filename", p), zap.Error(err)) + log.Debugf("cannot parse a property source (filename: %q). Err: %v", p, err) return nil } arr, ok := ret[profile] @@ -306,7 +306,7 @@ func (s springBootParser) GetSpringBootAppName(jarname string) (string, bool) { if !isSpringBootArchive(reader) { return "", false } - s.ctx.logger.Debug("parsing information from spring boot archive", zap.String("filename", jarname)) + log.Debugf("parsing information from spring boot archive: %q", jarname) combined := &props.Combined{Sources: []props.PropertyGetter{ newArgumentSource(s.ctx.args, "--"), diff --git a/pkg/collector/corechecks/servicediscovery/usm/spring_test.go b/pkg/collector/corechecks/servicediscovery/usm/spring_test.go index 2a3b7f3ee5547..78c1f75b539d4 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/spring_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/spring_test.go @@ -3,18 +3,19 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. +//go:build !windows + package usm import ( "archive/zip" "bytes" "os" + "path/filepath" "strings" "testing" "testing/fstest" - "go.uber.org/zap" - "github.com/stretchr/testify/require" ) @@ -117,7 +118,7 @@ func TestParseUri(t *testing.T) { expectedClassPathLocations: map[string][]string{}, }, } - parser := newSpringBootParser(NewDetectionContext(zap.NewNop(), nil, nil, fstest.MapFS(nil))) + parser := newSpringBootParser(NewDetectionContext(nil, nil, fstest.MapFS(nil))) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fsLocs, cpLocs := parser.parseURI(strings.Split(tt.locations, ";"), tt.configName, tt.profiles, tt.cwd) @@ -208,14 +209,15 @@ func TestArgumentPropertySource(t *testing.T) { } } func TestScanSourcesFromFileSystem(t *testing.T) { - cwd, err := os.Getwd() + full, err := filepath.Abs("testdata/root") require.NoError(t, err) - parser := newSpringBootParser(NewDetectionContext(zap.NewNop(), nil, nil, &RealFs{})) + sub := NewSubDirFS(full) + parser := newSpringBootParser(NewDetectionContext(nil, nil, sub)) fileSources := parser.scanSourcesFromFileSystem(map[string][]string{ "fs": { - abs("./application-fs.properties", cwd), - abs("./*/application-fs.properties", cwd), + "application-fs.properties", + "testdata/*/application-fs.properties", }, }) require.Len(t, fileSources, 1) @@ -299,7 +301,7 @@ func TestExtractServiceMetadataSpringBoot(t *testing.T) { name string jarname string cmdline []string - envs []string + envs map[string]string expected string }{ { @@ -342,8 +344,8 @@ func TestExtractServiceMetadataSpringBoot(t *testing.T) { "-jar", spFullPath, }, - envs: []string{ - "SPRING_APPLICATION_NAME=found", + envs: map[string]string{ + "SPRING_APPLICATION_NAME": "found", }, expected: "found", }, @@ -395,7 +397,7 @@ func TestExtractServiceMetadataSpringBoot(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - app, ok := newSpringBootParser(NewDetectionContext(zap.NewNop(), tt.cmdline, tt.envs, RealFs{})).GetSpringBootAppName(tt.jarname) + app, ok := newSpringBootParser(NewDetectionContext(tt.cmdline, tt.envs, RealFs{})).GetSpringBootAppName(tt.jarname) require.Equal(t, tt.expected, app) require.Equal(t, len(app) > 0, ok) }) diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/application-fs.properties b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/application-fs.properties similarity index 100% rename from pkg/collector/corechecks/servicediscovery/usm/testdata/application-fs.properties rename to pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/application-fs.properties diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/bins/json-server b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/bins/json-server new file mode 120000 index 0000000000000..666af441b33a7 --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/bins/json-server @@ -0,0 +1 @@ +../json-server/lib/bin.js \ No newline at end of file diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/bins/notjs b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/bins/notjs new file mode 120000 index 0000000000000..b870225aa053e --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/bins/notjs @@ -0,0 +1 @@ +../ \ No newline at end of file diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/bins/package.json b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/bins/package.json new file mode 100644 index 0000000000000..5c8f1cc5a8a82 --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/bins/package.json @@ -0,0 +1,3 @@ +{ + "name": "should-not-be-used" +} diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/deep/index.js b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/deep/index.js similarity index 100% rename from pkg/collector/corechecks/servicediscovery/usm/testdata/deep/index.js rename to pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/deep/index.js diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/index.js b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/index.js similarity index 100% rename from pkg/collector/corechecks/servicediscovery/usm/testdata/index.js rename to pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/index.js diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/inner/package.json b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/inner/package.json similarity index 100% rename from pkg/collector/corechecks/servicediscovery/usm/testdata/inner/package.json rename to pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/inner/package.json diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/python/flask/__init__.py b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/json-server/lib/bin.js similarity index 100% rename from pkg/collector/corechecks/servicediscovery/usm/testdata/python/flask/__init__.py rename to pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/json-server/lib/bin.js diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/json-server/package.json b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/json-server/package.json new file mode 100644 index 0000000000000..7ba8c820db72f --- /dev/null +++ b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/json-server/package.json @@ -0,0 +1,3 @@ +{ + "name": "json-server-package" +} diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/package.json b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/package.json similarity index 100% rename from pkg/collector/corechecks/servicediscovery/usm/testdata/package.json rename to pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/package.json diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/tomcat/webapps/app1/touch b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/python/flask/__init__.py similarity index 100% rename from pkg/collector/corechecks/servicediscovery/usm/testdata/tomcat/webapps/app1/touch rename to pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/python/flask/__init__.py diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/tomcat/conf/server.xml b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/tomcat/conf/server.xml similarity index 100% rename from pkg/collector/corechecks/servicediscovery/usm/testdata/tomcat/conf/server.xml rename to pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/tomcat/conf/server.xml diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/tomcat/webapps/app2/touch b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/tomcat/webapps/app1/touch similarity index 100% rename from pkg/collector/corechecks/servicediscovery/usm/testdata/tomcat/webapps/app2/touch rename to pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/tomcat/webapps/app1/touch diff --git a/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/tomcat/webapps/app2/touch b/pkg/collector/corechecks/servicediscovery/usm/testdata/root/testdata/tomcat/webapps/app2/touch new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/pkg/collector/corechecks/servicediscovery/usm/tomcat.go b/pkg/collector/corechecks/servicediscovery/usm/tomcat.go index 3d895ffcc37b2..0271bd6772010 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/tomcat.go +++ b/pkg/collector/corechecks/servicediscovery/usm/tomcat.go @@ -11,7 +11,7 @@ import ( "path" "strings" - "go.uber.org/zap" + "github.com/DataDog/datadog-agent/pkg/util/log" ) // tomcat vendor specific constants @@ -80,7 +80,7 @@ func (te tomcatExtractor) findDeployedApps(domainHome string) ([]jeeDeployment, func (te tomcatExtractor) scanDirForDeployments(path string, uniques *map[string]struct{}) []jeeDeployment { entries, err := fs.ReadDir(te.ctx.fs, path) if err != nil { - te.ctx.logger.Debug("error while scanning tomcat deployments", zap.String("appBase", path), zap.Error(err)) + log.Debugf("error while scanning tomcat deployments (app base: %q). Err: %v", path, err) return nil } var ret []jeeDeployment @@ -129,13 +129,14 @@ func (te tomcatExtractor) parseServerXML(domainHome string) *tomcatServerXML { xmlFilePath := path.Join(domainHome, serverXMLPath) file, err := te.ctx.fs.Open(xmlFilePath) if err != nil { - te.ctx.logger.Debug("Unable to locate tomcat server.xml", zap.String("filepath", xmlFilePath), zap.Error(err)) + log.Debugf("Unable to locate tomcat server.xml (%q). Err: %v", xmlFilePath, err) return nil } + defer file.Close() var serverXML tomcatServerXML err = xml.NewDecoder(file).Decode(&serverXML) if err != nil { - te.ctx.logger.Debug("Unable to parse tomcat server.xml", zap.String("filepath", xmlFilePath), zap.Error(err)) + log.Debugf("Unable to parse tomcat server.xml (%q). Err: %v", xmlFilePath, err) return nil } return &serverXML diff --git a/pkg/collector/corechecks/servicediscovery/usm/tomcat_test.go b/pkg/collector/corechecks/servicediscovery/usm/tomcat_test.go index 53b12ca0e3f45..e28d630f0bfbd 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/tomcat_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/tomcat_test.go @@ -11,7 +11,6 @@ import ( "testing/fstest" "github.com/stretchr/testify/require" - "go.uber.org/zap" ) func TestTomcatDefaultContextRootFromFile(t *testing.T) { @@ -48,7 +47,7 @@ func TestTomcatDefaultContextRootFromFile(t *testing.T) { expected: "", }, } - extractor := newTomcatExtractor(NewDetectionContext(zap.NewNop(), nil, nil, nil)) + extractor := newTomcatExtractor(NewDetectionContext(nil, nil, nil)) for _, tt := range tests { t.Run("Should parse "+tt.filename, func(t *testing.T) { value, ok := extractor.defaultContextRootFromFile(tt.filename) @@ -93,7 +92,7 @@ func TestScanDirForDeployments(t *testing.T) { }, }, } - extractor := tomcatExtractor{ctx: NewDetectionContext(zap.NewNop(), nil, nil, memfs)} + extractor := tomcatExtractor{ctx: NewDetectionContext(nil, nil, memfs)} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { deployments := extractor.scanDirForDeployments(tt.path, &map[string]struct{}{ @@ -170,7 +169,7 @@ func TestFindDeployedApps(t *testing.T) { } for _, tt := range tests { - extractor := tomcatExtractor{ctx: NewDetectionContext(zap.NewNop(), nil, nil, tt.fs)} + extractor := tomcatExtractor{ctx: NewDetectionContext(nil, nil, tt.fs)} deployments, ok := extractor.findDeployedApps(tt.domainHome) require.Equal(t, len(tt.expected) > 0, ok) require.Equal(t, tt.expected, deployments) diff --git a/pkg/collector/corechecks/servicediscovery/usm/weblogic.go b/pkg/collector/corechecks/servicediscovery/usm/weblogic.go index 86483ecfe8219..fd56df2eba14a 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/weblogic.go +++ b/pkg/collector/corechecks/servicediscovery/usm/weblogic.go @@ -10,7 +10,7 @@ import ( "io/fs" "path" - "go.uber.org/zap" + "github.com/DataDog/datadog-agent/pkg/util/log" ) // weblogic vendor specific constants @@ -59,26 +59,28 @@ func (we weblogicExtractor) findDeployedApps(domainHome string) ([]jeeDeployment } serverConfigFile, err := we.ctx.fs.Open(path.Join(domainHome, wlsServerConfigDir, wlsServerConfigFile)) if err != nil { - we.ctx.logger.Debug("weblogic: unable to open config.xml", zap.Error(err)) + log.Debugf("weblogic: unable to open config.xml. Err: %v", err) return nil, false } defer serverConfigFile.Close() if ok, err := canSafelyParse(serverConfigFile); !ok { - we.ctx.logger.Debug("weblogic: config.xml looks too big", zap.Error(err)) + log.Debugf("weblogic: config.xml looks too big. Err: %v", err) return nil, false } var deployInfos weblogicDeploymentInfo err = xml.NewDecoder(serverConfigFile).Decode(&deployInfos) if err != nil { - we.ctx.logger.Debug("weblogic: cannot parse config.xml", zap.Error(err)) + log.Debugf("weblogic: cannot parse config.xml. Err: %v", err) return nil, false } var deployments []jeeDeployment for _, di := range deployInfos.AppDeployment { if di.StagingMode == "stage" && di.Target == serverName { _, name := path.Split(di.SourcePath) - deployments = append(deployments, jeeDeployment{name: name, path: di.SourcePath}) + // The original code did not have the domainHome addition here, + // unlike in jboss/tomcat. + deployments = append(deployments, jeeDeployment{name: name, path: abs(di.SourcePath, domainHome)}) } } return deployments, len(deployments) > 0 diff --git a/pkg/collector/corechecks/servicediscovery/usm/weblogic_nix_test.go b/pkg/collector/corechecks/servicediscovery/usm/weblogic_nix_test.go index 4400fdea2f24a..70866b660f3af 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/weblogic_nix_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/weblogic_nix_test.go @@ -16,8 +16,6 @@ import ( "testing" "testing/fstest" - "go.uber.org/zap" - "github.com/stretchr/testify/require" ) @@ -25,9 +23,6 @@ import ( // The file contains staged and non-staged deployments for different servers. // It is expected that only the staged deployment of `AdminServer` are returned. func TestWeblogicFindDeployedApps(t *testing.T) { - cwd, err := os.Getwd() - require.NoError(t, err) - tests := []struct { name string serverName string @@ -38,12 +33,12 @@ func TestWeblogicFindDeployedApps(t *testing.T) { { name: "multiple deployments for multiple server - extract for AdminServer", serverName: "AdminServer", - domainHome: abs(weblogicTestAppRoot, cwd), - fs: RealFs{}, + domainHome: weblogicTestAppRootAbsolute, + fs: MakeTestSubDirFS(t), expected: []jeeDeployment{ { name: "test.war", - path: weblogicTestAppRoot + "/test.war", + path: weblogicTestAppRootAbsolute + "/test.war", }, { name: "sample4.war", @@ -51,7 +46,7 @@ func TestWeblogicFindDeployedApps(t *testing.T) { }, { name: "test.ear", - path: weblogicTestAppRoot + "/test.ear", + path: weblogicTestAppRootAbsolute + "/test.ear", }, }, }, @@ -80,7 +75,7 @@ func TestWeblogicFindDeployedApps(t *testing.T) { if len(tt.serverName) > 0 { args = append(args, wlsServerNameSysProp+tt.serverName) } - value, ok := weblogicExtractor{ctx: NewDetectionContext(zap.NewNop(), args, nil, tt.fs)}.findDeployedApps(tt.domainHome) + value, ok := weblogicExtractor{ctx: NewDetectionContext(args, nil, tt.fs)}.findDeployedApps(tt.domainHome) require.Equal(t, len(value) > 0, ok) require.Equal(t, tt.expected, value) }) @@ -138,7 +133,7 @@ http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">inva // now create a zip reader to pass to the tested function reader, err := zip.NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len())) require.NoError(t, err) - value, ok := newWeblogicExtractor(NewDetectionContext(zap.NewNop(), nil, nil, nil)).customExtractWarContextRoot(reader) + value, ok := newWeblogicExtractor(NewDetectionContext(nil, nil, nil)).customExtractWarContextRoot(reader) require.Equal(t, len(tt.expected) > 0, ok) require.Equal(t, tt.expected, value) }) @@ -150,8 +145,8 @@ http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">inva func TestWeblogicExtractExplodedWarContextRoot(t *testing.T) { cwd, err := os.Getwd() require.NoError(t, err) - fs := os.DirFS(path.Join(cwd, weblogicTestAppRoot, "test.war")) - value, ok := newWeblogicExtractor(NewDetectionContext(zap.NewNop(), nil, nil, nil)).customExtractWarContextRoot(fs) + fs := os.DirFS(path.Join(cwd, "../../../../discovery/testdata/root/testdata/b", "test.war")) + value, ok := newWeblogicExtractor(NewDetectionContext(nil, nil, nil)).customExtractWarContextRoot(fs) require.True(t, ok) require.Equal(t, "my_context", value) } diff --git a/pkg/collector/corechecks/servicediscovery/usm/websphere.go b/pkg/collector/corechecks/servicediscovery/usm/websphere.go index c2731f7dc3339..52f58931703bc 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/websphere.go +++ b/pkg/collector/corechecks/servicediscovery/usm/websphere.go @@ -11,7 +11,7 @@ import ( "io/fs" "path" - "go.uber.org/zap" + "github.com/DataDog/datadog-agent/pkg/util/log" ) type ( @@ -101,7 +101,7 @@ func (we websphereExtractor) findDeployedApps(domainHome string) ([]jeeDeploymen dt: ear, }) } else if err != nil { - we.ctx.logger.Debug("websphere: unable to know if an application is deployed", zap.String("path", m), zap.Error(err)) + log.Debugf("websphere: unable to know if an application is deployed (path %q). Err: %v", m, err) } } return apps, len(apps) > 0 diff --git a/pkg/collector/corechecks/servicediscovery/usm/websphere_test.go b/pkg/collector/corechecks/servicediscovery/usm/websphere_test.go index e99d700f3a0be..fd7a476d8eb9f 100644 --- a/pkg/collector/corechecks/servicediscovery/usm/websphere_test.go +++ b/pkg/collector/corechecks/servicediscovery/usm/websphere_test.go @@ -10,8 +10,6 @@ import ( "testing" "testing/fstest" - "go.uber.org/zap" - "github.com/stretchr/testify/require" ) @@ -112,7 +110,7 @@ func TestWebsphereFindDeployedApps(t *testing.T) { &fstest.MapFile{Data: []byte(tt.deploymentXML)} } - value, ok := newWebsphereExtractor(NewDetectionContext(zap.NewNop(), tt.args, nil, fs)).findDeployedApps("base") + value, ok := newWebsphereExtractor(NewDetectionContext(tt.args, nil, fs)).findDeployedApps("base") require.Equal(t, tt.expected, value) require.Equal(t, len(value) > 0, ok) }) @@ -120,7 +118,7 @@ func TestWebsphereFindDeployedApps(t *testing.T) { } func TestWebsphereDefaultContextRootFromFile(t *testing.T) { - value, ok := newWebsphereExtractor(NewDetectionContext(zap.NewNop(), nil, nil, nil)).defaultContextRootFromFile("myapp.war") + value, ok := newWebsphereExtractor(NewDetectionContext(nil, nil, nil)).defaultContextRootFromFile("myapp.war") require.Equal(t, "myapp", value) require.True(t, ok) } diff --git a/pkg/collector/corechecks/snmp/internal/discovery/discovery.go b/pkg/collector/corechecks/snmp/internal/discovery/discovery.go index 6347d190b1244..edf691e7e804f 100644 --- a/pkg/collector/corechecks/snmp/internal/discovery/discovery.go +++ b/pkg/collector/corechecks/snmp/internal/discovery/discovery.go @@ -101,7 +101,7 @@ func (d *Discovery) runWorker(w int, jobs <-chan checkDeviceJob) { log.Debugf("subnet %s: Handling IP %s", d.config.Network, job.currentIP.String()) err := d.checkDevice(job) if err != nil { - log.Errorf(err.Error()) + log.Errorf("%s", err.Error()) } } } @@ -139,7 +139,7 @@ func (d *Discovery) discoverDevices() { } discoveryTicker := time.NewTicker(time.Duration(d.config.DiscoveryInterval) * time.Second) - + defer discoveryTicker.Stop() for { log.Debugf("subnet %s: Run discovery", d.config.Network) startingIP := make(net.IP, len(subnet.startingIP)) diff --git a/pkg/collector/corechecks/systemd/systemd.go b/pkg/collector/corechecks/systemd/systemd.go index e1596d6653e5d..186403222d5fc 100644 --- a/pkg/collector/corechecks/systemd/systemd.go +++ b/pkg/collector/corechecks/systemd/systemd.go @@ -20,7 +20,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/pkg/aggregator/sender" "github.com/DataDog/datadog-agent/pkg/collector/check" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/metrics/servicecheck" "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/DataDog/datadog-agent/pkg/util/optional" @@ -272,7 +272,7 @@ func (c *SystemdCheck) getDbusConnection() (*dbus.Conn, error) { conn, err = c.getPrivateSocketConnection(c.config.instance.PrivateSocket) } else { defaultPrivateSocket := "/run/systemd/private" - if config.IsContainerized() { + if env.IsContainerized() { conn, err = c.getPrivateSocketConnection("/host" + defaultPrivateSocket) } else { conn, err = c.getSystemBusSocketConnection() @@ -411,9 +411,9 @@ func (c *SystemdCheck) submitPropertyMetricsAsGauge(sender sender.Sender, conn * if err != nil { msg := fmt.Sprintf("Cannot send property '%s' for unit '%s': %v", service.propertyName, unit.Name, err) if service.optional { - log.Debugf(msg) + log.Debugf("%s", msg) } else { - log.Warnf(msg) + log.Warnf("%s", msg) } } } diff --git a/pkg/collector/loaders/loaders_test.go b/pkg/collector/loaders/loaders_test.go index 594c694879cbe..1d12c7a683035 100644 --- a/pkg/collector/loaders/loaders_test.go +++ b/pkg/collector/loaders/loaders_test.go @@ -14,7 +14,6 @@ import ( "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/def" - "github.com/DataDog/datadog-agent/comp/logs/integrations/mock" "github.com/DataDog/datadog-agent/pkg/aggregator/mocksender" "github.com/DataDog/datadog-agent/pkg/aggregator/sender" "github.com/DataDog/datadog-agent/pkg/collector/check" @@ -75,7 +74,7 @@ func TestLoaderCatalog(t *testing.T) { RegisterLoader(10, factory2) RegisterLoader(30, factory3) senderManager := mocksender.CreateDefaultDemultiplexer() - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() require.Len(t, LoaderCatalog(senderManager, logReceiver), 2) assert.Equal(t, l1, LoaderCatalog(senderManager, logReceiver)[1]) assert.Equal(t, l2, LoaderCatalog(senderManager, logReceiver)[0]) diff --git a/pkg/collector/python/init.go b/pkg/collector/python/init.go index 3cc6c140ae432..5b905debba7ba 100644 --- a/pkg/collector/python/init.go +++ b/pkg/collector/python/init.go @@ -8,6 +8,7 @@ package python import ( + "errors" "expvar" "fmt" "os" @@ -258,7 +259,7 @@ func addExpvarPythonInitErrors(msg string) error { defer pyInitLock.Unlock() pyInitErrors = append(pyInitErrors, msg) - return fmt.Errorf(msg) + return errors.New(msg) } func sendTelemetry(pythonVersion string) { diff --git a/pkg/collector/python/loader.go b/pkg/collector/python/loader.go index 4a565fceb2699..969a3e10c07f9 100644 --- a/pkg/collector/python/loader.go +++ b/pkg/collector/python/loader.go @@ -84,12 +84,16 @@ func init() { // PythonCheckLoader is a specific loader for checks living in Python modules // //nolint:revive // TODO(AML) Fix revive linter -type PythonCheckLoader struct{} +type PythonCheckLoader struct { + logReceiver optional.Option[integrations.Component] +} // NewPythonCheckLoader creates an instance of the Python checks loader func NewPythonCheckLoader(senderManager sender.SenderManager, logReceiver optional.Option[integrations.Component]) (*PythonCheckLoader, error) { initializeCheckContext(senderManager, logReceiver) - return &PythonCheckLoader{}, nil + return &PythonCheckLoader{ + logReceiver: logReceiver, + }, nil } func getRtLoaderError() error { @@ -220,6 +224,10 @@ func (cl *PythonCheckLoader) Load(senderManager sender.SenderManager, config int return c, fmt.Errorf("could not configure check instance for python check %s: %s", moduleName, err.Error()) } + if v, ok := cl.logReceiver.Get(); ok { + v.RegisterIntegration(string(c.id), config) + } + c.version = wheelVersion C.rtloader_decref(rtloader, checkClass) C.rtloader_decref(rtloader, checkModule) diff --git a/pkg/collector/python/test_aggregator.go b/pkg/collector/python/test_aggregator.go index a982015eb2269..d9b0b07402089 100644 --- a/pkg/collector/python/test_aggregator.go +++ b/pkg/collector/python/test_aggregator.go @@ -11,7 +11,6 @@ import ( "testing" integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/def" - "github.com/DataDog/datadog-agent/comp/logs/integrations/mock" "github.com/DataDog/datadog-agent/pkg/aggregator/mocksender" "github.com/DataDog/datadog-agent/pkg/aggregator/sender" checkid "github.com/DataDog/datadog-agent/pkg/collector/check/id" @@ -25,7 +24,7 @@ import "C" func testSubmitMetric(t *testing.T) { sender := mocksender.NewMockSender(checkid.ID("testID")) - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() release := scopeInitCheckContext(sender.GetSenderManager(), logReceiver) defer release() @@ -101,7 +100,7 @@ func testSubmitMetric(t *testing.T) { func testSubmitMetricEmptyTags(t *testing.T) { sender := mocksender.NewMockSender(checkid.ID("testID")) - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() release := scopeInitCheckContext(sender.GetSenderManager(), logReceiver) defer release() @@ -121,7 +120,7 @@ func testSubmitMetricEmptyTags(t *testing.T) { func testSubmitMetricEmptyHostname(t *testing.T) { sender := mocksender.NewMockSender(checkid.ID("testID")) - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() release := scopeInitCheckContext(sender.GetSenderManager(), logReceiver) defer release() @@ -141,7 +140,7 @@ func testSubmitMetricEmptyHostname(t *testing.T) { func testSubmitServiceCheck(t *testing.T) { sender := mocksender.NewMockSender(checkid.ID("testID")) - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() release := scopeInitCheckContext(sender.GetSenderManager(), logReceiver) defer release() @@ -160,7 +159,7 @@ func testSubmitServiceCheck(t *testing.T) { func testSubmitServiceCheckEmptyTag(t *testing.T) { sender := mocksender.NewMockSender(checkid.ID("testID")) - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() release := scopeInitCheckContext(sender.GetSenderManager(), logReceiver) defer release() @@ -179,7 +178,7 @@ func testSubmitServiceCheckEmptyTag(t *testing.T) { func testSubmitServiceCheckEmptyHostame(t *testing.T) { sender := mocksender.NewMockSender(checkid.ID("testID")) - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() release := scopeInitCheckContext(sender.GetSenderManager(), logReceiver) defer release() @@ -198,7 +197,7 @@ func testSubmitServiceCheckEmptyHostame(t *testing.T) { func testSubmitEvent(t *testing.T) { sender := mocksender.NewMockSender(checkid.ID("testID")) - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() release := scopeInitCheckContext(sender.GetSenderManager(), logReceiver) defer release() @@ -235,7 +234,7 @@ func testSubmitEvent(t *testing.T) { func testSubmitHistogramBucket(t *testing.T) { sender := mocksender.NewMockSender(checkid.ID("testID")) - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() release := scopeInitCheckContext(sender.GetSenderManager(), logReceiver) defer release() @@ -259,7 +258,7 @@ func testSubmitHistogramBucket(t *testing.T) { func testSubmitEventPlatformEvent(t *testing.T) { sender := mocksender.NewMockSender("testID") - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() release := scopeInitCheckContext(sender.GetSenderManager(), logReceiver) defer release() diff --git a/pkg/collector/python/test_loader.go b/pkg/collector/python/test_loader.go index 3295c01fe6155..b0af8775925e4 100644 --- a/pkg/collector/python/test_loader.go +++ b/pkg/collector/python/test_loader.go @@ -12,7 +12,7 @@ import ( "testing" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" - "github.com/DataDog/datadog-agent/comp/logs/integrations/mock" + integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/def" "github.com/DataDog/datadog-agent/pkg/aggregator/mocksender" "github.com/DataDog/datadog-agent/pkg/util/optional" @@ -141,7 +141,7 @@ func testLoadCustomCheck(t *testing.T) { rtloader = newMockRtLoaderPtr() defer func() { rtloader = nil }() senderManager := mocksender.CreateDefaultDemultiplexer() - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() loader, err := NewPythonCheckLoader(senderManager, logReceiver) assert.Nil(t, err) @@ -179,7 +179,7 @@ func testLoadWheelCheck(t *testing.T) { defer func() { rtloader = nil }() senderManager := mocksender.CreateDefaultDemultiplexer() - logReceiver := optional.NewOption(mock.Mock()) + logReceiver := optional.NewNoneOption[integrations.Component]() loader, err := NewPythonCheckLoader(senderManager, logReceiver) assert.Nil(t, err) diff --git a/pkg/collector/scheduler.go b/pkg/collector/scheduler.go index 0b32dd70150cc..e61b3f7dc7690 100644 --- a/pkg/collector/scheduler.go +++ b/pkg/collector/scheduler.go @@ -214,10 +214,6 @@ func (s *CheckScheduler) getChecks(config integration.Config) ([]check.Check, er } } - if len(checks) == 0 { - return checks, fmt.Errorf("unable to load any check from config '%s'", config.Name) - } - return checks, nil } diff --git a/pkg/compliance/agent.go b/pkg/compliance/agent.go index 2b44199c3459b..d7d2dfb9acae6 100644 --- a/pkg/compliance/agent.go +++ b/pkg/compliance/agent.go @@ -30,6 +30,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/compliance/metrics" "github.com/DataDog/datadog-agent/pkg/compliance/utils" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/security/rules" secl "github.com/DataDog/datadog-agent/pkg/security/secl/rules" "github.com/DataDog/datadog-agent/pkg/security/telemetry" @@ -135,7 +136,7 @@ func xccdfEnabled() bool { // will exclude rules based on the evaluation context / environment running // the benchmark. func DefaultRuleFilter(r *Rule) bool { - if config.IsKubernetes() { + if env.IsKubernetes() { if r.SkipOnK8s { return false } @@ -390,7 +391,7 @@ func (a *Agent) runXCCDFBenchmarks(ctx context.Context) { } func (a *Agent) runKubernetesConfigurationsExport(ctx context.Context) { - if !config.IsKubernetes() { + if !env.IsKubernetes() { return } diff --git a/pkg/compliance/evaluator_rego.go b/pkg/compliance/evaluator_rego.go index 2e2106e88e234..a6456ad0f2242 100644 --- a/pkg/compliance/evaluator_rego.go +++ b/pkg/compliance/evaluator_rego.go @@ -8,6 +8,7 @@ package compliance import ( "context" "encoding/json" + "errors" "fmt" "os" "strconv" @@ -117,7 +118,7 @@ func newCheckEventFromRegoResult(data interface{}, rule *Rule, resolvedInputs Re if errMsg == "" { errMsg = "unknown" } - errReason = fmt.Errorf(errMsg) + errReason = errors.New(errMsg) default: errReason = fmt.Errorf("rego result invalid: bad status %q", status) } diff --git a/pkg/compliance/evaluator_xccdf.go b/pkg/compliance/evaluator_xccdf.go index 146d70a24311f..70e545cc8d91e 100644 --- a/pkg/compliance/evaluator_xccdf.go +++ b/pkg/compliance/evaluator_xccdf.go @@ -22,7 +22,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/compliance/metrics" "github.com/DataDog/datadog-agent/pkg/compliance/scap" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/executable" "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/DataDog/datadog-agent/pkg/version" @@ -93,7 +93,7 @@ func newOSCAPIO(file string) *oscapIO { func (p *oscapIO) Run(ctx context.Context) error { defer p.Stop() - if config.IsContainerized() { + if env.IsContainerized() { hostRoot := os.Getenv("HOST_ROOT") if hostRoot == "" { hostRoot = "/host" diff --git a/pkg/compliance/reporter.go b/pkg/compliance/reporter.go index 22c5da998c0b0..2bbf3a39f4c27 100644 --- a/pkg/compliance/reporter.go +++ b/pkg/compliance/reporter.go @@ -50,9 +50,8 @@ func NewLogReporter(hostname string, sourceName, sourceType string, endpoints *c logSource := sources.NewLogSource( sourceName, &config.LogsConfig{ - Type: sourceType, - Service: sourceName, - Source: sourceName, + Type: sourceType, + Source: sourceName, }, ) logChan := pipelineProvider.NextPipelineChan() diff --git a/pkg/config/aliases.go b/pkg/config/aliases.go index df18cff011c7a..159d7e2300dca 100644 --- a/pkg/config/aliases.go +++ b/pkg/config/aliases.go @@ -39,43 +39,6 @@ var NewConfig = model.NewConfig // Warnings represent the warnings in the config type Warnings = model.Warnings -// environment Aliases -var ( - IsFeaturePresent = env.IsFeaturePresent - IsECS = env.IsECS - IsKubernetes = env.IsKubernetes - IsECSFargate = env.IsECSFargate - IsServerless = env.IsServerless - IsContainerized = env.IsContainerized - IsDockerRuntime = env.IsDockerRuntime - IsHostProcAvailable = env.IsHostProcAvailable - IsHostSysAvailable = env.IsHostSysAvailable - IsAnyContainerFeaturePresent = env.IsAnyContainerFeaturePresent - GetDetectedFeatures = env.GetDetectedFeatures -) - -type ( - // Feature Alias - Feature = env.Feature - // FeatureMap Alias - FeatureMap = env.FeatureMap -) - -// Aliases for constants -const ( - ECSFargate = env.ECSFargate - Podman = env.Podman - Docker = env.Docker - EKSFargate = env.EKSFargate - ECSEC2 = env.ECSEC2 - Kubernetes = env.Kubernetes - CloudFoundry = env.CloudFoundry - Cri = env.Cri - Containerd = env.Containerd - KubeOrchestratorExplorer = env.KubeOrchestratorExplorer - ECSOrchestratorExplorer = env.ECSOrchestratorExplorer -) - var ( // Datadog Alias Datadog = pkgconfigsetup.Datadog diff --git a/pkg/config/autodiscovery/autodiscovery.go b/pkg/config/autodiscovery/autodiscovery.go index cc00406954992..ccd4ae2930eb4 100644 --- a/pkg/config/autodiscovery/autodiscovery.go +++ b/pkg/config/autodiscovery/autodiscovery.go @@ -12,6 +12,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/autodiscovery/providers" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/providers/names" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" snmplistener "github.com/DataDog/datadog-agent/pkg/snmp" "github.com/DataDog/datadog-agent/pkg/util/flavor" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -100,11 +101,11 @@ func DiscoverComponentsFromEnv() ([]config.ConfigurationProviders, []config.List return detectedProviders, detectedListeners } - isContainerEnv := config.IsFeaturePresent(config.Docker) || - config.IsFeaturePresent(config.Containerd) || - config.IsFeaturePresent(config.Podman) || - config.IsFeaturePresent(config.ECSFargate) - isKubeEnv := config.IsFeaturePresent(config.Kubernetes) + isContainerEnv := env.IsFeaturePresent(env.Docker) || + env.IsFeaturePresent(env.Containerd) || + env.IsFeaturePresent(env.Podman) || + env.IsFeaturePresent(env.ECSFargate) + isKubeEnv := env.IsFeaturePresent(env.Kubernetes) if isContainerEnv || isKubeEnv { detectedProviders = append(detectedProviders, config.ConfigurationProviders{Name: names.KubeContainer}) diff --git a/pkg/config/config_template.yaml b/pkg/config/config_template.yaml index a53836464ca73..e01a2e747831b 100644 --- a/pkg/config/config_template.yaml +++ b/pkg/config/config_template.yaml @@ -3196,6 +3196,13 @@ api_key: # # ecs_metadata_timeout: 500 +## @param ecs_task_collection_enabled - boolean - optional - default: false +## @env DD_ECS_TASK_COLLECTION_ENABLED - boolean - optional - default: false +## The Agent can collect detailed task information from the metadata API exposed by the ECS Agent, +## which is used for the orchestrator ECS check. +# +# ecs_task_collection_enabled: false + {{ end -}} {{- if .CRI }} diff --git a/pkg/config/env/go.mod b/pkg/config/env/go.mod index d33c6292751a3..48ebc42d093c0 100644 --- a/pkg/config/env/go.mod +++ b/pkg/config/env/go.mod @@ -41,12 +41,12 @@ require ( github.com/spf13/pflag v1.0.3 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/config/env/go.sum b/pkg/config/env/go.sum index e95a454a74317..7e9473fb01e18 100644 --- a/pkg/config/env/go.sum +++ b/pkg/config/env/go.sum @@ -191,8 +191,8 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -235,11 +235,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -252,8 +252,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/config/legacy_converter.go b/pkg/config/legacy_converter.go index 07de5a612396d..f0b173070893a 100644 --- a/pkg/config/legacy_converter.go +++ b/pkg/config/legacy_converter.go @@ -6,8 +6,6 @@ package config import ( - "strings" - "github.com/DataDog/datadog-agent/pkg/config/model" pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" ) @@ -25,10 +23,5 @@ func (c *LegacyConfigConverter) Set(key string, value interface{}) { // NewConfigConverter is creating and returning a config converter func NewConfigConverter() *LegacyConfigConverter { - // Configure Datadog global configuration - newCfg := NewConfig("datadog", "DD", strings.NewReplacer(".", "_")) - // Configuration defaults - pkgconfigsetup.SetDatadog(newCfg) - pkgconfigsetup.InitConfig(newCfg) - return &LegacyConfigConverter{newCfg} + return &LegacyConfigConverter{pkgconfigsetup.Datadog()} } diff --git a/pkg/config/mock.go b/pkg/config/mock.go deleted file mode 100644 index d336128dadebb..0000000000000 --- a/pkg/config/mock.go +++ /dev/null @@ -1,72 +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 2016-present Datadog, Inc. - -package config - -import ( - "strings" - "sync" - "testing" - - "github.com/DataDog/datadog-agent/pkg/config/model" - pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" -) - -var ( - isSystemProbeConfigMocked = false - m = sync.Mutex{} -) - -// mockConfig should only be used in tests -type mockConfig struct { - Config -} - -// Set is used for setting configuration in tests -func (c *mockConfig) Set(key string, value interface{}, source model.Source) { - c.Config.Set(key, value, source) -} - -// SetWithoutSource is used for setting configuration in tests -func (c *mockConfig) SetWithoutSource(key string, value interface{}) { - c.Config.SetWithoutSource(key, value) -} - -// SetKnown is used for setting configuration in tests -func (c *mockConfig) SetKnown(key string) { - c.Config.SetKnown(key) -} - -// MockSystemProbe is creating and returning a mock system-probe Config -// -// This method is deprecated and will soon be removed. Use pkg/config/mock.NewSystemProbe instead. -func MockSystemProbe(t testing.TB) model.Config { - // We only check isSystemProbeConfigMocked when registering a cleanup function. 'isSystemProbeConfigMocked' - // avoids nested calls to Mock to reset the config to a blank state. This way we have only one mock per test and - // test helpers can call Mock. - if t != nil { - m.Lock() - defer m.Unlock() - if isSystemProbeConfigMocked { - // The configuration is already mocked. - return &mockConfig{pkgconfigsetup.SystemProbe()} - } - - isSystemProbeConfigMocked = true - originalConfig := pkgconfigsetup.SystemProbe() - t.Cleanup(func() { - m.Lock() - defer m.Unlock() - isSystemProbeConfigMocked = false - pkgconfigsetup.SetSystemProbe(originalConfig) - }) - } - - // Configure Datadog global configuration - pkgconfigsetup.SetSystemProbe(NewConfig("system-probe", "DD", strings.NewReplacer(".", "_"))) - // Configuration defaults - pkgconfigsetup.InitSystemProbeConfig(pkgconfigsetup.SystemProbe()) - return &mockConfig{pkgconfigsetup.SystemProbe()} -} diff --git a/pkg/config/mock/go.mod b/pkg/config/mock/go.mod index 3ba6dc30feeb6..88d2f94e90167 100644 --- a/pkg/config/mock/go.mod +++ b/pkg/config/mock/go.mod @@ -49,6 +49,7 @@ replace github.com/DataDog/datadog-agent/pkg/util/testutil => ../../../pkg/util/ require ( github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/config/setup v0.0.0-00010101000000-000000000000 + github.com/stretchr/testify v1.9.0 ) require ( @@ -68,6 +69,7 @@ require ( github.com/DataDog/viper v1.13.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -78,6 +80,7 @@ require ( github.com/mitchellh/mapstructure v1.1.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/pelletier/go-toml v1.2.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/shirou/gopsutil/v3 v3.23.12 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect @@ -89,11 +92,12 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/config/mock/go.sum b/pkg/config/mock/go.sum index 79c2fcb395d02..77ba213060c82 100644 --- a/pkg/config/mock/go.sum +++ b/pkg/config/mock/go.sum @@ -234,25 +234,25 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -295,11 +295,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -312,8 +312,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/config/mock/mock.go b/pkg/config/mock/mock.go index c9646063f7fa9..407bbc41ee7a3 100644 --- a/pkg/config/mock/mock.go +++ b/pkg/config/mock/mock.go @@ -7,12 +7,14 @@ package mock import ( + "bytes" "strings" "sync" "testing" "github.com/DataDog/datadog-agent/pkg/config/model" "github.com/DataDog/datadog-agent/pkg/config/setup" + "github.com/stretchr/testify/require" ) var ( @@ -43,26 +45,21 @@ func (c *mockConfig) SetKnown(key string) { // New creates a mock for the config func New(t testing.TB) model.Config { - // We only check isConfigMocked when registering a cleanup function. 'isConfigMocked' avoids nested calls to - // Mock to reset the config to a blank state. This way we have only one mock per test and test helpers can call - // Mock. - if t != nil { + m.Lock() + defer m.Unlock() + if isConfigMocked { + // The configuration is already mocked. + return &mockConfig{setup.Datadog()} + } + + isConfigMocked = true + originalDatadogConfig := setup.Datadog() + t.Cleanup(func() { m.Lock() defer m.Unlock() - if isConfigMocked { - // The configuration is already mocked. - return &mockConfig{setup.Datadog()} - } - - isConfigMocked = true - originalDatadogConfig := setup.Datadog() - t.Cleanup(func() { - m.Lock() - defer m.Unlock() - isConfigMocked = false - setup.SetDatadog(originalDatadogConfig) - }) - } + isConfigMocked = false + setup.SetDatadog(originalDatadogConfig) + }) // Configure Datadog global configuration newCfg := model.NewConfig("datadog", "DD", strings.NewReplacer(".", "_")) @@ -72,6 +69,25 @@ func New(t testing.TB) model.Config { return &mockConfig{newCfg} } +// NewFromYAML creates a mock for the config and load the give YAML +func NewFromYAML(t testing.TB, yamlData string) model.Config { + conf := New(t) + conf.SetConfigType("yaml") + err := conf.ReadConfig(bytes.NewBuffer([]byte(yamlData))) + require.NoError(t, err) + return conf +} + +// NewFromFile creates a mock for the config and load the give YAML +func NewFromFile(t testing.TB, yamlFilePath string) model.Config { + conf := New(t) + conf.SetConfigType("yaml") + conf.SetConfigFile(yamlFilePath) + err := conf.ReadInConfig() + require.NoErrorf(t, err, "error loading yaml config file '%s'", yamlFilePath) + return conf +} + // NewSystemProbe creates a mock for the system-probe config func NewSystemProbe(t testing.TB) model.Config { // We only check isSystemProbeConfigMocked when registering a cleanup function. 'isSystemProbeConfigMocked' diff --git a/pkg/config/model/go.mod b/pkg/config/model/go.mod index 27bc9e41a664b..6d714751b915c 100644 --- a/pkg/config/model/go.mod +++ b/pkg/config/model/go.mod @@ -13,9 +13,8 @@ require ( github.com/DataDog/viper v1.13.5 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 github.com/spf13/afero v1.1.2 - github.com/spf13/pflag v1.0.3 github.com/stretchr/testify v1.9.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa ) require ( @@ -30,9 +29,10 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/cast v1.3.0 // indirect github.com/spf13/jwalterweatherman v1.0.0 // indirect + github.com/spf13/pflag v1.0.3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/config/model/go.sum b/pkg/config/model/go.sum index 19ac313639bcd..0635f691ae9fb 100644 --- a/pkg/config/model/go.sum +++ b/pkg/config/model/go.sum @@ -167,8 +167,8 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -201,11 +201,11 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/pkg/config/model/types.go b/pkg/config/model/types.go index 441db450ddb13..5613a41dbcef1 100644 --- a/pkg/config/model/types.go +++ b/pkg/config/model/types.go @@ -12,7 +12,6 @@ import ( "github.com/DataDog/viper" "github.com/spf13/afero" - "github.com/spf13/pflag" ) // Proxy represents the configuration for proxies in the agent @@ -111,7 +110,15 @@ type Setup interface { SetEnvPrefix(in string) BindEnv(input ...string) SetEnvKeyReplacer(r *strings.Replacer) + + // SetEnvKeyTransformer is deprecated in favor of ParseEnvAs* functions SetEnvKeyTransformer(key string, fn func(string) interface{}) + // The following helpers allow a type to be enforce when parsing environment variables. Most of them exists to + // support historic behavior. Refrain from adding more as it's most likely a sign of poorly design configuration + // layout. + ParseEnvAsStringSlice(key string, fx func(string) []string) + ParseEnvAsMapStringInterface(key string, fx func(string) map[string]interface{}) + ParseEnvAsSliceMapString(key string, fx func(string) []map[string]string) // SetKnown adds a key to the set of known valid config keys SetKnown(key string) @@ -144,8 +151,6 @@ type Compound interface { SetConfigName(in string) SetConfigFile(in string) SetConfigType(in string) - - BindPFlag(key string, flag *pflag.Flag) error } // Config represents an object that can load and store configuration parameters diff --git a/pkg/config/model/viper.go b/pkg/config/model/viper.go index a9b86a44bd7cb..9cf12b87e680e 100644 --- a/pkg/config/model/viper.go +++ b/pkg/config/model/viper.go @@ -11,6 +11,7 @@ import ( "fmt" "io" "os" + "path" "reflect" "strconv" "strings" @@ -22,7 +23,6 @@ import ( "github.com/DataDog/viper" "github.com/mohae/deepcopy" "github.com/spf13/afero" - "github.com/spf13/pflag" "golang.org/x/exp/slices" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -238,12 +238,36 @@ func (c *safeConfig) GetKnownKeysLowercased() map[string]interface{} { // SetEnvKeyTransformer allows defining a transformer function which decides // how an environment variables value gets assigned to key. +// +// [DEPRECATED] This function will soon be remove. Use one of the ParseEnvAs* helpers instead. func (c *safeConfig) SetEnvKeyTransformer(key string, fn func(string) interface{}) { c.Lock() defer c.Unlock() c.Viper.SetEnvKeyTransformer(key, fn) } +// ParseEnvAsStringSlice registers a transformer function to parse an an environment variables as a []string. +func (c *safeConfig) ParseEnvAsStringSlice(key string, fn func(string) []string) { + c.Lock() + defer c.Unlock() + c.Viper.SetEnvKeyTransformer(key, func(data string) interface{} { return fn(data) }) +} + +// ParseEnvAsMapStringInterface registers a transformer function to parse an an environment variables as a +// map[string]interface{}. +func (c *safeConfig) ParseEnvAsMapStringInterface(key string, fn func(string) map[string]interface{}) { + c.Lock() + defer c.Unlock() + c.Viper.SetEnvKeyTransformer(key, func(data string) interface{} { return fn(data) }) +} + +// ParseEnvAsSliceMapString registers a transformer function to parse an an environment variables as a []map[string]string. +func (c *safeConfig) ParseEnvAsSliceMapString(key string, fn func(string) []map[string]string) { + c.Lock() + defer c.Unlock() + c.Viper.SetEnvKeyTransformer(key, func(data string) interface{} { return fn(data) }) +} + // SetFs wraps Viper for concurrent access func (c *safeConfig) SetFs(fs afero.Fs) { c.Lock() @@ -643,6 +667,7 @@ func (c *safeConfig) MergeFleetPolicy(configPath string) error { for _, key := range c.configSources[SourceFleetPolicies].AllKeys() { c.mergeViperInstances(key) } + log.Infof("Fleet policies configuration %s successfully merged", path.Base(configPath)) return nil } @@ -775,13 +800,6 @@ func (c *safeConfig) SetTypeByDefaultValue(in bool) { c.Viper.SetTypeByDefaultValue(in) } -// BindPFlag wraps Viper for concurrent access -func (c *safeConfig) BindPFlag(key string, flag *pflag.Flag) error { - c.Lock() - defer c.Unlock() - return c.Viper.BindPFlag(key, flag) -} - // GetEnvVars implements the Config interface func (c *safeConfig) GetEnvVars() []string { c.RLock() diff --git a/pkg/config/model/viper_test.go b/pkg/config/model/viper_test.go index ea54fe712fc90..83bec5ee7a66b 100644 --- a/pkg/config/model/viper_test.go +++ b/pkg/config/model/viper_test.go @@ -418,3 +418,34 @@ func TestMergeFleetPolicy(t *testing.T) { assert.Equal(t, "baz", config.Get("foo")) assert.Equal(t, SourceFleetPolicies, config.GetSource("foo")) } + +func TestParseEnvAsStringSlice(t *testing.T) { + config := NewConfig("test", "DD", strings.NewReplacer(".", "_")) + + config.BindEnv("slice_of_string") + config.ParseEnvAsStringSlice("slice_of_string", func(string) []string { return []string{"a", "b", "c"} }) + + t.Setenv("DD_SLICE_OF_STRING", "__some_data__") + assert.Equal(t, []string{"a", "b", "c"}, config.Get("slice_of_string")) +} + +func TestParseEnvAsMapStringInterface(t *testing.T) { + config := NewConfig("test", "DD", strings.NewReplacer(".", "_")) + + config.BindEnv("map_of_float") + config.ParseEnvAsMapStringInterface("map_of_float", func(string) map[string]interface{} { return map[string]interface{}{"a": 1.0, "b": 2.0, "c": 3.0} }) + + t.Setenv("DD_MAP_OF_FLOAT", "__some_data__") + assert.Equal(t, map[string]interface{}{"a": 1.0, "b": 2.0, "c": 3.0}, config.Get("map_of_float")) + assert.Equal(t, map[string]interface{}{"a": 1.0, "b": 2.0, "c": 3.0}, config.GetStringMap("map_of_float")) +} + +func TestParseEnvAsSliceMapString(t *testing.T) { + config := NewConfig("test", "DD", strings.NewReplacer(".", "_")) + + config.BindEnv("map") + config.ParseEnvAsSliceMapString("map", func(string) []map[string]string { return []map[string]string{{"a": "a", "b": "b", "c": "c"}} }) + + t.Setenv("DD_MAP", "__some_data__") + assert.Equal(t, []map[string]string{{"a": "a", "b": "b", "c": "c"}}, config.Get("map")) +} diff --git a/pkg/config/remote/go.mod b/pkg/config/remote/go.mod index f9b2a1e53d4f0..87dbbcf5ebb2a 100644 --- a/pkg/config/remote/go.mod +++ b/pkg/config/remote/go.mod @@ -52,7 +52,7 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect ) require ( @@ -77,9 +77,9 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/tinylib/msgp v1.1.8 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // 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 google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/pkg/config/remote/go.sum b/pkg/config/remote/go.sum index ec1f280c30bdc..61c0ef33e4625 100644 --- a/pkg/config/remote/go.sum +++ b/pkg/config/remote/go.sum @@ -355,8 +355,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -367,8 +367,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -433,8 +433,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -506,8 +506,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -520,8 +520,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/pkg/config/settings/http/client.go b/pkg/config/settings/http/client.go index 748ad5834fbd4..6d9a8ff42236b 100644 --- a/pkg/config/settings/http/client.go +++ b/pkg/config/settings/http/client.go @@ -9,6 +9,7 @@ package http import ( "bytes" "encoding/json" + "errors" "fmt" "html" "net/http" @@ -37,7 +38,7 @@ func (rc *runtimeSettingsHTTPClient) doGet(url string, formatError bool) (string _ = json.Unmarshal(r, &errMap) // If the error has been marshalled into a json object, check it and return it properly if e, found := errMap["error"]; found { - return "", fmt.Errorf(e) + return "", errors.New(e) } if formatError { return "", fmt.Errorf("Could not reach %s: %v \nMake sure the %s is running before requesting the runtime configuration and contact support if you continue having issues", rc.targetProcessName, err, rc.targetProcessName) @@ -130,7 +131,7 @@ func (rc *runtimeSettingsHTTPClient) Set(key string, value string) (bool, error) _ = json.Unmarshal(r, &errMap) // If the error has been marshalled into a json object, check it and return it properly if e, found := errMap["error"]; found { - return false, fmt.Errorf(e) + return false, errors.New(e) } return false, err } diff --git a/pkg/config/setup/apm.go b/pkg/config/setup/apm.go index 769ecef5c64d3..251af766fc0af 100644 --- a/pkg/config/setup/apm.go +++ b/pkg/config/setup/apm.go @@ -154,7 +154,7 @@ func setupAPM(config pkgconfigmodel.Setup) { config.BindEnv("apm_config.obfuscation.credit_cards.luhn", "DD_APM_OBFUSCATION_CREDIT_CARDS_LUHN") config.BindEnvAndSetDefault("apm_config.debug.port", 5012, "DD_APM_DEBUG_PORT") config.BindEnv("apm_config.features", "DD_APM_FEATURES") - config.SetEnvKeyTransformer("apm_config.features", func(s string) interface{} { + config.ParseEnvAsStringSlice("apm_config.features", func(s string) []string { // Either commas or spaces can be used as separators. // Comma takes precedence as it was the only supported separator in the past. // Mixing separators is not supported. @@ -170,7 +170,7 @@ func setupAPM(config pkgconfigmodel.Setup) { return res }) - config.SetEnvKeyTransformer("apm_config.ignore_resources", func(in string) interface{} { + config.ParseEnvAsStringSlice("apm_config.ignore_resources", func(in string) []string { r, err := splitCSVString(in, ',') if err != nil { log.Warnf(`"apm_config.ignore_resources" can not be parsed: %v`, err) @@ -179,15 +179,12 @@ func setupAPM(config pkgconfigmodel.Setup) { return r }) - config.SetEnvKeyTransformer("apm_config.filter_tags.require", parseKVList("apm_config.filter_tags.require")) + config.ParseEnvAsStringSlice("apm_config.filter_tags.require", parseKVList("apm_config.filter_tags.require")) + config.ParseEnvAsStringSlice("apm_config.filter_tags.reject", parseKVList("apm_config.filter_tags.reject")) + config.ParseEnvAsStringSlice("apm_config.filter_tags_regex.require", parseKVList("apm_config.filter_tags_regex.require")) + config.ParseEnvAsStringSlice("apm_config.filter_tags_regex.reject", parseKVList("apm_config.filter_tags_regex.reject")) - config.SetEnvKeyTransformer("apm_config.filter_tags.reject", parseKVList("apm_config.filter_tags.reject")) - - config.SetEnvKeyTransformer("apm_config.filter_tags_regex.require", parseKVList("apm_config.filter_tags_regex.require")) - - config.SetEnvKeyTransformer("apm_config.filter_tags_regex.reject", parseKVList("apm_config.filter_tags_regex.reject")) - - config.SetEnvKeyTransformer("apm_config.replace_tags", func(in string) interface{} { + config.ParseEnvAsSliceMapString("apm_config.replace_tags", func(in string) []map[string]string { var out []map[string]string if err := json.Unmarshal([]byte(in), &out); err != nil { log.Warnf(`"apm_config.replace_tags" can not be parsed: %v`, err) @@ -195,7 +192,7 @@ func setupAPM(config pkgconfigmodel.Setup) { return out }) - config.SetEnvKeyTransformer("apm_config.analyzed_spans", func(in string) interface{} { + config.ParseEnvAsMapStringInterface("apm_config.analyzed_spans", func(in string) map[string]interface{} { out, err := parseAnalyzedSpans(in) if err != nil { log.Errorf(`Bad format for "apm_config.analyzed_spans" it should be of the form \"service_name|operation_name=rate,other_service|other_operation=rate\", error: %v`, err) @@ -204,7 +201,7 @@ func setupAPM(config pkgconfigmodel.Setup) { }) config.BindEnv("apm_config.peer_tags", "DD_APM_PEER_TAGS") - config.SetEnvKeyTransformer("apm_config.peer_tags", func(in string) interface{} { + config.ParseEnvAsStringSlice("apm_config.peer_tags", func(in string) []string { var out []string if err := json.Unmarshal([]byte(in), &out); err != nil { log.Warnf(`"apm_config.peer_tags" can not be parsed: %v`, err) @@ -213,8 +210,8 @@ func setupAPM(config pkgconfigmodel.Setup) { }) } -func parseKVList(key string) func(string) interface{} { - return func(in string) interface{} { +func parseKVList(key string) func(string) []string { + return func(in string) []string { if len(in) == 0 { return []string{} } @@ -254,10 +251,10 @@ func parseNameAndRate(token string) (string, float64, error) { // parseAnalyzedSpans parses the env string to extract a map of spans to be analyzed by service and operation. // the format is: service_name|operation_name=rate,other_service|other_operation=rate -func parseAnalyzedSpans(env string) (analyzedSpans map[string]interface{}, err error) { - analyzedSpans = make(map[string]interface{}) +func parseAnalyzedSpans(env string) (map[string]interface{}, error) { + analyzedSpans := make(map[string]interface{}) if env == "" { - return + return analyzedSpans, nil } tokens := strings.Split(env, ",") for _, token := range tokens { @@ -267,5 +264,5 @@ func parseAnalyzedSpans(env string) (analyzedSpans map[string]interface{}, err e } analyzedSpans[name] = rate } - return + return analyzedSpans, nil } diff --git a/pkg/config/setup/config.go b/pkg/config/setup/config.go index ba058fe9715a9..e75e1af11d2f1 100644 --- a/pkg/config/setup/config.go +++ b/pkg/config/setup/config.go @@ -19,6 +19,7 @@ import ( "slices" "strconv" "strings" + "sync" "time" "gopkg.in/yaml.v2" @@ -108,29 +109,26 @@ const ( var ( datadog pkgconfigmodel.Config systemProbe pkgconfigmodel.Config -) -// Datadog returns the current agent configuration -func Datadog() pkgconfigmodel.Config { - return datadog -} + datadogMutex = sync.RWMutex{} + systemProbeMutex = sync.RWMutex{} +) // SetDatadog sets the the reference to the agent configuration. // This is currently used by the legacy converter and config mocks and should not be user anywhere else. Once the // legacy converter and mock have been migrated we will remove this function. func SetDatadog(cfg pkgconfigmodel.Config) { + datadogMutex.Lock() + defer datadogMutex.Unlock() datadog = cfg } -// SystemProbe returns the current SystemProbe configuration -func SystemProbe() pkgconfigmodel.Config { - return systemProbe -} - // SetSystemProbe sets the the reference to the systemProbe configuration. // This is currently used by the config mocks and should not be user anywhere else. Once the mocks have been migrated we // will remove this function. func SetSystemProbe(cfg pkgconfigmodel.Config) { + systemProbeMutex.Lock() + defer systemProbeMutex.Unlock() systemProbe = cfg } @@ -357,6 +355,24 @@ func InitConfig(config pkgconfigmodel.Config) { config.BindEnvAndSetDefault("kubernetes_node_label_as_cluster_name", "") config.BindEnvAndSetDefault("kubernetes_namespace_labels_as_tags", map[string]string{}) config.BindEnvAndSetDefault("kubernetes_namespace_annotations_as_tags", map[string]string{}) + // kubernetes_resources_annotations_as_tags should be parseable as map[string]map[string]string + // it maps group resources to annotations as tags maps + // a group resource has the format `{resource}.{group}`, or simply `{resource}` if it belongs to the empty group + // examples of group resources: + // - `deployments.apps` + // - `statefulsets.apps` + // - `pods` + // - `nodes` + config.BindEnvAndSetDefault("kubernetes_resources_annotations_as_tags", "{}") + // kubernetes_resources_labels_as_tags should be parseable as map[string]map[string]string + // it maps group resources to labels as tags maps + // a group resource has the format `{resource}.{group}`, or simply `{resource}` if it belongs to the empty group + // examples of group resources: + // - `deployments.apps` + // - `statefulsets.apps` + // - `pods` + // - `nodes` + config.BindEnvAndSetDefault("kubernetes_resources_labels_as_tags", "{}") config.BindEnvAndSetDefault("kubernetes_persistent_volume_claims_as_tags", true) config.BindEnvAndSetDefault("container_cgroup_prefix", "") @@ -837,6 +853,7 @@ func InitConfig(config pkgconfigmodel.Config) { config.BindEnvAndSetDefault("otelcollector.extension_url", "https://localhost:7777") config.BindEnvAndSetDefault("otelcollector.extension_timeout", 0) // in seconds, 0 for default value config.BindEnvAndSetDefault("otelcollector.submit_dummy_metadata", false) // dev flag - to be removed + config.BindEnvAndSetDefault("otelcollector.converter.enabled", true) // inventories config.BindEnvAndSetDefault("inventories_enabled", true) @@ -857,7 +874,7 @@ func InitConfig(config pkgconfigmodel.Config) { config.BindEnvAndSetDefault("security_agent.remote_workloadmeta", false) // TODO: switch this to true when ready // debug config to enable a remote client to receive data from the workloadmeta agent without a timeout - config.BindEnvAndSetDefault("workloadmeta.remote.recv_without_timeout", false) + config.BindEnvAndSetDefault("workloadmeta.remote.recv_without_timeout", true) config.BindEnvAndSetDefault("security_agent.internal_profiling.enabled", false, "DD_SECURITY_AGENT_INTERNAL_PROFILING_ENABLED") config.BindEnvAndSetDefault("security_agent.internal_profiling.site", DefaultSite, "DD_SECURITY_AGENT_INTERNAL_PROFILING_SITE", "DD_SITE") @@ -955,6 +972,8 @@ func InitConfig(config pkgconfigmodel.Config) { config.BindEnvAndSetDefault("remote_updates", false) config.BindEnvAndSetDefault("installer.registry.url", "") config.BindEnvAndSetDefault("installer.registry.auth", "") + config.BindEnv("fleet_policies_dir") + config.SetDefault("fleet_layers", []string{}) // Data Jobs Monitoring config config.BindEnvAndSetDefault("djm_config.enabled", false) @@ -1053,6 +1072,11 @@ func agent(config pkgconfigmodel.Setup) { // Use to output logs in JSON format config.BindEnvAndSetDefault("log_format_json", false) + // Agent GUI access host + // 'http://localhost' is preferred over 'http://127.0.0.1' due to Internet Explorer behavior. + // Internet Explorer High Security Level does not support setting cookies via HTTP Header response. + // By default, 'http://localhost' is categorized as an "intranet" website, which is considered safer and allowed to use cookies. This is not the case for 'http://127.0.0.1'. + config.BindEnvAndSetDefault("GUI_host", "localhost") // Agent GUI access port config.BindEnvAndSetDefault("GUI_port", defaultGuiPort) config.BindEnvAndSetDefault("GUI_session_expiration", 0) @@ -1463,7 +1487,7 @@ func logsagent(config pkgconfigmodel.Setup) { // maximum time that the windows tailer will hold a log file open, while waiting for // the downstream logs pipeline to be ready to accept more data config.BindEnvAndSetDefault("logs_config.windows_open_file_timeout", 5) - config.BindEnvAndSetDefault("logs_config.experimental_auto_multi_line_detection", false) + config.BindEnvAndSetDefault("logs_config.auto_multi_line_detection", false) config.BindEnvAndSetDefault("logs_config.auto_multi_line_extra_patterns", []string{}) // The following auto_multi_line settings are experimental and may change @@ -1471,6 +1495,17 @@ func logsagent(config pkgconfigmodel.Setup) { config.BindEnvAndSetDefault("logs_config.auto_multi_line_default_match_timeout", 30) // Seconds config.BindEnvAndSetDefault("logs_config.auto_multi_line_default_match_threshold", 0.48) + // Experimental auto multiline detection settings (these are subject to change until the feature is no longer experimental) + config.BindEnvAndSetDefault("logs_config.experimental_auto_multi_line_detection", false) + config.SetKnown("logs_config.auto_multi_line_detection_custom_samples") + config.BindEnvAndSetDefault("logs_config.auto_multi_line.timestamp_detector_match_threshold", 0.5) + config.BindEnvAndSetDefault("logs_config.auto_multi_line.tokenizer_max_input_bytes", 60) + config.BindEnvAndSetDefault("logs_config.auto_multi_line.pattern_table_max_size", 20) + config.BindEnvAndSetDefault("logs_config.auto_multi_line.pattern_table_match_threshold", 0.75) + config.BindEnvAndSetDefault("logs_config.tag_auto_multi_line_logs", false) + // Add a tag to logs that are truncated by the agent + config.BindEnvAndSetDefault("logs_config.tag_truncated_logs", false) + // If true, the agent looks for container logs in the location used by podman, rather // than docker. This is a temporary configuration parameter to support podman logs until // a more substantial refactor of autodiscovery is made to determine this automatically. @@ -1504,6 +1539,10 @@ func logsagent(config pkgconfigmodel.Setup) { // more disk I/O at the wildcard log paths config.BindEnvAndSetDefault("logs_config.file_wildcard_selection_mode", "by_name") + // SDS logs blocking mechanism + config.BindEnvAndSetDefault("logs_config.sds.wait_for_configuration", "") + config.BindEnvAndSetDefault("logs_config.sds.buffer_max_size", 0) + // Max size in MB to allow for integrations logs files config.BindEnvAndSetDefault("logs_config.integrations_logs_files_max_size", 100) } @@ -1870,9 +1909,7 @@ func LoadDatadogCustom(config pkgconfigmodel.Config, origin string, secretResolv err := LoadCustom(config, additionalKnownEnvVars) if err != nil { if errors.Is(err, os.ErrPermission) { - log.Warnf("Error loading config: %v (check config file permissions for dd-agent user)", err) - } else { - log.Warnf("Error loading config: %v", err) + return warnings, log.Warnf("Error loading config: %v (check config file permissions for dd-agent user)", err) } return warnings, err } @@ -1949,7 +1986,7 @@ func LoadCustom(config pkgconfigmodel.Config, additionalKnownEnvVars []string) e } for _, warningMsg := range findUnexpectedUnicode(config) { - log.Warnf(warningMsg) + log.Warnf("%s", warningMsg) } return nil diff --git a/pkg/config/setup/config_accessor.go b/pkg/config/setup/config_accessor.go new file mode 100644 index 0000000000000..2ab096ea9b51a --- /dev/null +++ b/pkg/config/setup/config_accessor.go @@ -0,0 +1,20 @@ +// 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. + +//go:build !test + +package setup + +import pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model" + +// Datadog returns the current agent configuration +func Datadog() pkgconfigmodel.Config { + return datadog +} + +// SystemProbe returns the current SystemProbe configuration +func SystemProbe() pkgconfigmodel.Config { + return systemProbe +} diff --git a/pkg/config/setup/config_test_accessor.go b/pkg/config/setup/config_test_accessor.go new file mode 100644 index 0000000000000..b19ff02286f1e --- /dev/null +++ b/pkg/config/setup/config_test_accessor.go @@ -0,0 +1,24 @@ +// 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. + +//go:build test + +package setup + +import pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model" + +// Datadog returns the current agent configuration +func Datadog() pkgconfigmodel.Config { + datadogMutex.RLock() + defer datadogMutex.RUnlock() + return datadog +} + +// SystemProbe returns the current SystemProbe configuration +func SystemProbe() pkgconfigmodel.Config { + systemProbeMutex.RLock() + defer systemProbeMutex.RUnlock() + return systemProbe +} diff --git a/pkg/config/setup/go.mod b/pkg/config/setup/go.mod index 561d86ad4bb1c..a4486128b46dd 100644 --- a/pkg/config/setup/go.mod +++ b/pkg/config/setup/go.mod @@ -45,7 +45,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/system v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/util/winutil v0.56.0-rc.3 github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.18.2 + go.uber.org/fx v1.22.2 gopkg.in/yaml.v2 v2.4.0 ) @@ -100,15 +100,15 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/config/setup/go.sum b/pkg/config/setup/go.sum index 1f99a4d1b59d9..a93fc7c02ab32 100644 --- a/pkg/config/setup/go.sum +++ b/pkg/config/setup/go.sum @@ -239,27 +239,27 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -302,11 +302,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -319,8 +319,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/config/setup/process.go b/pkg/config/setup/process.go index 2a10f62cb2f9d..cbd1e75cf5a02 100644 --- a/pkg/config/setup/process.go +++ b/pkg/config/setup/process.go @@ -7,6 +7,7 @@ package setup import ( "net" + "runtime" "strconv" "strings" "sync" @@ -211,9 +212,18 @@ func setupProcesses(config pkgconfigmodel.Config) { processesAddOverrideOnce.Do(func() { pkgconfigmodel.AddOverrideFunc(loadProcessTransforms) + pkgconfigmodel.AddOverrideFunc(overrideRunInCoreAgentConfig) }) } +// overrideRunInCoreAgentConfig sets the process_config.run_in_core_agent.enabled to false in non-Linux environments. +// Otherwise, it is a no-op. +func overrideRunInCoreAgentConfig(config pkgconfigmodel.Config) { + if runtime.GOOS != "linux" { + config.Set("process_config.run_in_core_agent.enabled", false, pkgconfigmodel.SourceAgentRuntime) + } +} + // loadProcessTransforms loads transforms associated with process config settings. func loadProcessTransforms(config pkgconfigmodel.Config) { if config.IsSet("process_config.enabled") { diff --git a/pkg/config/setup/system_probe.go b/pkg/config/setup/system_probe.go index e7754f72c842b..9567f2df8b0f7 100644 --- a/pkg/config/setup/system_probe.go +++ b/pkg/config/setup/system_probe.go @@ -206,6 +206,7 @@ func InitSystemProbeConfig(cfg pkgconfigmodel.Config) { cfg.BindEnvAndSetDefault(join(netNS, "ignore_conntrack_init_failure"), false, "DD_SYSTEM_PROBE_NETWORK_IGNORE_CONNTRACK_INIT_FAILURE") cfg.BindEnvAndSetDefault(join(netNS, "conntrack_init_timeout"), 10*time.Second) cfg.BindEnvAndSetDefault(join(netNS, "allow_netlink_conntracker_fallback"), true) + cfg.BindEnvAndSetDefault(join(netNS, "enable_ebpf_conntracker"), true) cfg.BindEnvAndSetDefault(join(spNS, "source_excludes"), map[string][]string{}) cfg.BindEnvAndSetDefault(join(spNS, "dest_excludes"), map[string][]string{}) @@ -258,6 +259,7 @@ func InitSystemProbeConfig(cfg pkgconfigmodel.Config) { cfg.BindEnv(join(smNS, "max_http_stats_buffered")) cfg.BindEnvAndSetDefault(join(smNS, "max_kafka_stats_buffered"), 100000) cfg.BindEnv(join(smNS, "max_postgres_stats_buffered")) + cfg.BindEnvAndSetDefault(join(smNS, "max_postgres_telemetry_buffer"), 160) cfg.BindEnv(join(smNS, "max_redis_stats_buffered")) cfg.BindEnv(join(smNS, "max_concurrent_requests")) cfg.BindEnv(join(smNS, "enable_quantization")) @@ -298,6 +300,8 @@ func InitSystemProbeConfig(cfg pkgconfigmodel.Config) { // connection aggregation with port rollups cfg.BindEnvAndSetDefault(join(netNS, "enable_connection_rollup"), false) + cfg.BindEnvAndSetDefault(join(netNS, "enable_ebpfless"), false) + // windows config cfg.BindEnvAndSetDefault(join(spNS, "windows.enable_monotonic_count"), false) @@ -392,6 +396,9 @@ func InitSystemProbeConfig(cfg pkgconfigmodel.Config) { // Discovery config cfg.BindEnvAndSetDefault(join(discoveryNS, "enabled"), false) + // Fleet policies + cfg.BindEnv("fleet_policies_dir") + initCWSSystemProbeConfig(cfg) } diff --git a/comp/core/flare/component_mock.go b/pkg/config/setup/test_config_accessor.go similarity index 61% rename from comp/core/flare/component_mock.go rename to pkg/config/setup/test_config_accessor.go index f0c8decbc0925..2f25fd2f3d43d 100644 --- a/comp/core/flare/component_mock.go +++ b/pkg/config/setup/test_config_accessor.go @@ -5,13 +5,7 @@ //go:build test -package flare +package setup -// team: agent-shared-components - -// Mock is the mocked component type. -type Mock interface { - Component - - // no further methods are defined. -} +// This file contains the accessor for the configuration when running tests. This version offer a way to set the +// different configurations at runtime. diff --git a/pkg/config/test_helpers.go b/pkg/config/test_helpers.go index cde9d54eb28bb..b463b7980fbf0 100644 --- a/pkg/config/test_helpers.go +++ b/pkg/config/test_helpers.go @@ -8,9 +8,6 @@ package config import ( - "strings" - "testing" - "github.com/DataDog/datadog-agent/pkg/config/env" pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" ) @@ -21,19 +18,6 @@ var ( // SetFeaturesNoCleanup is alias from env SetFeaturesNoCleanup = env.SetFeaturesNoCleanup - // SetupConf generates and returns a new configuration - SetupConf = pkgconfigsetup.Conf - // SetupConfFromYAML generates a configuration from the given yaml config SetupConfFromYAML = pkgconfigsetup.ConfFromYAML ) - -// ResetSystemProbeConfig resets the configuration. -func ResetSystemProbeConfig(t *testing.T) { - originalConfig := pkgconfigsetup.SystemProbe() - t.Cleanup(func() { - pkgconfigsetup.SetSystemProbe(originalConfig) - }) - pkgconfigsetup.SetSystemProbe(NewConfig("system-probe", "DD", strings.NewReplacer(".", "_"))) - pkgconfigsetup.InitSystemProbeConfig(pkgconfigsetup.SystemProbe()) -} diff --git a/pkg/config/utils/go.mod b/pkg/config/utils/go.mod index 8e7d13ef03d31..a5d3d47068d7b 100644 --- a/pkg/config/utils/go.mod +++ b/pkg/config/utils/go.mod @@ -76,12 +76,12 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/config/utils/go.sum b/pkg/config/utils/go.sum index 79c2fcb395d02..77ba213060c82 100644 --- a/pkg/config/utils/go.sum +++ b/pkg/config/utils/go.sum @@ -234,25 +234,25 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -295,11 +295,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -312,8 +312,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/config/utils/metadata_as_tags.go b/pkg/config/utils/metadata_as_tags.go new file mode 100644 index 0000000000000..f3a60650c8a21 --- /dev/null +++ b/pkg/config/utils/metadata_as_tags.go @@ -0,0 +1,200 @@ +// 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 2024-present Datadog, Inc. + +package utils + +import ( + "encoding/json" + "maps" + "strings" + + "github.com/DataDog/datadog-agent/pkg/util/log" + + pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model" +) + +const ( + pods string = "pods" + nodes string = "nodes" + namespaces string = "namespaces" +) + +// MetadataAsTags contains the labels as tags and annotations as tags for each kubernetes resource based on the user configurations of the following options ordered in increasing order of priority: +// +// kubernetes_pod_labels_as_tags +// kubernetes_pod_annotations_as_tags +// kubernetes_node_labels_as_tags +// kubernetes_node_annotations_as_tags +// kubernetes_namespace_labels_as_tags +// kubernetes_namespace_annotations_as_tags +// kubernetes_resources_labels_as_tags +// kubernetes_resources_anotations_as_tags +// +// In case of conflict, higher priority configuration value takes precedences +// For example, if kubernetes_pod_labels_as_tags = {`l1`: `v1`, `l2`: `v2`} and kubernetes_resources_labels_as_tags = {`pods`: {`l1`: `x`}}, +// the resulting labels as tags for pods will be {`l1`: `x`, `l2`: `v2`} +type MetadataAsTags interface { + // GetPodLabelsAsTags returns pod labels as tags + GetPodLabelsAsTags() map[string]string + // GetPodAnnotationsAsTags returns pod annotations as tags + GetPodAnnotationsAsTags() map[string]string + // GetNodeLabelsAsTags returns node labels as tags + GetNodeLabelsAsTags() map[string]string + // GetNodeAnnotationsAsTags returns node annotations as tags + GetNodeAnnotationsAsTags() map[string]string + // GetNamespaceLabelsAsTags returns namespace labels as tags + GetNamespaceLabelsAsTags() map[string]string + // GetNamespaceAnnotationsAsTags returns namespace annotations as tags + GetNamespaceAnnotationsAsTags() map[string]string + // GetResourcesLabelsAsTags returns resources labels as tags + GetResourcesLabelsAsTags() map[string]map[string]string + // GetResourcesAnnotationsAsTags returns resources annotations as tags + GetResourcesAnnotationsAsTags() map[string]map[string]string +} + +type metadataAsTags struct { + labelsAsTags map[string]map[string]string + annotationsAsTags map[string]map[string]string +} + +var _ MetadataAsTags = &metadataAsTags{} + +// GetPodLabelsAsTags implements MetadataAsTags#GetPodLabelsAsTags +func (m *metadataAsTags) GetPodLabelsAsTags() map[string]string { + return m.labelsAsTags[pods] +} + +// GetPodAnnotationsAsTags implements MetadataAsTags#GetPodAnnotationsAsTags +func (m *metadataAsTags) GetPodAnnotationsAsTags() map[string]string { + return m.annotationsAsTags[pods] +} + +// GetNodeLabelsAsTags implements MetadataAsTags#GetNodeLabelsAsTags +func (m *metadataAsTags) GetNodeLabelsAsTags() map[string]string { + return m.labelsAsTags[nodes] +} + +// GetNodeAnnotationsAsTags implements MetadataAsTags#GetNodeAnnotationsAsTags +func (m *metadataAsTags) GetNodeAnnotationsAsTags() map[string]string { + return m.annotationsAsTags[nodes] +} + +// GetNamespaceLabelsAsTags implements MetadataAsTags#GetNamespaceLabelsAsTags +func (m *metadataAsTags) GetNamespaceLabelsAsTags() map[string]string { + return m.labelsAsTags[namespaces] +} + +// GetNamespaceAnnotationsAsTags implements MetadataAsTags#GetNamespaceAnnotationsAsTags +func (m *metadataAsTags) GetNamespaceAnnotationsAsTags() map[string]string { + return m.annotationsAsTags[namespaces] +} + +// GetResourcesLabelsAsTags implements MetadataAsTags#GetResourcesLabelsAsTags +func (m *metadataAsTags) GetResourcesLabelsAsTags() map[string]map[string]string { + return m.labelsAsTags +} + +// GetResourcesAnnotationsAsTags implements MetadataAsTags#GetResourcesAnnotationsAsTags +func (m *metadataAsTags) GetResourcesAnnotationsAsTags() map[string]map[string]string { + return m.annotationsAsTags +} + +func (m *metadataAsTags) mergeGenericResourcesLabelsAsTags(cfg pkgconfigmodel.Reader) { + resourcesToLabelsAsTags := retrieveDoubleMappingFromConfig(cfg, "kubernetes_resources_labels_as_tags") + + for resource, labelsAsTags := range resourcesToLabelsAsTags { + // "pods.", "nodes.", "namespaces." are valid configurations, but they should be replaced here by "pods", "nodes" and "namespaces" respectively to ensure that they override the existing configurations for pods, nodes and namespaces + cleanResource := strings.TrimSuffix(resource, ".") + _, found := m.labelsAsTags[cleanResource] + if !found { + m.labelsAsTags[cleanResource] = map[string]string{} + } + // When a key in `labelsAsTags` exist in `m.labelsAsTags[cleanResource]`, the value in `m.labelsAsTags[cleanResource]` will be overwritten by the value associated with the key in `labelsAsTags` + // source: https://pkg.go.dev/maps#Copy + maps.Copy(m.labelsAsTags[cleanResource], labelsAsTags) + } +} + +func (m *metadataAsTags) mergeGenericResourcesAnnotationsAsTags(cfg pkgconfigmodel.Reader) { + resourcesToAnnotationsAsTags := retrieveDoubleMappingFromConfig(cfg, "kubernetes_resources_annotations_as_tags") + + for resource, annotationsAsTags := range resourcesToAnnotationsAsTags { + // "pods.", "nodes.", "namespaces." are valid configurations, but they should be replaced here by "pods", "nodes" and "namespaces" respectively to ensure that they override the existing configurations for pods, nodes and namesapces + cleanResource := strings.TrimSuffix(resource, ".") + _, found := m.annotationsAsTags[cleanResource] + if !found { + m.annotationsAsTags[cleanResource] = map[string]string{} + } + // When a key in `annotationsAsTags` exist in `m.annotationsAsTags[cleanResource]`, the value in `m.annotationsAsTags[cleanResource]` will be overwritten by the value associated with the key in `annotationsAsTags` + // source: https://pkg.go.dev/maps#Copy + maps.Copy(m.annotationsAsTags[cleanResource], annotationsAsTags) + } +} + +// GetMetadataAsTags returns a merged configuration of all labels and annotations as tags set by the user +func GetMetadataAsTags(c pkgconfigmodel.Reader) MetadataAsTags { + + metadataAsTags := metadataAsTags{ + labelsAsTags: map[string]map[string]string{}, + annotationsAsTags: map[string]map[string]string{}, + } + + // node labels/annotations as tags + if nodeLabelsAsTags := c.GetStringMapString("kubernetes_node_labels_as_tags"); nodeLabelsAsTags != nil { + metadataAsTags.labelsAsTags[nodes] = lowerCaseMapKeys(nodeLabelsAsTags) + } + if nodeAnnotationsAsTags := c.GetStringMapString("kubernetes_node_annotations_as_tags"); nodeAnnotationsAsTags != nil { + metadataAsTags.annotationsAsTags[nodes] = lowerCaseMapKeys(nodeAnnotationsAsTags) + } + + // namespace labels/annotations as tags + if namespaceLabelsAsTags := c.GetStringMapString("kubernetes_namespace_labels_as_tags"); namespaceLabelsAsTags != nil { + metadataAsTags.labelsAsTags[namespaces] = lowerCaseMapKeys(namespaceLabelsAsTags) + } + if namespaceAnnotationsAsTags := c.GetStringMapString("kubernetes_namespace_annotations_as_tags"); namespaceAnnotationsAsTags != nil { + metadataAsTags.annotationsAsTags[namespaces] = lowerCaseMapKeys(namespaceAnnotationsAsTags) + } + + // pod labels/annotations as tags + if podLabelsAsTags := c.GetStringMapString("kubernetes_pod_labels_as_tags"); podLabelsAsTags != nil { + metadataAsTags.labelsAsTags[pods] = lowerCaseMapKeys(podLabelsAsTags) + } + if podAnnotationsAsTags := c.GetStringMapString("kubernetes_pod_annotations_as_tags"); podAnnotationsAsTags != nil { + metadataAsTags.annotationsAsTags[pods] = lowerCaseMapKeys(podAnnotationsAsTags) + } + + // generic resources labels/annotations as tags + metadataAsTags.mergeGenericResourcesLabelsAsTags(c) + metadataAsTags.mergeGenericResourcesAnnotationsAsTags(c) + + return &metadataAsTags +} + +func retrieveDoubleMappingFromConfig(cfg pkgconfigmodel.Reader, configKey string) map[string]map[string]string { + valueFromConfig := cfg.GetString(configKey) + + var doubleMap map[string]map[string]string + err := json.Unmarshal([]byte(valueFromConfig), &doubleMap) + + if err != nil { + log.Errorf("failed to parse %s with value %s into json: %v", configKey, valueFromConfig, err) + return map[string]map[string]string{} + } + + for resource, tags := range doubleMap { + doubleMap[resource] = lowerCaseMapKeys(tags) + } + + return doubleMap +} + +// lowerCaseMapKeys lowercases all map keys +func lowerCaseMapKeys(m map[string]string) map[string]string { + for label, value := range m { + delete(m, label) + m[strings.ToLower(label)] = value + } + return m +} diff --git a/pkg/config/utils/metadata_as_tags_test.go b/pkg/config/utils/metadata_as_tags_test.go new file mode 100644 index 0000000000000..c1f73c8fa1599 --- /dev/null +++ b/pkg/config/utils/metadata_as_tags_test.go @@ -0,0 +1,127 @@ +// 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 2024-present Datadog, Inc. + +package utils + +import ( + "reflect" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + + pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model" + pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" +) + +func TestGetMetadataAsTagsNoError(t *testing.T) { + + tests := []struct { + name string + podLabelsAsTags map[string]string + podAnnotationsAsTags map[string]string + nodeLabelsAsTags map[string]string + nodeAnnotationsAsTags map[string]string + namespaceLabelsAsTags map[string]string + namespaceAnnotationsAsTags map[string]string + resourcesLabelsAsTags string + resourcesAnnotationsAsTags string + expectedLabelsAsTags map[string]map[string]string + expectedAnnotationsAsTags map[string]map[string]string + }{ + { + name: "no configs", + resourcesLabelsAsTags: "{}", + resourcesAnnotationsAsTags: "{}", + expectedLabelsAsTags: map[string]map[string]string{}, + expectedAnnotationsAsTags: map[string]map[string]string{}, + }, + { + name: "old configurations only", + podLabelsAsTags: map[string]string{"l1": "v1", "l2": "v2"}, + podAnnotationsAsTags: map[string]string{"l3": "v3", "l4": "v4"}, + nodeLabelsAsTags: map[string]string{"L5": "v5", "L6": "v6"}, // keys should be lower-cased automatically + nodeAnnotationsAsTags: map[string]string{"l7": "v7", "l8": "v8"}, + namespaceLabelsAsTags: map[string]string{"l9": "v9", "l10": "v10"}, + namespaceAnnotationsAsTags: map[string]string{"l11": "v11", "l12": "v12"}, + resourcesLabelsAsTags: "{}", + resourcesAnnotationsAsTags: "{}", + expectedLabelsAsTags: map[string]map[string]string{ + "nodes": {"l5": "v5", "l6": "v6"}, + "pods": {"l1": "v1", "l2": "v2"}, + "namespaces": {"l9": "v9", "l10": "v10"}, + }, + expectedAnnotationsAsTags: map[string]map[string]string{ + "nodes": {"l7": "v7", "l8": "v8"}, + "pods": {"l3": "v3", "l4": "v4"}, + "namespaces": {"l11": "v11", "l12": "v12"}, + }, + }, + { + name: "new configurations only", + resourcesLabelsAsTags: `{"pods.": {"l1": "v1", "l2": "v2"}, "deployments.apps": {"l3": "v3", "l4": "v4"}, "namespaces": {"l5": "v5"}}`, + resourcesAnnotationsAsTags: `{"nodes.": {"l6": "v6", "l7": "v7"},"deployments.apps": {"l8": "v8", "l9": "v9"}, "namespaces": {"l10": "v10"}}`, + expectedLabelsAsTags: map[string]map[string]string{ + "pods": {"l1": "v1", "l2": "v2"}, + "deployments.apps": {"l3": "v3", "l4": "v4"}, + "namespaces": {"l5": "v5"}, + }, + expectedAnnotationsAsTags: map[string]map[string]string{ + "nodes": {"l6": "v6", "l7": "v7"}, + "deployments.apps": {"l8": "v8", "l9": "v9"}, + "namespaces": {"l10": "v10"}, + }, + }, + { + name: "old and new configurations | new configuration should take precedence", + podLabelsAsTags: map[string]string{"l1": "v1", "l2": "v2"}, + podAnnotationsAsTags: map[string]string{"l3": "v3", "l4": "v4"}, + nodeLabelsAsTags: map[string]string{"l5": "v5", "l6": "v6"}, + nodeAnnotationsAsTags: map[string]string{"l7": "v7", "l8": "v8"}, + namespaceLabelsAsTags: map[string]string{"l9": "v9", "l10": "v10"}, + namespaceAnnotationsAsTags: map[string]string{"l11": "v11", "l12": "v12"}, + resourcesLabelsAsTags: `{"pods.": {"l1": "x1", "l99": "v99"}, "deployments.apps": {"l3": "v3", "l4": "v4"}}`, + resourcesAnnotationsAsTags: `{"nodes.": {"l6": "v6", "l7": "x7"}}`, + expectedLabelsAsTags: map[string]map[string]string{ + "nodes": {"l5": "v5", "l6": "v6"}, + "pods": {"l1": "x1", "l2": "v2", "l99": "v99"}, + "deployments.apps": {"l3": "v3", "l4": "v4"}, + "namespaces": {"l9": "v9", "l10": "v10"}, + }, + expectedAnnotationsAsTags: map[string]map[string]string{ + "nodes": {"l6": "v6", "l7": "x7", "l8": "v8"}, + "pods": {"l3": "v3", "l4": "v4"}, + "namespaces": {"l11": "v11", "l12": "v12"}, + }, + }, + } + + for _, test := range tests { + + t.Run(test.name, func(tt *testing.T) { + mockConfig := pkgconfigmodel.NewConfig("test", "DD", strings.NewReplacer(".", "_")) + pkgconfigsetup.InitConfig(mockConfig) + + mockConfig.SetWithoutSource("kubernetes_pod_labels_as_tags", test.podLabelsAsTags) + mockConfig.SetWithoutSource("kubernetes_pod_annotations_as_tags", test.podAnnotationsAsTags) + mockConfig.SetWithoutSource("kubernetes_namespace_labels_as_tags", test.namespaceLabelsAsTags) + mockConfig.SetWithoutSource("kubernetes_namespace_annotations_as_tags", test.namespaceAnnotationsAsTags) + mockConfig.SetWithoutSource("kubernetes_node_labels_as_tags", test.nodeLabelsAsTags) + mockConfig.SetWithoutSource("kubernetes_node_annotations_as_tags", test.nodeAnnotationsAsTags) + mockConfig.SetWithoutSource("kubernetes_resources_labels_as_tags", test.resourcesLabelsAsTags) + mockConfig.SetWithoutSource("kubernetes_resources_annotations_as_tags", test.resourcesAnnotationsAsTags) + + metadataAsTags := GetMetadataAsTags(mockConfig) + + assert.NotNil(tt, metadataAsTags) + + labelsAsTags := metadataAsTags.GetResourcesLabelsAsTags() + assert.Truef(tt, reflect.DeepEqual(labelsAsTags, test.expectedLabelsAsTags), "Expected %v, found %v", test.expectedLabelsAsTags, labelsAsTags) + + annotationsAsTags := metadataAsTags.GetResourcesAnnotationsAsTags() + assert.Truef(tt, reflect.DeepEqual(annotationsAsTags, test.expectedAnnotationsAsTags), "Expected %v, found %v", test.expectedAnnotationsAsTags, annotationsAsTags) + }) + } +} diff --git a/pkg/collector/corechecks/servicediscovery/testdata/a/domain/configuration/domain.xml b/pkg/discovery/testdata/root/testdata/a/domain/configuration/domain.xml similarity index 100% rename from pkg/collector/corechecks/servicediscovery/testdata/a/domain/configuration/domain.xml rename to pkg/discovery/testdata/root/testdata/a/domain/configuration/domain.xml diff --git a/pkg/collector/corechecks/servicediscovery/testdata/a/domain/configuration/host.xml b/pkg/discovery/testdata/root/testdata/a/domain/configuration/host.xml similarity index 100% rename from pkg/collector/corechecks/servicediscovery/testdata/a/domain/configuration/host.xml rename to pkg/discovery/testdata/root/testdata/a/domain/configuration/host.xml diff --git a/pkg/collector/corechecks/servicediscovery/testdata/a/standalone/configuration/standalone.xml b/pkg/discovery/testdata/root/testdata/a/standalone/configuration/standalone.xml similarity index 100% rename from pkg/collector/corechecks/servicediscovery/testdata/a/standalone/configuration/standalone.xml rename to pkg/discovery/testdata/root/testdata/a/standalone/configuration/standalone.xml diff --git a/pkg/collector/corechecks/servicediscovery/testdata/a/standalone/data/content/38/e/content b/pkg/discovery/testdata/root/testdata/a/standalone/data/content/38/e/content similarity index 100% rename from pkg/collector/corechecks/servicediscovery/testdata/a/standalone/data/content/38/e/content rename to pkg/discovery/testdata/root/testdata/a/standalone/data/content/38/e/content diff --git a/pkg/collector/corechecks/servicediscovery/testdata/a/standalone/data/content/f0/c/content b/pkg/discovery/testdata/root/testdata/a/standalone/data/content/f0/c/content similarity index 100% rename from pkg/collector/corechecks/servicediscovery/testdata/a/standalone/data/content/f0/c/content rename to pkg/discovery/testdata/root/testdata/a/standalone/data/content/f0/c/content diff --git a/pkg/collector/corechecks/servicediscovery/testdata/b/config/config.xml b/pkg/discovery/testdata/root/testdata/b/config/config.xml similarity index 97% rename from pkg/collector/corechecks/servicediscovery/testdata/b/config/config.xml rename to pkg/discovery/testdata/root/testdata/b/config/config.xml index 7ee4c2621da6a..b28f1387a1303 100644 --- a/pkg/collector/corechecks/servicediscovery/testdata/b/config/config.xml +++ b/pkg/discovery/testdata/root/testdata/b/config/config.xml @@ -61,7 +61,7 @@ sample AdminServer war - ../testdata/b/test.war + ./test.war DDOnly stage stage @@ -101,7 +101,7 @@ some_ear AdminServer ear - ../testdata/b/test.ear + ./test.ear DDOnly stage stage diff --git a/pkg/collector/corechecks/servicediscovery/testdata/b/test.ear/META-INF/application.xml b/pkg/discovery/testdata/root/testdata/b/test.ear/META-INF/application.xml similarity index 100% rename from pkg/collector/corechecks/servicediscovery/testdata/b/test.ear/META-INF/application.xml rename to pkg/discovery/testdata/root/testdata/b/test.ear/META-INF/application.xml diff --git a/pkg/collector/corechecks/servicediscovery/testdata/b/test.war/META-INF/weblogic.xml b/pkg/discovery/testdata/root/testdata/b/test.war/META-INF/weblogic.xml similarity index 100% rename from pkg/collector/corechecks/servicediscovery/testdata/b/test.war/META-INF/weblogic.xml rename to pkg/discovery/testdata/root/testdata/b/test.war/META-INF/weblogic.xml diff --git a/pkg/collector/corechecks/servicediscovery/testdata/test-bin/my-service.py b/pkg/discovery/testdata/root/testdata/test-bin/my-service.py similarity index 100% rename from pkg/collector/corechecks/servicediscovery/testdata/test-bin/my-service.py rename to pkg/discovery/testdata/root/testdata/test-bin/my-service.py diff --git a/pkg/ebpf/ebpftest/buildmode.go b/pkg/ebpf/ebpftest/buildmode.go index 6fcc977f80af4..76e774f68cbbb 100644 --- a/pkg/ebpf/ebpftest/buildmode.go +++ b/pkg/ebpf/ebpftest/buildmode.go @@ -16,6 +16,7 @@ var ( RuntimeCompiled BuildMode CORE BuildMode Fentry BuildMode + Ebpfless BuildMode ) func init() { @@ -23,6 +24,7 @@ func init() { RuntimeCompiled = runtimeCompiled{} CORE = core{} Fentry = fentry{} + Ebpfless = ebpfless{} } // BuildMode is an eBPF build mode @@ -95,6 +97,23 @@ func (f fentry) Env() map[string]string { } } +type ebpfless struct{} + +func (e ebpfless) String() string { + return "eBPFless" +} + +func (e ebpfless) Env() map[string]string { + return map[string]string{ + "NETWORK_TRACER_FENTRY_TESTS": "false", + "DD_ENABLE_RUNTIME_COMPILER": "false", + "DD_ENABLE_CO_RE": "false", + "DD_ALLOW_RUNTIME_COMPILED_FALLBACK": "false", + "DD_ALLOW_PRECOMPILED_FALLBACK": "false", + "DD_NETWORK_CONFIG_ENABLE_EBPFLESS": "true", + } +} + // GetBuildMode returns which build mode the current environment matches, if any func GetBuildMode() BuildMode { for _, mode := range []BuildMode{Prebuilt, RuntimeCompiled, CORE, Fentry} { diff --git a/pkg/ebpf/ebpftest/buildmode_linux.go b/pkg/ebpf/ebpftest/buildmode_linux.go index a16d7bbc8dc2d..0e88f0f528271 100644 --- a/pkg/ebpf/ebpftest/buildmode_linux.go +++ b/pkg/ebpf/ebpftest/buildmode_linux.go @@ -30,6 +30,10 @@ func SupportedBuildModes() []BuildMode { (runtime.GOARCH == "amd64" && (hostPlatform == "amazon" || hostPlatform == "amzn") && kv.Major() == 5 && kv.Minor() == 10) { modes = append(modes, Fentry) } + if os.Getenv("TEST_EBPFLESS_OVERRIDE") == "true" { + modes = append(modes, Ebpfless) + } + return modes } diff --git a/pkg/ebpf/perf.go b/pkg/ebpf/perf.go index c091c80410f50..03773792202f0 100644 --- a/pkg/ebpf/perf.go +++ b/pkg/ebpf/perf.go @@ -27,7 +27,7 @@ var _ EventHandler = new(PerfHandler) type PerfHandler struct { RecordGetter func() *perf.Record - dataChannel chan *DataEvent + dataChannel chan DataEvent lostChannel chan uint64 once sync.Once closed bool @@ -39,7 +39,7 @@ func NewPerfHandler(dataChannelSize int) *PerfHandler { RecordGetter: func() *perf.Record { return recordPool.Get() }, - dataChannel: make(chan *DataEvent, dataChannelSize), + dataChannel: make(chan DataEvent, dataChannelSize), lostChannel: make(chan uint64, 10), } } @@ -58,11 +58,11 @@ func (c *PerfHandler) RecordHandler(record *perf.Record, _ *manager.PerfMap, _ * return } - c.dataChannel <- &DataEvent{Data: record.RawSample, pr: record} + c.dataChannel <- DataEvent{Data: record.RawSample, pr: record} } // DataChannel returns the channel with event data -func (c *PerfHandler) DataChannel() <-chan *DataEvent { +func (c *PerfHandler) DataChannel() <-chan DataEvent { return c.dataChannel } diff --git a/pkg/ebpf/perf_data_event.go b/pkg/ebpf/perf_data_event.go index 82e0625a73b03..b1ba62dd43986 100644 --- a/pkg/ebpf/perf_data_event.go +++ b/pkg/ebpf/perf_data_event.go @@ -15,7 +15,7 @@ import ( // EventHandler is the common interface shared across perf map and perf ring // buffer handlers type EventHandler interface { - DataChannel() <-chan *DataEvent + DataChannel() <-chan DataEvent LostChannel() <-chan uint64 Stop() } diff --git a/pkg/ebpf/perf_ring_buffer.go b/pkg/ebpf/perf_ring_buffer.go index b8a4f6fee3c75..e81e996e34c50 100644 --- a/pkg/ebpf/perf_ring_buffer.go +++ b/pkg/ebpf/perf_ring_buffer.go @@ -27,7 +27,7 @@ var _ EventHandler = new(RingBufferHandler) type RingBufferHandler struct { RecordGetter func() *ringbuf.Record - dataChannel chan *DataEvent + dataChannel chan DataEvent lostChannel chan uint64 once sync.Once closed bool @@ -39,7 +39,7 @@ func NewRingBufferHandler(dataChannelSize int) *RingBufferHandler { RecordGetter: func() *ringbuf.Record { return ringPool.Get() }, - dataChannel: make(chan *DataEvent, dataChannelSize), + dataChannel: make(chan DataEvent, dataChannelSize), // This channel is not really used in the context of ring buffers but // it's here so `RingBufferHandler` and `PerfHandler` can be used // interchangeably @@ -53,11 +53,11 @@ func (c *RingBufferHandler) RecordHandler(record *ringbuf.Record, _ *manager.Rin return } - c.dataChannel <- &DataEvent{Data: record.RawSample, rr: record} + c.dataChannel <- DataEvent{Data: record.RawSample, rr: record} } // DataChannel returns the channel with event data -func (c *RingBufferHandler) DataChannel() <-chan *DataEvent { +func (c *RingBufferHandler) DataChannel() <-chan DataEvent { return c.dataChannel } diff --git a/pkg/ebpf/verifier/elf.go b/pkg/ebpf/verifier/elf.go index 31ef4ce75855e..3f1210852fd05 100644 --- a/pkg/ebpf/verifier/elf.go +++ b/pkg/ebpf/verifier/elf.go @@ -44,6 +44,8 @@ import ( "errors" "fmt" "io" + "path/filepath" + "runtime" "github.com/cilium/ebpf" ) @@ -252,7 +254,11 @@ func getSourceMap(file string, spec *ebpf.CollectionSpec) (map[string]map[int]*S prevAddress = int(line.Address) startPoint := progStartPoint{sequenceIndex, int64(line.Address)} - lineinfo := fmt.Sprintf("%s:%d", line.File.Name, line.Line) + absFilePath, err := ensureSourceFilePathIsAbsolute(line.File.Name) + if err != nil { + return nil, nil, fmt.Errorf("cannot get absolute path for %s: %w", line.File.Name, err) + } + lineinfo := fmt.Sprintf("%s:%d", absFilePath, line.Line) // Reset the current program only if it's the first time we see it. Multiple // assembly instructions might point to the first source line of a program @@ -310,3 +316,18 @@ func getSourceMap(file string, spec *ebpf.CollectionSpec) (map[string]map[int]*S return sourceMap, funcsPerSection, nil } + +func ensureSourceFilePathIsAbsolute(path string) (string, error) { + if filepath.IsAbs(path) { + return path, nil + } + + _, b, _, _ := runtime.Caller(0) + basepath := filepath.Dir(b) + repoRoot, err := filepath.Abs(filepath.Join(basepath, "..", "..", "..")) + if err != nil { + return "", err + } + + return filepath.Join(repoRoot, path), nil +} diff --git a/pkg/ebpf/verifier/elf_test.go b/pkg/ebpf/verifier/elf_test.go index 4132fd3bf62a6..bf62e28059314 100644 --- a/pkg/ebpf/verifier/elf_test.go +++ b/pkg/ebpf/verifier/elf_test.go @@ -21,6 +21,7 @@ import ( ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" "github.com/DataDog/datadog-agent/pkg/util/filesystem" + "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/stretchr/testify/require" ) @@ -40,8 +41,13 @@ func TestGetSourceMap(t *testing.T) { return nil } - if _, ok := objectFiles[d.Name()]; !ok { - objectFiles[d.Name()] = path + objName := d.Name() + if strings.Contains(path, "/co-re/") { + objName = "co-re/" + objName + } + + if _, ok := objectFiles[objName]; !ok { + objectFiles[objName] = path } return nil }) @@ -52,6 +58,7 @@ func TestGetSourceMap(t *testing.T) { for name, path := range objectFiles { t.Run(name, func(tt *testing.T) { + log.Debugf("Processing %s", path) spec, err := ebpf.LoadCollectionSpec(path) require.NoError(tt, err) sourceMap, funcsPerSection, err := getSourceMap(path, spec) @@ -110,6 +117,14 @@ func TestGetSourceMap(t *testing.T) { require.GreaterOrEqual(tt, line, 0, "invalid line %d, ins %d", line, ins) require.LessOrEqual(tt, line, len(fileCache[sourceFile]), "line %d not found in %s, ins %d", line, sourceFile, ins) expectedLine := fileCache[sourceFile][line-1] + + if expectedLine == "{" && expectedLine != sl.Line && line > 1 { + // We have problems with the initial instructions sometimes, as one + // source can assign them to the opening brace and another to the function declaration + // if they're in different lines. Try with the previous line in that case. + expectedLine = fileCache[sourceFile][line-2] + } + require.Equal(tt, expectedLine, sl.Line, "mismatch at instruction %d, lineinfo=%s, prog %s", ins, sl.LineInfo, prog) } diff --git a/pkg/ebpf/verifier/types.go b/pkg/ebpf/verifier/types.go index bed3c5af06667..401c86d6d1b66 100644 --- a/pkg/ebpf/verifier/types.go +++ b/pkg/ebpf/verifier/types.go @@ -51,6 +51,7 @@ type InstructionInfo struct { Code string `json:"code"` RegisterState map[int]*RegisterState `json:"register_state"` // Register state after execution of the instruction RegisterStateRaw string `json:"register_state_raw"` + IsDoubleWidth bool `json:"is_double_width"` } // SourceLineStats holds the aggregate verifier statistics for a given C source line diff --git a/pkg/ebpf/verifier/verifier_log_parser.go b/pkg/ebpf/verifier/verifier_log_parser.go index 65a2252cf2b14..aabef65c81578 100644 --- a/pkg/ebpf/verifier/verifier_log_parser.go +++ b/pkg/ebpf/verifier/verifier_log_parser.go @@ -6,6 +6,7 @@ package verifier import ( + "errors" "fmt" "math" "regexp" @@ -18,6 +19,7 @@ var ( regStateRegex = regexp.MustCompile(`^([0-9]+): (R[0-9]+.*)`) singleRegStateRegex = regexp.MustCompile(`R([0-9]+)(_[^=]+)?=([^ ]+)`) regInfoRegex = regexp.MustCompile(`^(P)?([a-z_]+)?(P)?(-?[0-9]+|\((.*)\))`) + doubleWidthInsRegex = regexp.MustCompile(`r[0-9] = 0x[0-9a-f]{16}$`) ) // verifierLogParser is a struct that maintains the state necessary to parse the verifier log @@ -72,6 +74,8 @@ func (vlp *verifierLogParser) parseVerifierLog(log string) (*ComplexityInfo, err return &vlp.complexity, nil } +var errNotFound = errors.New("instruction not found") + func (vlp *verifierLogParser) tryAttachRegisterState(regData string, insIdx int) error { insinfo, ok := vlp.complexity.InsnMap[insIdx] if !ok { @@ -79,7 +83,7 @@ func (vlp *verifierLogParser) tryAttachRegisterState(regData string, insIdx int) // the verifier outputs register state. For example, in some versions it will generate // the state *before* each instruction, but we want the state *after* the instruction, and // as such the first state we find (state before instruction 1) will have no match, for example. - return nil + return errNotFound } // For ease of parsing, replace certain patterns that introduce spaces and make parsing harder @@ -111,7 +115,14 @@ func (vlp *verifierLogParser) parseLine(line string) error { // Try attach the register state to the previous instruction err = vlp.tryAttachRegisterState(match[2], regInsnIdx-1) - if err != nil { + if errors.Is(err, errNotFound) { + // The previous instruction was not found. Check if the previous one is double width, and try to attach to the one before that + // We need to do this because the instruction index jumps one when we have a double width instruction + if insinfo, ok := vlp.complexity.InsnMap[regInsnIdx-2]; ok && insinfo.IsDoubleWidth { + err = vlp.tryAttachRegisterState(match[2], regInsnIdx-2) + } + } + if err != nil && !errors.Is(err, errNotFound) { return fmt.Errorf("failed to attach register state (line is '%s'): %w", line, err) } return nil @@ -134,12 +145,13 @@ func (vlp *verifierLogParser) parseLine(line string) error { if vlp.progSourceMap != nil { insinfo.Source = vlp.progSourceMap[insIdx] } + insinfo.IsDoubleWidth = doubleWidthInsRegex.MatchString(insinfo.Code) // In some kernel versions (6.5 at least), the register state for the next instruction might be printed after this instruction if len(match) >= 4 && match[3] != "" { regData := match[3][2:] // Remove the leading "; " err = vlp.tryAttachRegisterState(regData, insIdx) - if err != nil { + if err != nil && !errors.Is(err, errNotFound) { return fmt.Errorf("Cannot attach register state to instruction %d: %w", insIdx, err) } } diff --git a/pkg/ebpf/verifier/verifier_log_parser_test.go b/pkg/ebpf/verifier/verifier_log_parser_test.go index 89b7c5dc3d700..e7aa334bafbf3 100644 --- a/pkg/ebpf/verifier/verifier_log_parser_test.go +++ b/pkg/ebpf/verifier/verifier_log_parser_test.go @@ -235,6 +235,53 @@ func TestLogParsingWith(t *testing.T) { }, }, }, + { + name: "DoubleWidthInstruction", + input: "1803: R0=0\n1803: (18) r1 = 0xffff0001f3b06000\n1805: R1=1\n", + progSourceMap: map[int]*SourceLine{ + 1803: { + LineInfo: "file.c:5", + Line: "int a = 2", + }, + 1805: { + LineInfo: "file.c:5", + Line: "int a = 2", + }, + }, + expected: ComplexityInfo{ + InsnMap: map[int]*InstructionInfo{ + 1803: { + Index: 1803, + TimesProcessed: 1, + Source: &SourceLine{ + LineInfo: "file.c:5", + Line: "int a = 2", + }, + Code: "r1 = 0xffff0001f3b06000", + RegisterState: map[int]*RegisterState{ + 1: { + Register: 1, + Live: "", + Type: "scalar", + Value: "1", + Precise: false, + }, + }, + RegisterStateRaw: "R1=1", + IsDoubleWidth: true, + }, + }, + SourceMap: map[string]*SourceLineStats{ + "file.c:5": { + NumInstructions: 1, + MaxPasses: 1, + MinPasses: 1, + TotalInstructionsProcessed: 1, + AssemblyInsns: []int{1803}, + }, + }, + }, + }, } for _, tt := range tests { diff --git a/pkg/eventmonitor/eventmonitor.go b/pkg/eventmonitor/eventmonitor.go index 1d1b71eac7b87..1b57d1a9560b0 100644 --- a/pkg/eventmonitor/eventmonitor.go +++ b/pkg/eventmonitor/eventmonitor.go @@ -29,7 +29,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/secl/model" "github.com/DataDog/datadog-agent/pkg/security/seclog" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) var ( @@ -230,7 +229,7 @@ func (m *EventMonitor) GetStats() map[string]interface{} { } // NewEventMonitor instantiates an event monitoring system-probe module -func NewEventMonitor(config *config.Config, secconfig *secconfig.Config, opts Opts, wmeta optional.Option[workloadmeta.Component], telemetry telemetry.Component) (*EventMonitor, error) { +func NewEventMonitor(config *config.Config, secconfig *secconfig.Config, opts Opts, wmeta workloadmeta.Component, telemetry telemetry.Component) (*EventMonitor, error) { if opts.StatsdClient == nil { opts.StatsdClient = procstatsd.Client } diff --git a/pkg/eventmonitor/testutil/testutil.go b/pkg/eventmonitor/testutil/testutil.go index 209216fdbe00b..74bded51f3498 100644 --- a/pkg/eventmonitor/testutil/testutil.go +++ b/pkg/eventmonitor/testutil/testutil.go @@ -15,14 +15,15 @@ import ( "github.com/stretchr/testify/require" sysconfig "github.com/DataDog/datadog-agent/cmd/system-probe/config" + "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/core/telemetry" "github.com/DataDog/datadog-agent/comp/core/telemetry/telemetryimpl" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + wmmock "github.com/DataDog/datadog-agent/comp/core/workloadmeta/fx-mock" "github.com/DataDog/datadog-agent/pkg/eventmonitor" emconfig "github.com/DataDog/datadog-agent/pkg/eventmonitor/config" secconfig "github.com/DataDog/datadog-agent/pkg/security/config" "github.com/DataDog/datadog-agent/pkg/util/fxutil" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // PreStartCallback is a callback to register clients to the event monitor before starting it @@ -42,7 +43,11 @@ func StartEventMonitor(t *testing.T, callback PreStartCallback) { opts := eventmonitor.Opts{} telemetry := fxutil.Test[telemetry.Component](t, telemetryimpl.MockModule()) - evm, err := eventmonitor.NewEventMonitor(emconfig, secconfig, opts, optional.NewNoneOption[workloadmeta.Component](), telemetry) + wmeta := fxutil.Test[workloadmeta.Component](t, + core.MockBundle(), + wmmock.MockModule(workloadmeta.NewParams()), + ) + evm, err := eventmonitor.NewEventMonitor(emconfig, secconfig, opts, wmeta, telemetry) require.NoError(t, err) require.NoError(t, evm.Init()) callback(t, evm) diff --git a/pkg/flare/archive.go b/pkg/flare/archive.go index 5d9275822e638..59024af02be5e 100644 --- a/pkg/flare/archive.go +++ b/pkg/flare/archive.go @@ -32,6 +32,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/diagnose/diagnosis" "github.com/DataDog/datadog-agent/pkg/status/health" systemprobeStatus "github.com/DataDog/datadog-agent/pkg/status/systemprobe" + "github.com/DataDog/datadog-agent/pkg/util/ecs" "github.com/DataDog/datadog-agent/pkg/util/installinfo" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -92,6 +93,7 @@ func CompleteFlare(fb flaretypes.FlareBuilder, diagnoseDeps diagnose.SuitesDeps) fb.AddFileFromFunc("docker_ps.log", getDockerPs) //nolint:errcheck fb.AddFileFromFunc("k8s/kubelet_config.yaml", getKubeletConfig) //nolint:errcheck fb.AddFileFromFunc("k8s/kubelet_pods.yaml", getKubeletPods) //nolint:errcheck + fb.AddFileFromFunc("ecs_metadata.json", getECSMeta) //nolint:errcheck getRegistryJSON(fb) @@ -394,6 +396,18 @@ func getHealth() ([]byte, error) { return yamlValue, nil } +func getECSMeta() ([]byte, error) { + ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second) + defer cancel() + + ecsMeta, err := ecs.NewECSMeta(ctx) + if err != nil { + return nil, err + } + + return json.MarshalIndent(ecsMeta, "", "\t") +} + // getHTTPCallContent does a GET HTTP call to the given url and // writes the content of the HTTP response in the given file, ready // to be shipped in a flare. diff --git a/pkg/flare/archive_docker.go b/pkg/flare/archive_docker.go index 824553a6ef588..4b9b67c0139c8 100644 --- a/pkg/flare/archive_docker.go +++ b/pkg/flare/archive_docker.go @@ -17,7 +17,7 @@ import ( "text/tabwriter" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/containers/metrics" "github.com/DataDog/datadog-agent/pkg/util/docker" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -28,7 +28,7 @@ import ( const dockerCommandMaxLength = 29 func getDockerSelfInspect(wmeta optional.Option[workloadmeta.Component]) ([]byte, error) { - if !config.IsContainerized() { + if !env.IsContainerized() { return nil, fmt.Errorf("The Agent is not containerized") } diff --git a/pkg/fleet/env/env.go b/pkg/fleet/env/env.go index a9b46e91e1f62..a8df613e0b0e4 100644 --- a/pkg/fleet/env/env.go +++ b/pkg/fleet/env/env.go @@ -20,6 +20,7 @@ const ( envAPIKey = "DD_API_KEY" envSite = "DD_SITE" envRemoteUpdates = "DD_REMOTE_UPDATES" + envRemotePolicies = "DD_REMOTE_POLICIES" envRegistryURL = "DD_INSTALLER_REGISTRY_URL" envRegistryAuth = "DD_INSTALLER_REGISTRY_AUTH" envDefaultPackageVersion = "DD_INSTALLER_DEFAULT_PKG_VERSION" @@ -56,9 +57,10 @@ type ApmLibVersion string // Env contains the configuration for the installer. type Env struct { - APIKey string - Site string - RemoteUpdates bool + APIKey string + Site string + RemoteUpdates bool + RemotePolicies bool RegistryOverride string RegistryAuthOverride string @@ -79,16 +81,17 @@ type Env struct { // FromEnv returns an Env struct with values from the environment. func FromEnv() *Env { return &Env{ - APIKey: getEnvOrDefault(envAPIKey, defaultEnv.APIKey), - Site: getEnvOrDefault(envSite, defaultEnv.Site), - RemoteUpdates: os.Getenv(envRemoteUpdates) == "true", + APIKey: getEnvOrDefault(envAPIKey, defaultEnv.APIKey), + Site: getEnvOrDefault(envSite, defaultEnv.Site), + RemoteUpdates: strings.ToLower(os.Getenv(envRemoteUpdates)) == "true", + RemotePolicies: strings.ToLower(os.Getenv(envRemotePolicies)) == "true", RegistryOverride: getEnvOrDefault(envRegistryURL, defaultEnv.RegistryOverride), RegistryAuthOverride: getEnvOrDefault(envRegistryAuth, defaultEnv.RegistryAuthOverride), RegistryOverrideByImage: overridesByNameFromEnv(envRegistryURL, func(s string) string { return s }), RegistryAuthOverrideByImage: overridesByNameFromEnv(envRegistryAuth, func(s string) string { return s }), - DefaultPackagesInstallOverride: overridesByNameFromEnv(envDefaultPackageInstall, func(s string) bool { return s == "true" }), + DefaultPackagesInstallOverride: overridesByNameFromEnv(envDefaultPackageInstall, func(s string) bool { return strings.ToLower(s) == "true" }), DefaultPackagesVersionOverride: overridesByNameFromEnv(envDefaultPackageVersion, func(s string) string { return s }), ApmLibraries: parseApmLibrariesEnv(), diff --git a/pkg/fleet/installer/default_packages.go b/pkg/fleet/installer/default_packages.go index c00688dc3d113..dad23e5ce3241 100644 --- a/pkg/fleet/installer/default_packages.go +++ b/pkg/fleet/installer/default_packages.go @@ -32,17 +32,17 @@ var PackagesList = []Package{ {Name: "datadog-apm-library-js", version: apmLanguageVersion, released: true, condition: apmLanguageEnabled}, {Name: "datadog-apm-library-dotnet", version: apmLanguageVersion, released: true, condition: apmLanguageEnabled}, {Name: "datadog-apm-library-python", version: apmLanguageVersion, released: true, condition: apmLanguageEnabled}, + {Name: "datadog-apm-library-php", version: apmLanguageVersion, released: true, condition: apmLanguageEnabled}, {Name: "datadog-agent", version: agentVersion, released: false, releasedWithRemoteUpdates: true}, } -var packageDependencies = map[string][]string{} - var apmPackageDefaultVersions = map[string]string{ "datadog-apm-library-java": "1", "datadog-apm-library-ruby": "2", "datadog-apm-library-js": "5", "datadog-apm-library-dotnet": "2", "datadog-apm-library-python": "2", + "datadog-apm-library-php": "1", } // DefaultPackages resolves the default packages URLs to install based on the environment. @@ -86,16 +86,18 @@ func apmInjectEnabled(_ Package, e *env.Env) bool { return false } +// apmLanguageEnabled returns true if the package should be installed +// Note: the PHP tracer is in beta and isn't included in the "all" or default languages func apmLanguageEnabled(p Package, e *env.Env) bool { if _, ok := e.ApmLibraries[packageToLanguage(p.Name)]; ok { return true } - if _, ok := e.ApmLibraries["all"]; ok { + if _, ok := e.ApmLibraries["all"]; ok && p.Name != "datadog-apm-library-php" { return true } // If the ApmLibraries env is left empty but apm injection is // enabled, we install all languages - if len(e.ApmLibraries) == 0 && apmInjectEnabled(p, e) { + if len(e.ApmLibraries) == 0 && apmInjectEnabled(p, e) && p.Name != "datadog-apm-library-php" { return true } return false diff --git a/pkg/fleet/installer/default_packages_test.go b/pkg/fleet/installer/default_packages_test.go index 2276e98fcc06a..1707fff0a5609 100644 --- a/pkg/fleet/installer/default_packages_test.go +++ b/pkg/fleet/installer/default_packages_test.go @@ -199,6 +199,7 @@ func TestDefaultPackages(t *testing.T) { DefaultPackagesInstallOverride: map[string]bool{ "datadog-apm-library-java": true, "datadog-apm-library-ruby": true, + "datadog-apm-library-php": true, }, }, expected: []pkg{ @@ -251,15 +252,18 @@ func TestDefaultPackages(t *testing.T) { packages: []Package{ {Name: "datadog-apm-library-java", version: apmLanguageVersion, released: true, condition: apmLanguageEnabled}, {Name: "datadog-apm-library-ruby", version: apmLanguageVersion, released: true, condition: apmLanguageEnabled}, + {Name: "datadog-apm-library-php", version: apmLanguageVersion, released: true, condition: apmLanguageEnabled}, }, env: &env.Env{ ApmLibraries: map[env.ApmLibLanguage]env.ApmLibVersion{ "java": "1.2.3", + "php": "1", }, InstallScript: env.InstallScriptEnv{}, }, expected: []pkg{ {n: "datadog-apm-library-java", v: "1.2.3-1"}, + {n: "datadog-apm-library-php", v: "1"}, }, }, } diff --git a/pkg/fleet/installer/installer.go b/pkg/fleet/installer/installer.go index 88d571deba895..b51f585ecd2a2 100644 --- a/pkg/fleet/installer/installer.go +++ b/pkg/fleet/installer/installer.go @@ -18,6 +18,7 @@ import ( "sync" "time" + "github.com/DataDog/datadog-agent/pkg/fleet/internal/cdn" "github.com/DataDog/datadog-agent/pkg/fleet/internal/paths" "github.com/DataDog/datadog-agent/pkg/fleet/env" @@ -66,42 +67,48 @@ type Installer interface { type installerImpl struct { m sync.Mutex - db *db.PackagesDB - downloader *oci.Downloader - repositories *repository.Repositories - configsDir string - packagesDir string - tmpDirPath string + env *env.Env + cdn *cdn.CDN + db *db.PackagesDB + downloader *oci.Downloader + packages *repository.Repositories + configs *repository.Repositories + + packagesDir string + userConfigsDir string } // NewInstaller returns a new Package Manager. func NewInstaller(env *env.Env) (Installer, error) { - err := ensurePackageDirExists() + err := ensureRepositoriesExist() if err != nil { - return nil, fmt.Errorf("could not ensure packages directory exists: %w", err) + return nil, fmt.Errorf("could not ensure packages and config directory exists: %w", err) } db, err := db.New(filepath.Join(paths.PackagesPath, "packages.db"), db.WithTimeout(10*time.Second)) if err != nil { return nil, fmt.Errorf("could not create packages db: %w", err) } return &installerImpl{ - db: db, - downloader: oci.NewDownloader(env, http.DefaultClient), - repositories: repository.NewRepositories(paths.PackagesPath, paths.LocksPack), - configsDir: paths.DefaultConfigsDir, - tmpDirPath: paths.TmpDirPath, - packagesDir: paths.PackagesPath, + env: env, + cdn: cdn.New(env), + db: db, + downloader: oci.NewDownloader(env, http.DefaultClient), + packages: repository.NewRepositories(paths.PackagesPath, paths.LocksPath), + configs: repository.NewRepositories(paths.ConfigsPath, paths.LocksPath), + + userConfigsDir: paths.DefaultUserConfigsDir, + packagesDir: paths.PackagesPath, }, nil } // State returns the state of a package. func (i *installerImpl) State(pkg string) (repository.State, error) { - return i.repositories.GetPackageState(pkg) + return i.packages.GetPackageState(pkg) } // States returns the states of all packages. func (i *installerImpl) States() (map[string]repository.State, error) { - return i.repositories.GetState() + return i.packages.GetState() } // IsInstalled checks if a package is installed. @@ -138,18 +145,6 @@ func (i *installerImpl) Install(ctx context.Context, url string, args []string) span.SetTag(ext.ResourceName, pkg.Name) span.SetTag("package_version", pkg.Version) } - - for _, dependency := range packageDependencies[pkg.Name] { - installed, err := i.IsInstalled(ctx, dependency) - if err != nil { - return fmt.Errorf("could not check if required package %s is installed: %w", dependency, err) - } - if !installed { - // TODO: we should resolve the dependency version & install it instead - return fmt.Errorf("required package %s is not installed", dependency) - } - } - dbPkg, err := i.db.GetPackage(pkg.Name) if err != nil && !errors.Is(err, db.ErrPackageNotFound) { return fmt.Errorf("could not get package: %w", err) @@ -162,12 +157,12 @@ func (i *installerImpl) Install(ctx context.Context, url string, args []string) if err != nil { return fmt.Errorf("not enough disk space: %w", err) } - tmpDir, err := os.MkdirTemp(i.tmpDirPath, fmt.Sprintf("tmp-install-stable-%s-*", pkg.Name)) // * is replaced by a random string + tmpDir, err := i.packages.MkdirTemp() if err != nil { return fmt.Errorf("could not create temporary directory: %w", err) } defer os.RemoveAll(tmpDir) - configDir := filepath.Join(i.configsDir, pkg.Name) + configDir := filepath.Join(i.userConfigsDir, pkg.Name) err = pkg.ExtractLayers(oci.DatadogPackageLayerMediaType, tmpDir) if err != nil { return fmt.Errorf("could not extract package layers: %w", err) @@ -176,10 +171,14 @@ func (i *installerImpl) Install(ctx context.Context, url string, args []string) if err != nil { return fmt.Errorf("could not extract package config layer: %w", err) } - err = i.repositories.Create(pkg.Name, pkg.Version, tmpDir) + err = i.packages.Create(pkg.Name, pkg.Version, tmpDir) if err != nil { return fmt.Errorf("could not create repository: %w", err) } + err = i.configurePackage(ctx, pkg.Name) + if err != nil { + return fmt.Errorf("could not configure package: %w", err) + } err = i.setupPackage(ctx, pkg.Name, args) if err != nil { return fmt.Errorf("could not setup package: %w", err) @@ -207,12 +206,12 @@ func (i *installerImpl) InstallExperiment(ctx context.Context, url string) error if err != nil { return fmt.Errorf("not enough disk space: %w", err) } - tmpDir, err := os.MkdirTemp(i.tmpDirPath, fmt.Sprintf("tmp-install-experiment-%s-*", pkg.Name)) // * is replaced by a random string + tmpDir, err := i.packages.MkdirTemp() if err != nil { return fmt.Errorf("could not create temporary directory: %w", err) } defer os.RemoveAll(tmpDir) - configDir := filepath.Join(i.configsDir, pkg.Name) + configDir := filepath.Join(i.userConfigsDir, pkg.Name) err = pkg.ExtractLayers(oci.DatadogPackageLayerMediaType, tmpDir) if err != nil { return fmt.Errorf("could not extract package layers: %w", err) @@ -221,7 +220,7 @@ func (i *installerImpl) InstallExperiment(ctx context.Context, url string) error if err != nil { return fmt.Errorf("could not extract package config layer: %w", err) } - repository := i.repositories.Get(pkg.Name) + repository := i.packages.Get(pkg.Name) err = repository.SetExperiment(pkg.Version, tmpDir) if err != nil { return fmt.Errorf("could not set experiment: %w", err) @@ -234,7 +233,7 @@ func (i *installerImpl) RemoveExperiment(ctx context.Context, pkg string) error i.m.Lock() defer i.m.Unlock() - repository := i.repositories.Get(pkg) + repository := i.packages.Get(pkg) if runtime.GOOS != "windows" && pkg == packageDatadogInstaller { // Special case for the Linux installer since `stopExperiment` // will kill the current process, delete the experiment first. @@ -264,7 +263,7 @@ func (i *installerImpl) PromoteExperiment(ctx context.Context, pkg string) error i.m.Lock() defer i.m.Unlock() - repository := i.repositories.Get(pkg) + repository := i.packages.Get(pkg) err := repository.PromoteExperiment() if err != nil { return fmt.Errorf("could not promote experiment: %w", err) @@ -297,12 +296,16 @@ func (i *installerImpl) Purge(ctx context.Context) { log.Warnf("could not remove installer: %v", err) } + err = os.RemoveAll(paths.ConfigsPath) + if err != nil { + log.Warnf("could not delete configs dir: %v", err) + } // remove all from disk span, _ := tracer.StartSpanFromContext(ctx, "remove_all") err = os.RemoveAll(paths.PackagesPath) defer span.Finish(tracer.WithError(err)) if err != nil { - log.Warnf("could not remove path: %v", err) + log.Warnf("could not delete packages dir: %v", err) } } @@ -314,7 +317,7 @@ func (i *installerImpl) Remove(ctx context.Context, pkg string) error { if err != nil { return fmt.Errorf("could not remove package: %w", err) } - err = i.repositories.Delete(ctx, pkg) + err = i.packages.Delete(ctx, pkg) if err != nil { return fmt.Errorf("could not delete repository: %w", err) } @@ -329,8 +332,15 @@ func (i *installerImpl) Remove(ctx context.Context, pkg string) error { func (i *installerImpl) GarbageCollect(_ context.Context) error { i.m.Lock() defer i.m.Unlock() - - return i.repositories.Cleanup() + err := i.packages.Cleanup() + if err != nil { + return fmt.Errorf("could not cleanup packages: %w", err) + } + err = i.configs.Cleanup() + if err != nil { + return fmt.Errorf("could not cleanup configs: %w", err) + } + return nil } // InstrumentAPMInjector instruments the APM injector. @@ -432,6 +442,19 @@ func (i *installerImpl) removePackage(ctx context.Context, pkg string) error { } } +func (i *installerImpl) configurePackage(ctx context.Context, pkg string) error { + if !i.env.RemotePolicies { + return nil + } + + switch pkg { + case packageDatadogAgent: + return service.ConfigureAgent(ctx, i.cdn, i.configs) + default: + return nil + } +} + const ( packageUnknownSize = 2 << 30 // 2GiB installerOverhead = 10 << 20 // 10MiB @@ -465,10 +488,14 @@ func checkAvailableDiskSpace(pkg *oci.DownloadedPackage, path string) error { return nil } -func ensurePackageDirExists() error { +func ensureRepositoriesExist() error { err := os.MkdirAll(paths.PackagesPath, 0755) if err != nil { return fmt.Errorf("error creating packages directory: %w", err) } + err = os.MkdirAll(paths.ConfigsPath, 0755) + if err != nil { + return fmt.Errorf("error creating configs directory: %w", err) + } return nil } diff --git a/pkg/fleet/installer/installer_test.go b/pkg/fleet/installer/installer_test.go index a548fd2c596fe..069c2e04cf9e8 100644 --- a/pkg/fleet/installer/installer_test.go +++ b/pkg/fleet/installer/installer_test.go @@ -7,12 +7,13 @@ package installer import ( "context" - "github.com/stretchr/testify/assert" "io/fs" "os" "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/DataDog/datadog-agent/pkg/fleet/env" "github.com/DataDog/datadog-agent/pkg/fleet/installer/repository" "github.com/DataDog/datadog-agent/pkg/fleet/internal/db" @@ -27,23 +28,23 @@ type testPackageManager struct { } func newTestPackageManager(t *testing.T, s *fixtures.Server, rootPath string, locksPath string) *testPackageManager { - repositories := repository.NewRepositories(rootPath, locksPath) + packages := repository.NewRepositories(rootPath, locksPath) db, err := db.New(filepath.Join(rootPath, "packages.db")) assert.NoError(t, err) return &testPackageManager{ installerImpl{ - db: db, - downloader: oci.NewDownloader(&env.Env{}, s.Client()), - repositories: repositories, - configsDir: t.TempDir(), - tmpDirPath: rootPath, - packagesDir: rootPath, + env: &env.Env{}, + db: db, + downloader: oci.NewDownloader(&env.Env{}, s.Client()), + packages: packages, + userConfigsDir: t.TempDir(), + packagesDir: rootPath, }, } } func (i *testPackageManager) ConfigFS(f fixtures.Fixture) fs.FS { - return os.DirFS(filepath.Join(i.configsDir, f.Package)) + return os.DirFS(filepath.Join(i.userConfigsDir, f.Package)) } func TestInstallStable(t *testing.T) { @@ -53,7 +54,7 @@ func TestInstallStable(t *testing.T) { err := installer.Install(testCtx, s.PackageURL(fixtures.FixtureSimpleV1), nil) assert.NoError(t, err) - r := installer.repositories.Get(fixtures.FixtureSimpleV1.Package) + r := installer.packages.Get(fixtures.FixtureSimpleV1.Package) state, err := r.GetState() assert.NoError(t, err) assert.Equal(t, fixtures.FixtureSimpleV1.Version, state.Stable) @@ -71,7 +72,7 @@ func TestInstallExperiment(t *testing.T) { assert.NoError(t, err) err = installer.InstallExperiment(testCtx, s.PackageURL(fixtures.FixtureSimpleV2)) assert.NoError(t, err) - r := installer.repositories.Get(fixtures.FixtureSimpleV1.Package) + r := installer.packages.Get(fixtures.FixtureSimpleV1.Package) state, err := r.GetState() assert.NoError(t, err) assert.Equal(t, fixtures.FixtureSimpleV1.Version, state.Stable) @@ -92,7 +93,7 @@ func TestInstallPromoteExperiment(t *testing.T) { assert.NoError(t, err) err = installer.PromoteExperiment(testCtx, fixtures.FixtureSimpleV1.Package) assert.NoError(t, err) - r := installer.repositories.Get(fixtures.FixtureSimpleV1.Package) + r := installer.packages.Get(fixtures.FixtureSimpleV1.Package) state, err := r.GetState() assert.NoError(t, err) assert.Equal(t, fixtures.FixtureSimpleV2.Version, state.Stable) @@ -112,7 +113,7 @@ func TestUninstallExperiment(t *testing.T) { assert.NoError(t, err) err = installer.RemoveExperiment(testCtx, fixtures.FixtureSimpleV1.Package) assert.NoError(t, err) - r := installer.repositories.Get(fixtures.FixtureSimpleV1.Package) + r := installer.packages.Get(fixtures.FixtureSimpleV1.Package) state, err := r.GetState() assert.NoError(t, err) assert.Equal(t, fixtures.FixtureSimpleV1.Version, state.Stable) diff --git a/pkg/fleet/installer/repository/repositories.go b/pkg/fleet/installer/repository/repositories.go index 66e08d70bd342..ac2ee7988aa5f 100644 --- a/pkg/fleet/installer/repository/repositories.go +++ b/pkg/fleet/installer/repository/repositories.go @@ -13,6 +13,10 @@ import ( "strings" ) +const ( + tempDirPrefix = "tmp-i-" +) + // Repositories manages multiple repositories. type Repositories struct { rootPath string @@ -44,8 +48,12 @@ func (r *Repositories) loadRepositories() (map[string]*Repository, error) { if !d.IsDir() { continue } - if strings.HasPrefix(d.Name(), "tmp-install") { - // Temporary extraction dir, ignore + if strings.HasPrefix(d.Name(), tempDirPrefix) { + // Temporary dir created by Repositories.MkdirTemp, ignore + continue + } + if d.Name() == "run" { + // run dir, ignore continue } repo := r.newRepository(d.Name()) @@ -116,3 +124,10 @@ func (r *Repositories) Cleanup() error { } return nil } + +// MkdirTemp creates a temporary directory in the same partition as the root path. +// This ensures that the temporary directory can be moved to the root path without copying. +// The caller is responsible for cleaning up the directory. +func (r *Repositories) MkdirTemp() (string, error) { + return os.MkdirTemp(r.rootPath, tempDirPrefix+"*") +} diff --git a/pkg/fleet/installer/repository/repositories_test.go b/pkg/fleet/installer/repository/repositories_test.go index 28d7bcc888049..bac3114c3fcde 100644 --- a/pkg/fleet/installer/repository/repositories_test.go +++ b/pkg/fleet/installer/repository/repositories_test.go @@ -6,6 +6,8 @@ package repository import ( + "os" + "path" "testing" "github.com/stretchr/testify/assert" @@ -59,3 +61,17 @@ func TestRepositoriesReopen(t *testing.T) { assert.Equal(t, state["repo1"], State{Stable: "v1"}) assert.Equal(t, state["repo2"], State{Stable: "v1"}) } + +func TestLoadRepositories(t *testing.T) { + rootDir := t.TempDir() + runDir := t.TempDir() + + os.Mkdir(path.Join(rootDir, "datadog-agent"), 0755) + os.Mkdir(path.Join(rootDir, tempDirPrefix+"2394812349"), 0755) + + repositories, err := NewRepositories(rootDir, runDir).loadRepositories() + assert.NoError(t, err) + assert.Len(t, repositories, 1) + assert.Contains(t, repositories, "datadog-agent") + assert.NotContains(t, repositories, tempDirPrefix+"2394812349") +} diff --git a/pkg/fleet/installer/repository/repository.go b/pkg/fleet/installer/repository/repository.go index 202f60c16780b..559bf88854641 100644 --- a/pkg/fleet/installer/repository/repository.go +++ b/pkg/fleet/installer/repository/repository.go @@ -93,9 +93,14 @@ func (r *Repository) GetState() (State, error) { if err != nil { return State{}, err } + stable := repository.stable.Target() + experiment := repository.experiment.Target() + if experiment == stable { + experiment = "" + } return State{ - Stable: repository.stable.Target(), - Experiment: repository.experiment.Target(), + Stable: stable, + Experiment: experiment, }, nil } @@ -157,6 +162,10 @@ func (r *Repository) Create(name string, stableSourcePath string) error { if err != nil { return fmt.Errorf("could not set first stable: %w", err) } + err = repository.setExperimentToStable() + if err != nil { + return fmt.Errorf("could not set first experiment: %w", err) + } return nil } @@ -175,7 +184,10 @@ func (r *Repository) SetExperiment(name string, sourcePath string) error { return fmt.Errorf("could not cleanup repository: %w", err) } if !repository.stable.Exists() { - return fmt.Errorf("stable package does not exist, invalid state") + return fmt.Errorf("stable link does not exist, invalid state") + } + if !repository.experiment.Exists() { + return fmt.Errorf("experiment link does not exist, invalid state") } err = repository.setExperiment(name, sourcePath) if err != nil { @@ -187,9 +199,8 @@ func (r *Repository) SetExperiment(name string, sourcePath string) error { // PromoteExperiment promotes the experiment to stable. // // 1. Cleanup the repository. -// 2. Set the stable link to the experiment package. -// 3. Delete the experiment link. -// 4. Cleanup the repository to remove the previous stable package. +// 2. Set the stable link to the experiment package. The experiment link stays in place. +// 3. Cleanup the repository to remove the previous stable package. func (r *Repository) PromoteExperiment() error { repository, err := readRepository(r.rootPath, r.locksPath) if err != nil { @@ -200,19 +211,18 @@ func (r *Repository) PromoteExperiment() error { return fmt.Errorf("could not cleanup repository: %w", err) } if !repository.stable.Exists() { - return fmt.Errorf("stable package does not exist, invalid state") + return fmt.Errorf("stable link does not exist, invalid state") } if !repository.experiment.Exists() { - return fmt.Errorf("experiment package does not exist, invalid state") + return fmt.Errorf("experiment link does not exist, invalid state") + } + if repository.stable.Target() == repository.experiment.Target() { + return fmt.Errorf("no experiment to promote") } err = repository.stable.Set(*repository.experiment.packagePath) if err != nil { return fmt.Errorf("could not set stable: %w", err) } - err = repository.experiment.Delete() - if err != nil { - return fmt.Errorf("could not delete experiment link: %w", err) - } // Read repository again to re-load the list of locked packages repository, err = readRepository(r.rootPath, r.locksPath) @@ -229,7 +239,7 @@ func (r *Repository) PromoteExperiment() error { // DeleteExperiment deletes the experiment. // // 1. Cleanup the repository. -// 2. Delete the experiment link. +// 2. Sets the experiment link to the stable link. // 3. Cleanup the repository to remove the previous experiment package. func (r *Repository) DeleteExperiment() error { repository, err := readRepository(r.rootPath, r.locksPath) @@ -241,14 +251,14 @@ func (r *Repository) DeleteExperiment() error { return fmt.Errorf("could not cleanup repository: %w", err) } if !repository.stable.Exists() { - return fmt.Errorf("stable package does not exist, invalid state") + return fmt.Errorf("stable link does not exist, invalid state") } if !repository.experiment.Exists() { - return nil + return fmt.Errorf("experiment link does not exist, invalid state") } - err = repository.experiment.Delete() + err = repository.setExperimentToStable() if err != nil { - return fmt.Errorf("could not delete experiment link: %w", err) + return fmt.Errorf("could not set experiment to stable: %w", err) } // Read repository again to re-load the list of locked packages @@ -328,6 +338,11 @@ func (r *repositoryFiles) setExperiment(name string, sourcePath string) error { return r.experiment.Set(path) } +// setExperimentToStable moves the experiment to stable. +func (r *repositoryFiles) setExperimentToStable() error { + return r.experiment.Set(r.stable.linkPath) +} + func (r *repositoryFiles) setStable(name string, sourcePath string) error { path, err := movePackageFromSource(name, r.rootPath, r.lockedPackages, sourcePath) if err != nil { @@ -367,6 +382,15 @@ func movePackageFromSource(packageName string, rootPath string, lockedPackages m } func (r *repositoryFiles) cleanup() error { + // migrate old repositories that are missing the experiment link + if r.stable.Exists() && !r.experiment.Exists() { + err := r.setExperimentToStable() + if err != nil { + return fmt.Errorf("could not migrate old repository without experiment link: %w", err) + } + } + + // remove left-over packages files, err := os.ReadDir(r.rootPath) if err != nil { return fmt.Errorf("could not read root directory: %w", err) diff --git a/pkg/fleet/installer/repository/repository_test.go b/pkg/fleet/installer/repository/repository_test.go index 5092181e0c570..9e47e4e48dd86 100644 --- a/pkg/fleet/installer/repository/repository_test.go +++ b/pkg/fleet/installer/repository/repository_test.go @@ -9,6 +9,7 @@ import ( "fmt" "os" "path" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -36,12 +37,27 @@ func createTestDownloadedPackage(t *testing.T, dir string, packageName string) s return downloadPath } +func assertLinkTarget(t *testing.T, repository *Repository, link string, target string) { + linkPath := path.Join(repository.rootPath, link) + assert.FileExists(t, linkPath) + linkTarget, err := linkRead(linkPath) + assert.NoError(t, err) + assert.Equal(t, target, filepath.Base(linkTarget)) +} + func TestCreateFresh(t *testing.T) { dir := t.TempDir() repository := createTestRepository(t, dir, "v1") + state, err := repository.GetState() assert.DirExists(t, repository.rootPath) assert.DirExists(t, path.Join(repository.rootPath, "v1")) + assert.NoError(t, err) + assert.True(t, state.HasStable()) + assert.Equal(t, "v1", state.Stable) + assert.False(t, state.HasExperiment()) + assertLinkTarget(t, repository, stableVersionLink, "v1") + assertLinkTarget(t, repository, experimentVersionLink, "v1") } func TestCreateOverwrite(t *testing.T) { @@ -87,8 +103,17 @@ func TestSetExperiment(t *testing.T) { experimentDownloadPackagePath := createTestDownloadedPackage(t, dir, "v2") err := repository.SetExperiment("v2", experimentDownloadPackagePath) + assert.NoError(t, err) + state, err := repository.GetState() + assert.NoError(t, err) assert.DirExists(t, path.Join(repository.rootPath, "v2")) + assert.True(t, state.HasStable()) + assert.Equal(t, "v1", state.Stable) + assert.True(t, state.HasExperiment()) + assert.Equal(t, "v2", state.Experiment) + assertLinkTarget(t, repository, stableVersionLink, "v1") + assertLinkTarget(t, repository, experimentVersionLink, "v2") } func TestSetExperimentTwice(t *testing.T) { @@ -124,8 +149,16 @@ func TestPromoteExperiment(t *testing.T) { assert.NoError(t, err) err = repository.PromoteExperiment() assert.NoError(t, err) + state, err := repository.GetState() + assert.NoError(t, err) + assert.NoDirExists(t, path.Join(repository.rootPath, "v1")) assert.DirExists(t, path.Join(repository.rootPath, "v2")) + assert.True(t, state.HasStable()) + assert.Equal(t, "v2", state.Stable) + assert.False(t, state.HasExperiment()) + assertLinkTarget(t, repository, stableVersionLink, "v2") + assertLinkTarget(t, repository, experimentVersionLink, "v2") } func TestPromoteExperimentWithoutExperiment(t *testing.T) { @@ -192,16 +225,15 @@ func TestDeleteExperimentWithLockedPackage(t *testing.T) { assert.FileExists(t, path.Join(repository.locksPath, "v2", fmt.Sprint(os.Getpid()))) } -func TestLoadRepositories(t *testing.T) { - rootDir := t.TempDir() - runDir := t.TempDir() - - os.Mkdir(path.Join(rootDir, "datadog-agent"), 0755) - os.Mkdir(path.Join(rootDir, "tmp-install-stable-datadog-agent"), 0755) +func TestMigrateRepositoryWithoutExperiment(t *testing.T) { + dir := t.TempDir() + repository := createTestRepository(t, dir, "v1") - repositories, err := NewRepositories(rootDir, runDir).loadRepositories() + err := os.Remove(path.Join(repository.rootPath, experimentVersionLink)) + assert.NoError(t, err) + assert.NoFileExists(t, path.Join(repository.rootPath, experimentVersionLink)) + err = repository.Cleanup() assert.NoError(t, err) - assert.Len(t, repositories, 1) - assert.Contains(t, repositories, "datadog-agent") - assert.NotContains(t, repositories, "tmp-install-stable-datadog-agent") + assertLinkTarget(t, repository, stableVersionLink, "v1") + assertLinkTarget(t, repository, experimentVersionLink, "v1") } diff --git a/pkg/fleet/installer/service/apm_sockets.go b/pkg/fleet/installer/service/apm_sockets.go index e691ef9438baa..b6d40a1010e01 100644 --- a/pkg/fleet/installer/service/apm_sockets.go +++ b/pkg/fleet/installer/service/apm_sockets.go @@ -25,7 +25,7 @@ const ( apmInstallerSocket = "/var/run/datadog/apm.socket" statsdInstallerSocket = "/var/run/datadog/dsd.socket" apmInjectOldPath = "/opt/datadog/apm/inject" - envFilePath = "/var/run/datadog-installer/environment" + envFilePath = "/opt/datadog-packages/run/environment" ) // Overridden in tests diff --git a/pkg/fleet/installer/service/datadog_agent.go b/pkg/fleet/installer/service/datadog_agent.go index 5c92bbb947932..30a69271d59d9 100644 --- a/pkg/fleet/installer/service/datadog_agent.go +++ b/pkg/fleet/installer/service/datadog_agent.go @@ -15,25 +15,32 @@ import ( "os" "os/exec" "path/filepath" + "strings" + "github.com/DataDog/datadog-agent/pkg/fleet/installer/repository" + "github.com/DataDog/datadog-agent/pkg/fleet/internal/cdn" "github.com/DataDog/datadog-agent/pkg/util/installinfo" "github.com/DataDog/datadog-agent/pkg/util/log" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" ) const ( - pathOldAgent = "/opt/datadog-agent" - agentSymlink = "/usr/bin/datadog-agent" - agentUnit = "datadog-agent.service" - traceAgentUnit = "datadog-agent-trace.service" - processAgentUnit = "datadog-agent-process.service" - systemProbeUnit = "datadog-agent-sysprobe.service" - securityAgentUnit = "datadog-agent-security.service" - agentExp = "datadog-agent-exp.service" - traceAgentExp = "datadog-agent-trace-exp.service" - processAgentExp = "datadog-agent-process-exp.service" - systemProbeExp = "datadog-agent-sysprobe-exp.service" - securityAgentExp = "datadog-agent-security-exp.service" + agentPackage = "datadog-agent" + pathOldAgent = "/opt/datadog-agent" + agentSymlink = "/usr/bin/datadog-agent" + agentUnit = "datadog-agent.service" + traceAgentUnit = "datadog-agent-trace.service" + processAgentUnit = "datadog-agent-process.service" + systemProbeUnit = "datadog-agent-sysprobe.service" + securityAgentUnit = "datadog-agent-security.service" + agentExp = "datadog-agent-exp.service" + traceAgentExp = "datadog-agent-trace-exp.service" + processAgentExp = "datadog-agent-process-exp.service" + systemProbeExp = "datadog-agent-sysprobe-exp.service" + securityAgentExp = "datadog-agent-security-exp.service" + configDatadogYAML = "datadog.yaml" + configSecurityAgentYAML = "security-agent.yaml" + configSystemProbeYAML = "system-probe.yaml" ) var ( @@ -53,6 +60,16 @@ var ( } ) +var ( + // matches omnibus/package-scripts/agent-deb/postinst + rootOwnedAgentPaths = []string{ + "embedded/bin/system-probe", + "embedded/bin/security-agent", + "embedded/share/system-probe/ebpf", + "embedded/share/system-probe/java", + } +) + // SetupAgent installs and starts the agent func SetupAgent(ctx context.Context, _ []string) (err error) { span, ctx := tracer.StartSpanFromContext(ctx, "setup_agent") @@ -89,7 +106,7 @@ func SetupAgent(ctx context.Context, _ []string) (err error) { if err = os.Chown("/etc/datadog-agent", ddAgentUID, ddAgentGID); err != nil { return fmt.Errorf("failed to chown /etc/datadog-agent: %v", err) } - if err = chownRecursive("/opt/datadog-packages/datadog-agent/stable/", ddAgentUID, ddAgentGID); err != nil { + if err = chownRecursive("/opt/datadog-packages/datadog-agent/stable/", ddAgentUID, ddAgentGID, rootOwnedAgentPaths); err != nil { return fmt.Errorf("failed to chown /opt/datadog-packages/datadog-agent/stable/: %v", err) } @@ -192,11 +209,20 @@ func stopOldAgentUnits(ctx context.Context) error { return nil } -func chownRecursive(path string, uid int, gid int) error { +func chownRecursive(path string, uid int, gid int, ignorePaths []string) error { return filepath.Walk(path, func(p string, _ os.FileInfo, err error) error { if err != nil { return err } + relPath, err := filepath.Rel(path, p) + if err != nil { + return err + } + for _, ignore := range ignorePaths { + if relPath == ignore || strings.HasPrefix(relPath, ignore+string(os.PathSeparator)) { + return nil + } + } return os.Chown(p, uid, gid) }) } @@ -207,7 +233,7 @@ func StartAgentExperiment(ctx context.Context) error { if err != nil { return fmt.Errorf("error getting dd-agent user and group IDs: %w", err) } - if err = chownRecursive("/opt/datadog-packages/datadog-agent/experiment/", ddAgentUID, ddAgentGID); err != nil { + if err = chownRecursive("/opt/datadog-packages/datadog-agent/experiment/", ddAgentUID, ddAgentGID, rootOwnedAgentPaths); err != nil { return fmt.Errorf("failed to chown /opt/datadog-packages/datadog-agent/experiment/: %v", err) } return startUnit(ctx, agentExp, "--no-block") @@ -222,3 +248,49 @@ func StopAgentExperiment(ctx context.Context) error { func PromoteAgentExperiment(ctx context.Context) error { return StopAgentExperiment(ctx) } + +// ConfigureAgent configures the stable agent +func ConfigureAgent(ctx context.Context, cdn *cdn.CDN, configs *repository.Repositories) error { + config, err := cdn.Get(ctx) + if err != nil { + return fmt.Errorf("could not get cdn config: %w", err) + } + tmpDir, err := configs.MkdirTemp() + if err != nil { + return fmt.Errorf("could not create temporary directory: %w", err) + } + defer os.RemoveAll(tmpDir) + ddAgentUID, ddAgentGID, err := getAgentIDs() + if err != nil { + return fmt.Errorf("error getting dd-agent user and group IDs: %w", err) + } + + if config.Datadog != nil { + err = os.WriteFile(filepath.Join(tmpDir, configDatadogYAML), []byte(config.Datadog), 0640) + if err != nil { + return fmt.Errorf("could not write datadog.yaml: %w", err) + } + err = os.Chown(filepath.Join(tmpDir, configDatadogYAML), ddAgentUID, ddAgentGID) + if err != nil { + return fmt.Errorf("could not chown datadog.yaml: %w", err) + } + } + if config.SecurityAgent != nil { + err = os.WriteFile(filepath.Join(tmpDir, configSecurityAgentYAML), []byte(config.SecurityAgent), 0600) + if err != nil { + return fmt.Errorf("could not write datadog.yaml: %w", err) + } + } + if config.SystemProbe != nil { + err = os.WriteFile(filepath.Join(tmpDir, configSystemProbeYAML), []byte(config.SystemProbe), 0600) + if err != nil { + return fmt.Errorf("could not write datadog.yaml: %w", err) + } + } + + err = configs.Create(agentPackage, config.Version, tmpDir) + if err != nil { + return fmt.Errorf("could not create repository: %w", err) + } + return nil +} diff --git a/pkg/fleet/installer/service/datadog_agent_windows.go b/pkg/fleet/installer/service/datadog_agent_windows.go index 6ad1595c6d293..96d7feb77d9b5 100644 --- a/pkg/fleet/installer/service/datadog_agent_windows.go +++ b/pkg/fleet/installer/service/datadog_agent_windows.go @@ -11,12 +11,14 @@ package service import ( "context" "fmt" + "os/exec" + "path/filepath" + + "github.com/DataDog/datadog-agent/pkg/fleet/installer/repository" + "github.com/DataDog/datadog-agent/pkg/fleet/internal/cdn" "github.com/DataDog/datadog-agent/pkg/fleet/internal/paths" "github.com/DataDog/datadog-agent/pkg/util/log" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" - "os" - "os/exec" - "path/filepath" ) func msiexec(target, operation string, args []string) (err error) { @@ -31,13 +33,7 @@ func msiexec(target, operation string, args []string) (err error) { return fmt.Errorf("no MSIs in package") } - tmpDir, err := os.MkdirTemp(paths.TmpDirPath, fmt.Sprintf("install-%s-*", filepath.Base(msis[0]))) - if err != nil { - return fmt.Errorf("could not create temporary directory: %w", err) - } - - logPath := filepath.Join(tmpDir, "install.log") - cmd := exec.Command("msiexec", append([]string{operation, msis[0], "/qn", "/l", logPath, "MSIFASTINSTALL=7"}, args...)...) + cmd := exec.Command("msiexec", append([]string{operation, msis[0], "/qn", "MSIFASTINSTALL=7"}, args...)...) return cmd.Run() } @@ -100,3 +96,8 @@ func RemoveAgent(ctx context.Context) (err error) { }() return msiexec("stable", "/x", nil) } + +// ConfigureAgent noop +func ConfigureAgent(_ context.Context, _ *cdn.CDN, _ *repository.Repositories) error { + return nil +} diff --git a/pkg/fleet/installer/service/datadog_installer.go b/pkg/fleet/installer/service/datadog_installer.go index f04e5a735aa70..465e68b10ada1 100644 --- a/pkg/fleet/installer/service/datadog_installer.go +++ b/pkg/fleet/installer/service/datadog_installer.go @@ -14,11 +14,9 @@ import ( "os" "os/exec" "os/user" - "path/filepath" "strconv" "github.com/DataDog/datadog-agent/pkg/util/log" - "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" ) const ( @@ -73,18 +71,18 @@ func SetupInstaller(ctx context.Context) (err error) { if err != nil { return fmt.Errorf("error creating /var/log/datadog: %w", err) } - err = os.MkdirAll("/var/run/datadog-installer", 0755) + err = os.MkdirAll("/opt/datadog-packages/run", 0755) if err != nil { - return fmt.Errorf("error creating /var/run/datadog-installer: %w", err) + return fmt.Errorf("error creating /opt/datadog-packages/run: %w", err) } - err = os.MkdirAll("/var/run/datadog-installer/locks", 0777) + err = os.MkdirAll("/opt/datadog-packages/run/locks", 0777) if err != nil { - return fmt.Errorf("error creating /var/run/datadog-installer/locks: %w", err) + return fmt.Errorf("error creating /opt/datadog-packages/run/locks: %w", err) } // Locks directory can already be created by a package install - err = os.Chmod("/var/run/datadog-installer/locks", 0777) + err = os.Chmod("/opt/datadog-packages/run/locks", 0777) if err != nil { - return fmt.Errorf("error changing permissions of /var/run/datadog-installer/locks: %w", err) + return fmt.Errorf("error changing permissions of /opt/datadog-packages/run/locks: %w", err) } err = os.Chown("/etc/datadog-agent", ddAgentUID, ddAgentGID) if err != nil { @@ -94,15 +92,14 @@ func SetupInstaller(ctx context.Context) (err error) { if err != nil { return fmt.Errorf("error changing owner of /var/log/datadog: %w", err) } - err = os.Chown("/var/run/datadog-installer", ddAgentUID, ddAgentGID) + err = os.Chown("/opt/datadog-packages/run", ddAgentUID, ddAgentGID) if err != nil { - return fmt.Errorf("error changing owner of /var/run/datadog-installer: %w", err) + return fmt.Errorf("error changing owner of /opt/datadog-packages/run: %w", err) } - if err = os.MkdirAll("/var/run/datadog", 0755); err != nil { - return fmt.Errorf("failed to create /var/run/datadog: %v", err) - } - if err = os.Chown("/var/run/datadog", ddAgentUID, ddAgentGID); err != nil { - return fmt.Errorf("failed to chown /var/run/datadog: %v", err) + // Symlink /opt/datadog-packages/run to /var/run/datadog-installer for backwards compatibility + // This is a best effort, so we won't fail on it. + if err := os.Symlink("/opt/datadog-packages/run", "/var/run/datadog-installer"); err != nil && !os.IsExist(err) { + log.Warnf("failed to symlink /opt/datadog-packages/run to /var/run/datadog-installer: %s", err.Error()) } // Enforce that the directory exists. It should be created by the bootstrapper but // older versions don't do it @@ -114,7 +111,6 @@ func SetupInstaller(ctx context.Context) (err error) { if err != nil { return fmt.Errorf("error changing owner of /opt/datadog-installer/tmp: %w", err) } - // Create installer path symlink err = os.Symlink("/opt/datadog-packages/datadog-installer/stable/bin/installer/installer", "/usr/bin/datadog-installer") if err != nil && errors.Is(err, os.ErrExist) { @@ -138,10 +134,6 @@ func SetupInstaller(ctx context.Context) (err error) { return fmt.Errorf("error creating %s: %w", systemdPath, err) } - if err = addSystemDRuntimeConfigOverride(ctx); err != nil { - return err - } - // FIXME(Arthur): enable the daemon unit by default and use the same strategy as the system probe if os.Getenv("DD_REMOTE_UPDATES") != "true" { if err = systemdReload(ctx); err != nil { @@ -240,28 +232,3 @@ func StartInstallerExperiment(ctx context.Context) error { func StopInstallerExperiment(ctx context.Context) error { return startUnit(ctx, installerUnit) } - -// addSystemDRuntimeConfigOverride removes RuntimeConfig from the agent unit -// to avoid folder deletion on agent stop -func addSystemDRuntimeConfigOverride(ctx context.Context) (err error) { - span, _ := tracer.StartSpanFromContext(ctx, "add_systemd_runtime_config_override") - defer func() { span.Finish(tracer.WithError(err)) }() - - content := []byte("[Service]\nRuntimeConfig=\n") - - // We don't need a file mutator here as we're fully hard coding the content. - // We don't really need to remove the file either as it'll just be ignored once the - // unit is removed. - path := filepath.Join(systemdPath, "datadog-agent.service.d", "datadog_runtime_config.conf") - err = os.Mkdir(filepath.Dir(path), 0755) - if err != nil && !os.IsExist(err) { - err = fmt.Errorf("error creating systemd environment override directory: %w", err) - return err - } - err = os.WriteFile(path, content, 0644) - if err != nil { - err = fmt.Errorf("error writing systemd runtime config override: %w", err) - return err - } - return nil -} diff --git a/pkg/fleet/installer/service/embedded/datadog-agent-exp.service b/pkg/fleet/installer/service/embedded/datadog-agent-exp.service index ed500b148089b..40adc828787db 100644 --- a/pkg/fleet/installer/service/embedded/datadog-agent-exp.service +++ b/pkg/fleet/installer/service/embedded/datadog-agent-exp.service @@ -12,9 +12,11 @@ Type=oneshot PIDFile=/opt/datadog-packages/datadog-agent/experiment/run/agent.pid User=dd-agent EnvironmentFile=-/etc/datadog-agent/environment +Environment="DD_FLEET_POLICIES_DIR=/etc/datadog-packages/datadog-agent/experiment" ExecStart=/opt/datadog-packages/datadog-agent/experiment/bin/agent/agent run -p /opt/datadog-packages/datadog-agent/experiment/run/agent.pid ExecStart=/bin/false ExecStop=/bin/false +RuntimeDirectory=datadog [Install] WantedBy=multi-user.target diff --git a/pkg/fleet/installer/service/embedded/datadog-agent-process-exp.service b/pkg/fleet/installer/service/embedded/datadog-agent-process-exp.service index 426d019f4c62a..9583865d902df 100644 --- a/pkg/fleet/installer/service/embedded/datadog-agent-process-exp.service +++ b/pkg/fleet/installer/service/embedded/datadog-agent-process-exp.service @@ -9,6 +9,7 @@ PIDFile=/opt/datadog-packages/datadog-agent/experiment/run/process-agent.pid User=dd-agent Restart=on-failure EnvironmentFile=-/etc/datadog-agent/environment +Environment="DD_FLEET_POLICIES_DIR=/etc/datadog-packages/datadog-agent/experiment" ExecStart=/opt/datadog-packages/datadog-agent/experiment/embedded/bin/process-agent --cfgpath=/etc/datadog-agent/datadog.yaml --sysprobe-config=/etc/datadog-agent/system-probe.yaml --pid=/opt/datadog-packages/datadog-agent/experiment/run/process-agent.pid # Since systemd 229, should be in [Unit] but in order to support systemd <229, # it is also supported to have it here. diff --git a/pkg/fleet/installer/service/embedded/datadog-agent-process.service b/pkg/fleet/installer/service/embedded/datadog-agent-process.service index e990c47e28748..23e892f1ef5da 100644 --- a/pkg/fleet/installer/service/embedded/datadog-agent-process.service +++ b/pkg/fleet/installer/service/embedded/datadog-agent-process.service @@ -9,6 +9,7 @@ PIDFile=/opt/datadog-packages/datadog-agent/stable/run/process-agent.pid User=dd-agent Restart=on-failure EnvironmentFile=-/etc/datadog-agent/environment +Environment="DD_FLEET_POLICIES_DIR=/etc/datadog-packages/datadog-agent/stable" ExecStart=/opt/datadog-packages/datadog-agent/stable/embedded/bin/process-agent --cfgpath=/etc/datadog-agent/datadog.yaml --sysprobe-config=/etc/datadog-agent/system-probe.yaml --pid=/opt/datadog-packages/datadog-agent/stable/run/process-agent.pid # Since systemd 229, should be in [Unit] but in order to support systemd <229, # it is also supported to have it here. diff --git a/pkg/fleet/installer/service/embedded/datadog-agent-security-exp.service b/pkg/fleet/installer/service/embedded/datadog-agent-security-exp.service index dd2db087469cd..c86acfd7ee24b 100644 --- a/pkg/fleet/installer/service/embedded/datadog-agent-security-exp.service +++ b/pkg/fleet/installer/service/embedded/datadog-agent-security-exp.service @@ -9,6 +9,7 @@ Type=simple PIDFile=/opt/datadog-packages/datadog-agent/experiment/run/security-agent.pid Restart=on-failure EnvironmentFile=-/etc/datadog-agent/environment +Environment="DD_FLEET_POLICIES_DIR=/etc/datadog-packages/datadog-agent/experiment" ExecStart=/opt/datadog-packages/datadog-agent/experiment/embedded/bin/security-agent -c /etc/datadog-agent/datadog.yaml --pidfile /opt/datadog-packages/datadog-agent/experiment/run/security-agent.pid # Since systemd 229, should be in [Unit] but in order to support systemd <229, # it is also supported to have it here. diff --git a/pkg/fleet/installer/service/embedded/datadog-agent-security.service b/pkg/fleet/installer/service/embedded/datadog-agent-security.service index 935070f68ce33..a71b46142be9b 100644 --- a/pkg/fleet/installer/service/embedded/datadog-agent-security.service +++ b/pkg/fleet/installer/service/embedded/datadog-agent-security.service @@ -9,6 +9,7 @@ Type=simple PIDFile=/opt/datadog-packages/datadog-agent/stable/run/security-agent.pid Restart=on-failure EnvironmentFile=-/etc/datadog-agent/environment +Environment="DD_FLEET_POLICIES_DIR=/etc/datadog-packages/datadog-agent/stable" ExecStart=/opt/datadog-packages/datadog-agent/stable/embedded/bin/security-agent -c /etc/datadog-agent/datadog.yaml --pidfile /opt/datadog-packages/datadog-agent/stable/run/security-agent.pid # Since systemd 229, should be in [Unit] but in order to support systemd <229, # it is also supported to have it here. diff --git a/pkg/fleet/installer/service/embedded/datadog-agent-sysprobe-exp.service b/pkg/fleet/installer/service/embedded/datadog-agent-sysprobe-exp.service index 6b0d435fac472..e07fee41bad04 100644 --- a/pkg/fleet/installer/service/embedded/datadog-agent-sysprobe-exp.service +++ b/pkg/fleet/installer/service/embedded/datadog-agent-sysprobe-exp.service @@ -9,6 +9,7 @@ ConditionPathExists=/etc/datadog-agent/system-probe.yaml Type=simple PIDFile=/opt/datadog-packages/datadog-agent/experiment/run/system-probe.pid Restart=on-failure +Environment="DD_FLEET_POLICIES_DIR=/etc/datadog-packages/datadog-agent/experiment" ExecStart=/opt/datadog-packages/datadog-agent/experiment/embedded/bin/system-probe run --config=/etc/datadog-agent/system-probe.yaml --pid=/opt/datadog-packages/datadog-agent/experiment/run/system-probe.pid # Since systemd 229, should be in [Unit] but in order to support systemd <229, # it is also supported to have it here. diff --git a/pkg/fleet/installer/service/embedded/datadog-agent-sysprobe.service b/pkg/fleet/installer/service/embedded/datadog-agent-sysprobe.service index 5bcfeb717e984..f79685a577aa4 100644 --- a/pkg/fleet/installer/service/embedded/datadog-agent-sysprobe.service +++ b/pkg/fleet/installer/service/embedded/datadog-agent-sysprobe.service @@ -10,6 +10,7 @@ ConditionPathExists=/etc/datadog-agent/system-probe.yaml Type=simple PIDFile=/opt/datadog-packages/datadog-agent/stable/run/system-probe.pid Restart=on-failure +Environment="DD_FLEET_POLICIES_DIR=/etc/datadog-packages/datadog-agent/stable" ExecStart=/opt/datadog-packages/datadog-agent/stable/embedded/bin/system-probe run --config=/etc/datadog-agent/system-probe.yaml --pid=/opt/datadog-packages/datadog-agent/stable/run/system-probe.pid # Since systemd 229, should be in [Unit] but in order to support systemd <229, # it is also supported to have it here. diff --git a/pkg/fleet/installer/service/embedded/datadog-agent-trace-exp.service b/pkg/fleet/installer/service/embedded/datadog-agent-trace-exp.service index bcb3306b608c6..17bc119e85290 100644 --- a/pkg/fleet/installer/service/embedded/datadog-agent-trace-exp.service +++ b/pkg/fleet/installer/service/embedded/datadog-agent-trace-exp.service @@ -8,6 +8,7 @@ PIDFile=/opt/datadog-packages/datadog-agent/experiment/run/trace-agent.pid User=dd-agent Restart=on-failure EnvironmentFile=-/etc/datadog-agent/environment +Environment="DD_FLEET_POLICIES_DIR=/etc/datadog-packages/datadog-agent/experiment" ExecStart=/opt/datadog-packages/datadog-agent/experiment/embedded/bin/trace-agent --config /etc/datadog-agent/datadog.yaml --pidfile /opt/datadog-packages/datadog-agent/experiment/run/trace-agent.pid # Since systemd 229, should be in [Unit] but in order to support systemd <229, # it is also supported to have it here. diff --git a/pkg/fleet/installer/service/embedded/datadog-agent-trace.service b/pkg/fleet/installer/service/embedded/datadog-agent-trace.service index 483b47a1ead24..c3568e7004738 100644 --- a/pkg/fleet/installer/service/embedded/datadog-agent-trace.service +++ b/pkg/fleet/installer/service/embedded/datadog-agent-trace.service @@ -9,6 +9,7 @@ PIDFile=/opt/datadog-packages/datadog-agent/stable/run/trace-agent.pid User=dd-agent Restart=on-failure EnvironmentFile=-/etc/datadog-agent/environment +Environment="DD_FLEET_POLICIES_DIR=/etc/datadog-packages/datadog-agent/stable" ExecStart=/opt/datadog-packages/datadog-agent/stable/embedded/bin/trace-agent --config /etc/datadog-agent/datadog.yaml --pidfile /opt/datadog-packages/datadog-agent/stable/run/trace-agent.pid # Since systemd 229, should be in [Unit] but in order to support systemd <229, # it is also supported to have it here. diff --git a/pkg/fleet/installer/service/embedded/datadog-agent.service b/pkg/fleet/installer/service/embedded/datadog-agent.service index cb8d9455d4648..0f527777fc2e1 100644 --- a/pkg/fleet/installer/service/embedded/datadog-agent.service +++ b/pkg/fleet/installer/service/embedded/datadog-agent.service @@ -11,11 +11,13 @@ PIDFile=/opt/datadog-packages/datadog-agent/stable/run/agent.pid User=dd-agent Restart=on-failure EnvironmentFile=-/etc/datadog-agent/environment +Environment="DD_FLEET_POLICIES_DIR=/etc/datadog-packages/datadog-agent/stable" ExecStart=/opt/datadog-packages/datadog-agent/stable/bin/agent/agent run -p /opt/datadog-packages/datadog-agent/stable/run/agent.pid # Since systemd 229, should be in [Unit] but in order to support systemd <229, # it is also supported to have it here. StartLimitInterval=10 StartLimitBurst=5 +RuntimeDirectory=datadog [Install] WantedBy=multi-user.target diff --git a/pkg/fleet/installer/service/embedded/datadog-installer-exp.service b/pkg/fleet/installer/service/embedded/datadog-installer-exp.service index 53fadca02fdbf..6c37f99622e04 100644 --- a/pkg/fleet/installer/service/embedded/datadog-installer-exp.service +++ b/pkg/fleet/installer/service/embedded/datadog-installer-exp.service @@ -7,8 +7,8 @@ JobTimeoutSec=3000 [Service] Type=oneshot -PIDFile=/var/run/datadog-installer/installer-exp.pid -ExecStart=/opt/datadog-packages/datadog-installer/experiment/bin/installer/installer run -p /var/run/datadog-installer/installer-exp.pid +PIDFile=/opt/datadog-packages/run/installer-exp.pid +ExecStart=/opt/datadog-packages/datadog-installer/experiment/bin/installer/installer run -p /opt/datadog-packages/run/installer-exp.pid ExecStart=/bin/false ExecStop=/bin/false diff --git a/pkg/fleet/installer/service/embedded/datadog-installer.service b/pkg/fleet/installer/service/embedded/datadog-installer.service index dda46cb890eff..423ea6a97c1ff 100644 --- a/pkg/fleet/installer/service/embedded/datadog-installer.service +++ b/pkg/fleet/installer/service/embedded/datadog-installer.service @@ -5,9 +5,9 @@ Conflicts=datadog-installer-exp.service [Service] Type=simple -PIDFile=/var/run/datadog-installer/installer.pid +PIDFile=/opt/datadog-packages/run/installer.pid Restart=on-failure -ExecStart=/opt/datadog-packages/datadog-installer/stable/bin/installer/installer run -p /var/run/datadog-installer/installer.pid +ExecStart=/opt/datadog-packages/datadog-installer/stable/bin/installer/installer run -p /opt/datadog-packages/run/installer.pid # Since systemd 229, should be in [Unit] but in order to support systemd <229, # it is also supported to have it here. StartLimitInterval=10 diff --git a/pkg/fleet/internal/cdn/cdn.go b/pkg/fleet/internal/cdn/cdn.go new file mode 100644 index 0000000000000..53d93568777b4 --- /dev/null +++ b/pkg/fleet/internal/cdn/cdn.go @@ -0,0 +1,180 @@ +// 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 cdn provides access to the Remote Config CDN. +package cdn + +import ( + "context" + "encoding/json" + "fmt" + "regexp" + "time" + + "github.com/DataDog/datadog-agent/comp/metadata/host/hostimpl/hosttags" + "github.com/DataDog/datadog-agent/comp/remote-config/rctelemetryreporter/rctelemetryreporterimpl" + detectenv "github.com/DataDog/datadog-agent/pkg/config/env" + "github.com/DataDog/datadog-agent/pkg/config/model" + remoteconfig "github.com/DataDog/datadog-agent/pkg/config/remote/service" + pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" + "github.com/DataDog/datadog-agent/pkg/fleet/env" + pbgo "github.com/DataDog/datadog-agent/pkg/proto/pbgo/core" + pkghostname "github.com/DataDog/datadog-agent/pkg/util/hostname" + "github.com/DataDog/datadog-agent/pkg/version" + "github.com/google/uuid" + "go.uber.org/multierr" + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" +) + +var datadogConfigIDRegexp = regexp.MustCompile(`^datadog/\d+/AGENT_CONFIG/([^/]+)/[^/]+$`) + +const configOrderID = "configuration_order" + +// CDN provides access to the Remote Config CDN. +type CDN struct { + env *env.Env +} + +// Config represents the configuration from the CDN. +type Config struct { + Version string + Datadog []byte + SecurityAgent []byte + SystemProbe []byte +} + +type orderConfig struct { + Order []string `json:"order"` +} + +// New creates a new CDN. +func New(env *env.Env) *CDN { + return &CDN{ + env: env, + } +} + +// Get gets the configuration from the CDN. +func (c *CDN) Get(ctx context.Context) (_ *Config, err error) { + span, ctx := tracer.StartSpanFromContext(ctx, "cdn.Get") + defer func() { span.Finish(tracer.WithError(err)) }() + configLayers, err := c.getOrderedLayers(ctx) + if err != nil { + return nil, err + } + return newConfig(configLayers...) +} + +// getOrderedLayers calls the Remote Config service to get the ordered layers. +// Today it doesn't use the CDN, but it should in the future +func (c *CDN) getOrderedLayers(ctx context.Context) ([]*layer, error) { + // HACK(baptiste): Create a dedicated one-shot RC service just for the configuration + // We should use the CDN instead + config := pkgconfigsetup.Datadog() + config.Set("run_path", "/opt/datadog-packages/datadog-installer/stable/run", model.SourceAgentRuntime) + + detectenv.DetectFeatures(config) + hostname, err := pkghostname.Get(ctx) + if err != nil { + return nil, err + } + options := []remoteconfig.Option{ + remoteconfig.WithAPIKey(c.env.APIKey), + remoteconfig.WithConfigRootOverride(c.env.Site, ""), + remoteconfig.WithDirectorRootOverride(c.env.Site, ""), + } + service, err := remoteconfig.NewService( + config, + "Datadog Installer", + fmt.Sprintf("https://config.%s", c.env.Site), + hostname, + getHostTags(ctx, config), + &rctelemetryreporterimpl.DdRcTelemetryReporter{}, // No telemetry for this client + version.AgentVersion, + options..., + ) + if err != nil { + return nil, err + } + service.Start() + defer func() { _ = service.Stop() }() + // Force a cache bypass + cfgs, err := service.ClientGetConfigs(ctx, &pbgo.ClientGetConfigsRequest{ + Client: &pbgo.Client{ + Id: uuid.New().String(), + Products: []string{"AGENT_CONFIG"}, + IsUpdater: true, + ClientUpdater: &pbgo.ClientUpdater{}, + State: &pbgo.ClientState{ + RootVersion: 1, + TargetsVersion: 1, + }, + }, + }) + if err != nil { + return nil, err + } + + // Unmarshal RC results + configLayers := map[string]*layer{} + var configOrder *orderConfig + var layersErr error + for _, file := range cfgs.TargetFiles { + matched := datadogConfigIDRegexp.FindStringSubmatch(file.GetPath()) + if len(matched) != 2 { + layersErr = multierr.Append(layersErr, fmt.Errorf("invalid config path: %s", file.GetPath())) + continue + } + configName := matched[1] + + if configName != configOrderID { + configLayer := &layer{} + err = json.Unmarshal(file.GetRaw(), configLayer) + if err != nil { + // If a layer is wrong, fail later to parse the rest and check them all + layersErr = multierr.Append(layersErr, err) + continue + } + configLayers[configName] = configLayer + } else { + configOrder = &orderConfig{} + err = json.Unmarshal(file.GetRaw(), configOrder) + if err != nil { + // Return first - we can't continue without the order + return nil, err + } + } + } + if layersErr != nil { + return nil, layersErr + } + + // Order configs + if configOrder == nil { + return nil, fmt.Errorf("no configuration_order found") + } + orderedLayers := []*layer{} + for _, configName := range configOrder.Order { + if configLayer, ok := configLayers[configName]; ok { + orderedLayers = append(orderedLayers, configLayer) + } + } + + return orderedLayers, nil +} + +func getHostTags(ctx context.Context, config model.Config) func() []string { + return func() []string { + // Host tags are cached on host, but we add a timeout to avoid blocking the RC request + // if the host tags are not available yet and need to be fetched. They will be fetched + // by the first agent metadata V5 payload. + ctx, cc := context.WithTimeout(ctx, time.Second) + defer cc() + hostTags := hosttags.Get(ctx, true, config) + tags := append(hostTags.System, hostTags.GoogleCloudPlatform...) + tags = append(tags, "installer:true") + return tags + } +} diff --git a/pkg/fleet/internal/cdn/config.go b/pkg/fleet/internal/cdn/config.go new file mode 100644 index 0000000000000..979845c31aec8 --- /dev/null +++ b/pkg/fleet/internal/cdn/config.go @@ -0,0 +1,110 @@ +// 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 cdn + +import ( + "bytes" + "crypto/sha256" + "encoding/json" + "fmt" + + "gopkg.in/yaml.v2" +) + +const ( + layerKeys = "fleet_layers" + doNotEditDisclaimer = `# This configuration was generated by Datadog's Fleet Automation. DO NOT EDIT.` +) + +// layer is a config layer that can be merged with other layers into a config. +type layer struct { + ID string `json:"name"` + AgentConfig map[string]interface{} `json:"config"` + SecurityAgentConfig map[string]interface{} `json:"security_agent"` + SystemProbeConfig map[string]interface{} `json:"system_probe"` +} + +// newConfig creates a new config from a list of layers. +func newConfig(layers ...*layer) (_ *Config, err error) { + layerIDs := []string{} + mergedLayer := &layer{ + AgentConfig: map[string]interface{}{}, + SecurityAgentConfig: map[string]interface{}{}, + SystemProbeConfig: map[string]interface{}{}, + } + + // Merge all layers in order + for _, l := range layers { + layerIDs = append(layerIDs, l.ID) + if l.AgentConfig != nil { + agentConfig, err := merge(mergedLayer.AgentConfig, l.AgentConfig) + if err != nil { + return nil, err + } + mergedLayer.AgentConfig = agentConfig.(map[string]interface{}) + } + + if l.SecurityAgentConfig != nil { + securityAgentConfig, err := merge(mergedLayer.SecurityAgentConfig, l.SecurityAgentConfig) + if err != nil { + return nil, err + } + mergedLayer.SecurityAgentConfig = securityAgentConfig.(map[string]interface{}) + } + + if l.SystemProbeConfig != nil { + systemProbeAgentConfig, err := merge(mergedLayer.SystemProbeConfig, l.SystemProbeConfig) + if err != nil { + return nil, err + } + mergedLayer.SystemProbeConfig = systemProbeAgentConfig.(map[string]interface{}) + } + } + mergedLayer.AgentConfig[layerKeys] = layerIDs // Add a field with the applied layers that will be reported through inventories + + serializedAgentConfig, err := marshalConfig(mergedLayer.AgentConfig) + if err != nil { + return nil, err + } + serializedSecurityAgentConfig, err := marshalConfig(mergedLayer.SecurityAgentConfig) + if err != nil { + return nil, err + } + serializedSystemProbeConfig, err := marshalConfig(mergedLayer.SystemProbeConfig) + if err != nil { + return nil, err + } + + hash := sha256.New() + serializedConfig, err := json.Marshal(mergedLayer) + if err != nil { + return nil, err + } + hash.Write(serializedConfig) + + return &Config{ + Version: fmt.Sprintf("%x", hash.Sum(nil)), + Datadog: serializedAgentConfig, + SecurityAgent: serializedSecurityAgentConfig, + SystemProbe: serializedSystemProbeConfig, + }, nil +} + +// marshalConfig marshals the config as YAML. +func marshalConfig(c map[string]interface{}) ([]byte, error) { + if len(c) == 0 { + return nil, nil + } + var b bytes.Buffer + b.WriteString(doNotEditDisclaimer) + b.WriteString("\n") + rawConfig, err := yaml.Marshal(c) + if err != nil { + return nil, err + } + b.Write(rawConfig) + return b.Bytes(), nil +} diff --git a/pkg/fleet/internal/cdn/config_test.go b/pkg/fleet/internal/cdn/config_test.go new file mode 100644 index 0000000000000..78dd772a456b6 --- /dev/null +++ b/pkg/fleet/internal/cdn/config_test.go @@ -0,0 +1,47 @@ +// 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 cdn + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestConfig(t *testing.T) { + baseLayer := &layer{ + ID: "base", + AgentConfig: map[string]interface{}{ + "api_key": "1234", + "apm": map[string]interface{}{ + "enabled": true, + "sampling_rate": 0.5, + }, + }, + } + overrideLayer := &layer{ + ID: "override", + AgentConfig: map[string]interface{}{ + "apm": map[string]interface{}{ + "sampling_rate": 0.7, + "env": "prod", + }, + }, + } + config, err := newConfig(baseLayer, overrideLayer) + assert.NoError(t, err) + expectedConfig := doNotEditDisclaimer + ` +api_key: "1234" +apm: + enabled: true + env: prod + sampling_rate: 0.7 +fleet_layers: +- base +- override +` + assert.Equal(t, expectedConfig, string(config.Datadog)) +} diff --git a/pkg/fleet/internal/cdn/merge.go b/pkg/fleet/internal/cdn/merge.go new file mode 100644 index 0000000000000..05a4b1a08b01b --- /dev/null +++ b/pkg/fleet/internal/cdn/merge.go @@ -0,0 +1,65 @@ +// 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 cdn + +import ( + "fmt" +) + +func isList(i interface{}) bool { + _, ok := i.([]interface{}) + return ok +} + +func isMap(i interface{}) bool { + _, ok := i.(map[string]interface{}) + return ok +} + +func isScalar(i interface{}) bool { + return !isList(i) && !isMap(i) +} + +// merge merges two layers into a single layer +// +// The override layer takes precedence over the base layer. The values are merged as follows: +// - Scalars: the override value is used +// - Lists: the override list is used +// - Maps: the override map is recursively merged into the base map +func merge(base interface{}, override interface{}) (interface{}, error) { + if base == nil { + return override, nil + } + if override == nil { + // this allows to override a value with nil + return nil, nil + } + if isScalar(base) && isScalar(override) { + return override, nil + } + if isList(base) && isList(override) { + return override, nil + } + if isMap(base) && isMap(override) { + return mergeMap(base.(map[string]interface{}), override.(map[string]interface{})) + } + return nil, fmt.Errorf("could not merge %T with %T", base, override) +} + +func mergeMap(base, override map[string]interface{}) (map[string]interface{}, error) { + merged := make(map[string]interface{}) + for k, v := range base { + merged[k] = v + } + for k := range override { + v, err := merge(base[k], override[k]) + if err != nil { + return nil, fmt.Errorf("could not merge key %v: %w", k, err) + } + merged[k] = v + } + return merged, nil +} diff --git a/pkg/fleet/internal/cdn/merge_test.go b/pkg/fleet/internal/cdn/merge_test.go new file mode 100644 index 0000000000000..8af4b7f81d42b --- /dev/null +++ b/pkg/fleet/internal/cdn/merge_test.go @@ -0,0 +1,191 @@ +// 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 cdn + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMergeScalar(t *testing.T) { + tests := []struct { + name string + base interface{} + override interface{} + expected interface{} + expectedErr bool + }{ + { + name: "nil base and override", + base: nil, + override: nil, + expected: nil, + }, + { + name: "nil base", + base: nil, + override: "override", + expected: "override", + }, + { + name: "nil override", + base: "base", + override: nil, + expected: nil, + }, + { + name: "override", + base: "base", + override: "override", + expected: "override", + }, + { + name: "scalar and list error", + base: "base", + override: []interface{}{"override"}, + expectedErr: true, + }, + { + name: "scalar and map error", + base: "base", + override: map[string]interface{}{"key": "value"}, + expectedErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + merged, err := merge(tt.base, tt.override) + if tt.expectedErr { + assert.Error(t, err, "expected an error") + } else { + assert.Equal(t, tt.expected, merged) + } + }) + } +} + +func TestMergeList(t *testing.T) { + tests := []struct { + name string + base interface{} + override interface{} + expected interface{} + expectedErr bool + }{ + { + name: "nil override", + base: []interface{}{"base"}, + override: nil, + expected: nil, + }, + { + name: "override", + base: []interface{}{"base"}, + override: []interface{}{"override"}, + expected: []interface{}{"override"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + merged, err := merge(tt.base, tt.override) + if tt.expectedErr { + assert.Error(t, err, "expected an error") + } else { + assert.Equal(t, tt.expected, merged) + } + }) + } +} + +func TestMergeMap(t *testing.T) { + tests := []struct { + name string + base interface{} + override interface{} + expected interface{} + expectedErr bool + }{ + { + name: "nil override", + base: map[string]interface{}{ + "base": "value", + }, + override: nil, + expected: nil, + }, + { + name: "override", + base: map[string]interface{}{ + "base": "value", + }, + override: map[string]interface{}{ + "base": "override", + }, + expected: map[string]interface{}{ + "base": "override", + }, + }, + { + name: "add key", + base: map[string]interface{}{ + "base": "value", + }, + override: map[string]interface{}{ + "override": "value", + }, + expected: map[string]interface{}{ + "base": "value", + "override": "value", + }, + }, + { + name: "nested", + base: map[string]interface{}{ + "base": map[string]interface{}{ + "key": "value", + }, + }, + override: map[string]interface{}{ + "base": map[string]interface{}{ + "key": "override", + }, + }, + expected: map[string]interface{}{ + "base": map[string]interface{}{ + "key": "override", + }, + }, + }, + { + name: "nested scalar and list error", + base: map[string]interface{}{ + "base": map[string]interface{}{ + "key": []interface{}{"value"}, + }, + }, + override: map[string]interface{}{ + "base": map[string]interface{}{ + "key": "override", + }, + }, + expectedErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + merged, err := merge(tt.base, tt.override) + if tt.expectedErr { + assert.Error(t, err, "expected an error") + } else { + assert.Equal(t, tt.expected, merged) + } + }) + } +} diff --git a/pkg/fleet/internal/exec/installer_exec.go b/pkg/fleet/internal/exec/installer_exec.go index b0e1c08739473..a1beaf19764db 100644 --- a/pkg/fleet/internal/exec/installer_exec.go +++ b/pkg/fleet/internal/exec/installer_exec.go @@ -169,13 +169,13 @@ func (i *InstallerExec) DefaultPackages(ctx context.Context) (_ []string, err er // State returns the state of a package. func (i *InstallerExec) State(pkg string) (repository.State, error) { - repositories := repository.NewRepositories(paths.PackagesPath, paths.LocksPack) + repositories := repository.NewRepositories(paths.PackagesPath, paths.LocksPath) return repositories.Get(pkg).GetState() } // States returns the states of all packages. func (i *InstallerExec) States() (map[string]repository.State, error) { - repositories := repository.NewRepositories(paths.PackagesPath, paths.LocksPack) + repositories := repository.NewRepositories(paths.PackagesPath, paths.LocksPath) states, err := repositories.GetState() log.Debugf("repositories states: %v", states) return states, err diff --git a/pkg/fleet/internal/paths/installer_paths.go b/pkg/fleet/internal/paths/installer_paths.go index f20408c23705e..24e53dc13dceb 100644 --- a/pkg/fleet/internal/paths/installer_paths.go +++ b/pkg/fleet/internal/paths/installer_paths.go @@ -11,10 +11,11 @@ package paths const ( // PackagesPath is the path to the packages directory. PackagesPath = "/opt/datadog-packages" - // TmpDirPath is the path to the temporary directory used for package installation. - TmpDirPath = "/opt/datadog-packages" - // LocksPack is the path to the locks directory. - LocksPack = "/var/run/datadog-installer/locks" - // DefaultConfigsDir is the default Agent configuration directory - DefaultConfigsDir = "/etc" + // ConfigsPath is the path to the Fleet-managed configuration directory. + ConfigsPath = "/etc/datadog-packages" + // LocksPath is the path to the packages locks directory. + LocksPath = "/opt/datadog-packages/run/locks" + + // DefaultUserConfigsDir is the default Agent configuration directory. + DefaultUserConfigsDir = "/etc" ) diff --git a/pkg/fleet/internal/paths/installer_paths_windows.go b/pkg/fleet/internal/paths/installer_paths_windows.go index 47d16726e50f4..456cb7e6af7c2 100644 --- a/pkg/fleet/internal/paths/installer_paths_windows.go +++ b/pkg/fleet/internal/paths/installer_paths_windows.go @@ -9,29 +9,28 @@ package paths import ( + "path/filepath" + "github.com/DataDog/datadog-agent/pkg/fleet/internal/winregistry" "golang.org/x/sys/windows" - "path/filepath" ) var ( // PackagesPath is the path to the packages directory. PackagesPath string + // ConfigsPath is the path to the Fleet-managed configuration directory + ConfigsPath string + // LocksPath is the path to the locks directory. + LocksPath string - // TmpDirPath is the path to the temporary directory used for package installation. - TmpDirPath string - - // LocksPack is the path to the locks directory. - LocksPack string - - // DefaultConfigsDir is the default Agent configuration directory - DefaultConfigsDir string + // DefaultUserConfigsDir is the default Agent configuration directory + DefaultUserConfigsDir string ) func init() { datadogInstallerData, _ := winregistry.GetProgramDataDirForProduct("Datadog Installer") - TmpDirPath = filepath.Join(datadogInstallerData, "temp") PackagesPath = filepath.Join(datadogInstallerData, "packages") - LocksPack = filepath.Join(datadogInstallerData, "locks") - DefaultConfigsDir, _ = windows.KnownFolderPath(windows.FOLDERID_ProgramData, 0) + ConfigsPath = filepath.Join(datadogInstallerData, "configs") + LocksPath = filepath.Join(datadogInstallerData, "locks") + DefaultUserConfigsDir, _ = windows.KnownFolderPath(windows.FOLDERID_ProgramData, 0) } diff --git a/pkg/gohai/go.mod b/pkg/gohai/go.mod index 75633a855ce39..10685f7af8e2f 100644 --- a/pkg/gohai/go.mod +++ b/pkg/gohai/go.mod @@ -10,7 +10,7 @@ require ( github.com/moby/sys/mountinfo v0.7.2 github.com/shirou/gopsutil/v3 v3.24.5 github.com/stretchr/testify v1.9.0 - golang.org/x/sys v0.23.0 + golang.org/x/sys v0.24.0 ) require ( diff --git a/pkg/gohai/go.sum b/pkg/gohai/go.sum index 555fa36effac6..f8710927d8496 100644 --- a/pkg/gohai/go.sum +++ b/pkg/gohai/go.sum @@ -47,8 +47,8 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w 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.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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= 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= diff --git a/pkg/jmxfetch/jmxfetch.go b/pkg/jmxfetch/jmxfetch.go index 7c39684e06a8e..2f0fb0537beca 100644 --- a/pkg/jmxfetch/jmxfetch.go +++ b/pkg/jmxfetch/jmxfetch.go @@ -138,7 +138,7 @@ func (j *JMXFetch) Monitor() { if !limiter.canRestart(time.Now()) { msg := fmt.Sprintf("Too many JMXFetch restarts (%v) in time interval (%vs) - giving up", limiter.maxRestarts, limiter.interval) - log.Errorf(msg) + log.Errorf("%s", msg) s := jmxStatus.StartupError{LastError: msg, Timestamp: time.Now().Unix()} jmxStatus.SetStartupError(s) return diff --git a/pkg/languagedetection/privileged/privileged_detector.go b/pkg/languagedetection/privileged/privileged_detector.go index 2b26e3565d6c9..543a021194746 100644 --- a/pkg/languagedetection/privileged/privileged_detector.go +++ b/pkg/languagedetection/privileged/privileged_detector.go @@ -75,6 +75,7 @@ func (l *LanguageDetector) DetectWithPrivileges(procs []languagemodels.Process) if err != nil { handleDetectorError(err) log.Debug("failed to get binID:", err) + continue } if lang, ok := l.binaryIDCache.Get(bin); ok { diff --git a/pkg/languagedetection/privileged/privileged_detector_test.go b/pkg/languagedetection/privileged/privileged_detector_test.go index e1e4ba361b0e0..a356481008a89 100644 --- a/pkg/languagedetection/privileged/privileged_detector_test.go +++ b/pkg/languagedetection/privileged/privileged_detector_test.go @@ -9,6 +9,7 @@ package privileged import ( "os/exec" + "strconv" "testing" "time" @@ -34,8 +35,8 @@ func (p cmdWrapper) GetCmdline() []string { return p.Args } -func forkExecForTest(t *testing.T) *exec.Cmd { - cmd := exec.Command("sleep", "20") +func forkExecForTest(t *testing.T, timeout int) *exec.Cmd { + cmd := exec.Command("sleep", strconv.Itoa(timeout)) err := cmd.Start() time.Sleep(250 * time.Millisecond) @@ -52,7 +53,7 @@ func forkExecForTest(t *testing.T) *exec.Cmd { func TestPrivilegedDetectorCaching(t *testing.T) { t.Run("cache entry does not exist", func(t *testing.T) { - cmd1 := cmdWrapper{forkExecForTest(t)} + cmd1 := cmdWrapper{forkExecForTest(t, 20)} d := NewLanguageDetector() d.DetectWithPrivileges([]languagemodels.Process{cmd1}) @@ -68,7 +69,7 @@ func TestPrivilegedDetectorCaching(t *testing.T) { - `simplelru.LRUCache` has 10 methods which all have to be stubbed out, and add unnecessary bloat to the tests. - `simplelru.LRUCache` is an external dependency; if the interface ever changed then the test would have to be fixed. */ - cmd1 := cmdWrapper{forkExecForTest(t)} + cmd1 := cmdWrapper{forkExecForTest(t, 20)} d := NewLanguageDetector() binID, err := d.getBinID(cmd1) @@ -81,7 +82,7 @@ func TestPrivilegedDetectorCaching(t *testing.T) { } func TestGetBinID(t *testing.T) { - cmd1, cmd2 := forkExecForTest(t), forkExecForTest(t) + cmd1, cmd2 := forkExecForTest(t, 20), forkExecForTest(t, 20) d := NewLanguageDetector() // Assert cmd1 and cmd2 are not the same processes @@ -95,3 +96,15 @@ func TestGetBinID(t *testing.T) { assert.Equal(t, binID1, binID2) } + +func TestShortLivingProc(t *testing.T) { + cmd := forkExecForTest(t, 1) + _, err := cmd.Process.Wait() + require.NoError(t, err) + + d := NewLanguageDetector() + res := d.DetectWithPrivileges([]languagemodels.Process{cmdWrapper{cmd}}) + require.Len(t, res, 1) + require.Equal(t, languagemodels.Language{}, res[0]) + require.Zero(t, d.binaryIDCache.Len()) +} diff --git a/pkg/linters/components/pkgconfigusage/go.mod b/pkg/linters/components/pkgconfigusage/go.mod new file mode 100644 index 0000000000000..94737011484cb --- /dev/null +++ b/pkg/linters/components/pkgconfigusage/go.mod @@ -0,0 +1,17 @@ +module github.com/DataDog/datadog-agent/pkg/linters/components/pkgconfigusage + +go 1.22.0 + +require ( + github.com/golangci/plugin-module-register v0.1.1 + github.com/stretchr/testify v1.9.0 + golang.org/x/tools v0.24.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/sync v0.8.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/pkg/linters/components/pkgconfigusage/go.sum b/pkg/linters/components/pkgconfigusage/go.sum new file mode 100644 index 0000000000000..e4381e0e55b8d --- /dev/null +++ b/pkg/linters/components/pkgconfigusage/go.sum @@ -0,0 +1,20 @@ +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/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c= +github.com/golangci/plugin-module-register v0.1.1/go.mod h1:TTpqoB6KkwOJMV8u7+NyXMrkwwESJLOkfl9TxR1DGFc= +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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/linters/components/pkgconfigusage/pkgconfigusage.go b/pkg/linters/components/pkgconfigusage/pkgconfigusage.go new file mode 100644 index 0000000000000..9699c50dd87fb --- /dev/null +++ b/pkg/linters/components/pkgconfigusage/pkgconfigusage.go @@ -0,0 +1,72 @@ +// 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 pkgconfigusage provides a linter for ensuring pkg/config is not used inside comp folder +package pkgconfigusage + +import ( + "strings" + + "github.com/golangci/plugin-module-register/register" + "golang.org/x/tools/go/analysis" +) + +// We can replace it during tests +var componentPath = "github.com/DataDog/datadog-agent/comp/" + +func init() { + register.Plugin("pkgconfigusage", New) +} + +type pkgconfigUsagePlugin struct { +} + +// New returns a new config linter plugin +func New(any) (register.LinterPlugin, error) { + return &pkgconfigUsagePlugin{}, nil +} + +// BuildAnalyzers returns the analyzers for the plugin +func (f *pkgconfigUsagePlugin) BuildAnalyzers() ([]*analysis.Analyzer, error) { + return []*analysis.Analyzer{ + { + Name: "pkgconfigusage", + Doc: "ensure github.com/DataDog/datadog-agent/pkg/config is not used inside the components folder", + Run: f.run, + }, + }, nil +} + +// GetLoadMode returns the load mode for the plugin +func (f *pkgconfigUsagePlugin) GetLoadMode() string { + return register.LoadModeSyntax +} + +func (f *pkgconfigUsagePlugin) run(pass *analysis.Pass) (interface{}, error) { + for _, file := range pass.Files { + + if !strings.HasPrefix(pass.Pkg.Path(), componentPath) { + continue + } + + for _, imp := range file.Imports { + if imp.Path.Value == `"github.com/DataDog/datadog-agent/pkg/config"` { + pass.Report(analysis.Diagnostic{ + Pos: imp.Pos(), + End: imp.End(), + Category: "components", + Message: "github.com/DataDog/datadog-agent/pkg/config should not be used inside comp folder", + SuggestedFixes: []analysis.SuggestedFix{ + { + Message: "Use the config component instead, by declaring it as part of your component's dependencies.", + }, + }, + }) + } + } + } + + return nil, nil +} diff --git a/pkg/linters/components/pkgconfigusage/pkgconfigusage_test.go b/pkg/linters/components/pkgconfigusage/pkgconfigusage_test.go new file mode 100644 index 0000000000000..03d2c2afe160e --- /dev/null +++ b/pkg/linters/components/pkgconfigusage/pkgconfigusage_test.go @@ -0,0 +1,41 @@ +// 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 pkgconfigusage + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "golang.org/x/tools/go/analysis/analysistest" +) + +func TestAll(t *testing.T) { + wd, err := os.Getwd() + if err != nil { + t.Fatalf("Failed to get wd: %s", err) + } + + originalComponentPath := componentPath + componentPath = "comp" + + t.Cleanup(func() { + componentPath = originalComponentPath + }) + + testdata := filepath.Join(filepath.Dir(filepath.Dir(wd)), "testdata") + plugin := &pkgconfigUsagePlugin{} + analyzers, err := plugin.BuildAnalyzers() + assert.NoError(t, err) + + analyzer := analyzers[0] + // We do this to skip issues with import or other errors. + // We only care about parsing the test file and run the analyzer. + analyzer.RunDespiteErrors = true + + analysistest.Run(t, testdata, analyzer, "comp/...") +} diff --git a/pkg/linters/testdata/src/comp/a.go b/pkg/linters/testdata/src/comp/a.go new file mode 100644 index 0000000000000..6a7cdf211fb57 --- /dev/null +++ b/pkg/linters/testdata/src/comp/a.go @@ -0,0 +1,9 @@ +// 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 a is a test package to test the linter +package a + +import _ "github.com/DataDog/datadog-agent/pkg/config" // want "pkg/config should not be used inside comp folder" diff --git a/pkg/logs/auditor/go.mod b/pkg/logs/auditor/go.mod index a1cb4d79652f7..52a3aba073a47 100644 --- a/pkg/logs/auditor/go.mod +++ b/pkg/logs/auditor/go.mod @@ -13,6 +13,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../comp/logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../config/utils @@ -91,12 +92,12 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/logs/auditor/go.sum b/pkg/logs/auditor/go.sum index 79c2fcb395d02..77ba213060c82 100644 --- a/pkg/logs/auditor/go.sum +++ b/pkg/logs/auditor/go.sum @@ -234,25 +234,25 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -295,11 +295,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -312,8 +312,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/logs/client/go.mod b/pkg/logs/client/go.mod index 8f61051bb47d5..a57d90a5a1b37 100644 --- a/pkg/logs/client/go.mod +++ b/pkg/logs/client/go.mod @@ -15,6 +15,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../comp/logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../config/utils @@ -57,7 +58,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/log v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/version v0.56.0-rc.3 github.com/stretchr/testify v1.9.0 - golang.org/x/net v0.27.0 + golang.org/x/net v0.28.0 ) require ( @@ -124,16 +125,16 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/pkg/logs/client/go.sum b/pkg/logs/client/go.sum index e5ded612312fa..08e2bfaac8ea7 100644 --- a/pkg/logs/client/go.sum +++ b/pkg/logs/client/go.sum @@ -50,8 +50,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -357,21 +355,21 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -390,8 +388,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -454,8 +452,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -523,8 +521,8 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -534,8 +532,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -591,8 +589,8 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/pkg/logs/diagnostic/go.mod b/pkg/logs/diagnostic/go.mod index f79142e18b2e7..6c6616dd4d46d 100644 --- a/pkg/logs/diagnostic/go.mod +++ b/pkg/logs/diagnostic/go.mod @@ -14,6 +14,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../comp/logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../config/utils @@ -97,16 +98,16 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/logs/diagnostic/go.sum b/pkg/logs/diagnostic/go.sum index 7d9bb18a9b376..c0f06ba5f32fa 100644 --- a/pkg/logs/diagnostic/go.sum +++ b/pkg/logs/diagnostic/go.sum @@ -12,8 +12,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -238,27 +236,27 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -301,11 +299,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -318,8 +316,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/aggregator.go b/pkg/logs/internal/decoder/auto_multiline_detection/aggregator.go index 92d607a6cecf3..789573fbdd692 100644 --- a/pkg/logs/internal/decoder/auto_multiline_detection/aggregator.go +++ b/pkg/logs/internal/decoder/auto_multiline_detection/aggregator.go @@ -14,24 +14,35 @@ import ( ) type bucket struct { - message *message.Message - buffer *bytes.Buffer - lineCount int + tagTruncatedLogs bool + tagMultiLineLogs bool + + message *message.Message + originalDataLen int + buffer *bytes.Buffer + lineCount int + truncated bool } func (b *bucket) add(msg *message.Message) { if b.message == nil { b.message = msg } - if b.buffer.Len() > 0 { + if b.originalDataLen > 0 { b.buffer.Write(message.EscapedLineFeed) } b.buffer.Write(msg.GetContent()) + b.originalDataLen += msg.RawDataLen b.lineCount++ } func (b *bucket) isEmpty() bool { - return b.buffer.Len() == 0 + return b.originalDataLen == 0 +} + +func (b *bucket) truncate() { + b.buffer.Write(message.TruncatedFlag) + b.truncated = true } func (b *bucket) flush() *message.Message { @@ -39,17 +50,30 @@ func (b *bucket) flush() *message.Message { b.buffer.Reset() b.message = nil b.lineCount = 0 + b.originalDataLen = 0 + b.truncated = false }() - originalLen := b.buffer.Len() data := bytes.TrimSpace(b.buffer.Bytes()) content := make([]byte, len(data)) copy(content, data) + msg := message.NewRawMessage(content, b.message.Status, b.originalDataLen, b.message.ParsingExtra.Timestamp) + if b.lineCount > 1 { - return message.NewRawMultiLineMessage(content, b.message.Status, originalLen, b.message.ParsingExtra.Timestamp) + msg.ParsingExtra.IsMultiLine = true + if b.tagMultiLineLogs { + msg.ParsingExtra.Tags = append(msg.ParsingExtra.Tags, message.AutoMultiLineTag) + } } - return message.NewRawMessage(content, b.message.Status, originalLen, b.message.ParsingExtra.Timestamp) + + if b.truncated { + msg.ParsingExtra.IsTruncated = true + if b.tagTruncatedLogs { + msg.ParsingExtra.Tags = append(msg.ParsingExtra.Tags, message.TruncatedTag) + } + } + return msg } // Aggregator aggregates multiline logs with a given label. @@ -62,10 +86,10 @@ type Aggregator struct { } // NewAggregator creates a new aggregator. -func NewAggregator(outputFn func(m *message.Message), maxContentSize int, flushTimeout time.Duration) *Aggregator { +func NewAggregator(outputFn func(m *message.Message), maxContentSize int, flushTimeout time.Duration, tagTruncatedLogs bool, tagMultiLineLogs bool) *Aggregator { return &Aggregator{ outputFn: outputFn, - bucket: &bucket{buffer: bytes.NewBuffer(nil)}, + bucket: &bucket{buffer: bytes.NewBuffer(nil), tagTruncatedLogs: tagTruncatedLogs, tagMultiLineLogs: tagMultiLineLogs}, maxContentSize: maxContentSize, flushTimeout: flushTimeout, } @@ -97,9 +121,10 @@ func (a *Aggregator) Aggregate(msg *message.Message, label Label) { // At this point we either have `startGroup` with an empty bucket or `aggregate` with a non-empty bucket // so we add the message to the bucket or flush if the bucket will overflow the max content size. - if msg.RawDataLen+a.bucket.buffer.Len() > a.maxContentSize { - a.bucket.flush() + a.bucket.truncate() // Truncate the end of the current bucket + a.Flush() + a.bucket.truncate() // Truncate the start of the next bucket } a.bucket.add(msg) diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/aggregator_test.go b/pkg/logs/internal/decoder/auto_multiline_detection/aggregator_test.go index 2d25b7cf8c1ca..603ac5ec02cd1 100644 --- a/pkg/logs/internal/decoder/auto_multiline_detection/aggregator_test.go +++ b/pkg/logs/internal/decoder/auto_multiline_detection/aggregator_test.go @@ -34,9 +34,8 @@ func assertMessageContent(t *testing.T, m *message.Message, content string) { } func TestNoAggregate(t *testing.T) { - outputChan, outputFn := makeHandler() - ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second)) + ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second), false, false) ag.Aggregate(newMessage("1"), noAggregate) ag.Aggregate(newMessage("2"), noAggregate) @@ -50,7 +49,7 @@ func TestNoAggregate(t *testing.T) { func TestNoAggregateEndsGroup(t *testing.T) { outputChan, outputFn := makeHandler() - ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second)) + ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second), false, false) ag.Aggregate(newMessage("1"), startGroup) ag.Aggregate(newMessage("2"), startGroup) @@ -62,9 +61,8 @@ func TestNoAggregateEndsGroup(t *testing.T) { } func TestAggregateGroups(t *testing.T) { - outputChan, outputFn := makeHandler() - ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second)) + ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second), false, false) // Aggregated log ag.Aggregate(newMessage("1"), startGroup) @@ -83,9 +81,8 @@ func TestAggregateGroups(t *testing.T) { } func TestAggregateDoesntStartGroup(t *testing.T) { - outputChan, outputFn := makeHandler() - ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second)) + ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second), false, false) ag.Aggregate(newMessage("1"), aggregate) ag.Aggregate(newMessage("2"), aggregate) @@ -97,9 +94,8 @@ func TestAggregateDoesntStartGroup(t *testing.T) { } func TestForceFlush(t *testing.T) { - outputChan, outputFn := makeHandler() - ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second)) + ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second), false, false) ag.Aggregate(newMessage("1"), startGroup) ag.Aggregate(newMessage("2"), aggregate) @@ -110,9 +106,8 @@ func TestForceFlush(t *testing.T) { } func TestAggregationTimer(t *testing.T) { - outputChan, outputFn := makeHandler() - ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second)) + ag := NewAggregator(outputFn, 100, time.Duration(1*time.Second), false, false) assert.Nil(t, ag.FlushChan()) ag.Aggregate(newMessage("1"), startGroup) @@ -126,3 +121,55 @@ func TestAggregationTimer(t *testing.T) { assertMessageContent(t, <-outputChan, "1") assertMessageContent(t, <-outputChan, "2") } + +func TestTagTruncatedLogs(t *testing.T) { + outputChan, outputFn := makeHandler() + ag := NewAggregator(outputFn, 10, time.Duration(1*time.Second), true, false) + + ag.Aggregate(newMessage("1234567890"), startGroup) + ag.Aggregate(newMessage("1"), aggregate) // Causes overflow, truncate and flush + ag.Aggregate(newMessage("2"), noAggregate) + + msg := <-outputChan + assert.True(t, msg.ParsingExtra.IsTruncated) + assert.Equal(t, msg.ParsingExtra.Tags, []string{message.TruncatedTag}) + assertMessageContent(t, msg, "1234567890...TRUNCATED...") + + msg = <-outputChan + assert.True(t, msg.ParsingExtra.IsTruncated) + assert.Equal(t, msg.ParsingExtra.Tags, []string{message.TruncatedTag}) + assertMessageContent(t, msg, "...TRUNCATED...1") + + msg = <-outputChan + assert.False(t, msg.ParsingExtra.IsTruncated) + assert.Empty(t, msg.ParsingExtra.Tags) + assertMessageContent(t, msg, "2") +} + +func TestTagMultiLineLogs(t *testing.T) { + outputChan, outputFn := makeHandler() + ag := NewAggregator(outputFn, 10, time.Duration(1*time.Second), false, true) + + ag.Aggregate(newMessage("12345"), startGroup) + ag.Aggregate(newMessage("67890"), aggregate) + ag.Aggregate(newMessage("1"), aggregate) // Causes overflow, truncate and flush + ag.Aggregate(newMessage("2"), noAggregate) + + msg := <-outputChan + assert.True(t, msg.ParsingExtra.IsMultiLine) + assert.True(t, msg.ParsingExtra.IsTruncated) + assert.Equal(t, msg.ParsingExtra.Tags, []string{message.AutoMultiLineTag}) + assertMessageContent(t, msg, "12345\\n67890...TRUNCATED...") + + msg = <-outputChan + assert.False(t, msg.ParsingExtra.IsMultiLine) + assert.True(t, msg.ParsingExtra.IsTruncated) + assert.Empty(t, msg.ParsingExtra.Tags) + assertMessageContent(t, msg, "...TRUNCATED...1") + + msg = <-outputChan + assert.False(t, msg.ParsingExtra.IsMultiLine) + assert.False(t, msg.ParsingExtra.IsTruncated) + assert.Empty(t, msg.ParsingExtra.Tags) + assertMessageContent(t, msg, "2") +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/json_detector.go b/pkg/logs/internal/decoder/auto_multiline_detection/json_detector.go index b58e2267c4f2c..b598f618f1494 100644 --- a/pkg/logs/internal/decoder/auto_multiline_detection/json_detector.go +++ b/pkg/logs/internal/decoder/auto_multiline_detection/json_detector.go @@ -18,9 +18,9 @@ func NewJSONDetector() *JSONDetector { return &JSONDetector{} } -// Process checks if a message is a JSON message. +// ProcessAndContinue checks if a message is a JSON message. // This implements the Herustic interface - so we should stop processing if we detect a JSON message by returning false. -func (j *JSONDetector) Process(context *messageContext) bool { +func (j *JSONDetector) ProcessAndContinue(context *messageContext) bool { if jsonRegexp.Match(context.rawMessage) { context.label = noAggregate return false diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/json_detector_test.go b/pkg/logs/internal/decoder/auto_multiline_detection/json_detector_test.go index a22fbdd1386e5..a325c0386cccc 100644 --- a/pkg/logs/internal/decoder/auto_multiline_detection/json_detector_test.go +++ b/pkg/logs/internal/decoder/auto_multiline_detection/json_detector_test.go @@ -43,7 +43,7 @@ func TestJsonDetector(t *testing.T) { rawMessage: []byte(tc.rawMessage), label: aggregate, } - assert.Equal(t, tc.expectedResult, jsonDetector.Process(messageContext)) + assert.Equal(t, tc.expectedResult, jsonDetector.ProcessAndContinue(messageContext)) assert.Equal(t, tc.expectedLabel, messageContext.label) }) } diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/labeler.go b/pkg/logs/internal/decoder/auto_multiline_detection/labeler.go index 177bbf313e0f2..097bda7410aa7 100644 --- a/pkg/logs/internal/decoder/auto_multiline_detection/labeler.go +++ b/pkg/logs/internal/decoder/auto_multiline_detection/labeler.go @@ -6,6 +6,8 @@ // Package automultilinedetection contains auto multiline detection and aggregation logic. package automultilinedetection +import "github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens" + // Label is a label for a log message. type Label uint32 @@ -19,15 +21,16 @@ type messageContext struct { rawMessage []byte // NOTE: tokens can be nil if the heuristic runs before the tokenizer. // Heuristic implementations must check if tokens is nil before using it. - tokens []Token - label Label + tokens []tokens.Token + tokenIndicies []int + label Label } // Heuristic is an interface representing a strategy to label log messages. type Heuristic interface { - // Process processes a log message and annotates the context with a label. It returns false if the message should be done processing. + // ProcessAndContinue processes a log message and annotates the context with a label. It returns false if the message should be done processing. // Heuristic implementations may mutate the message context but must do so synchronously. - Process(*messageContext) bool + ProcessAndContinue(*messageContext) bool } // Labeler labels log messages based on a set of heuristics. @@ -52,9 +55,22 @@ func (l *Labeler) Label(rawMessage []byte) Label { label: aggregate, } for _, h := range l.heuristics { - if !h.Process(context) { + if !h.ProcessAndContinue(context) { return context.label } } return context.label } + +func labelToString(label Label) string { + switch label { + case startGroup: + return "start_group" + case noAggregate: + return "no_aggregate" + case aggregate: + return "aggregate" + default: + return "" + } +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/labeler_test.go b/pkg/logs/internal/decoder/auto_multiline_detection/labeler_test.go index c65c62feb108f..754b795486287 100644 --- a/pkg/logs/internal/decoder/auto_multiline_detection/labeler_test.go +++ b/pkg/logs/internal/decoder/auto_multiline_detection/labeler_test.go @@ -16,7 +16,7 @@ type mockHeuristic struct { processFunc func(*messageContext) bool } -func (m *mockHeuristic) Process(context *messageContext) bool { +func (m *mockHeuristic) ProcessAndContinue(context *messageContext) bool { return m.processFunc(context) } diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/pattern_table.go b/pkg/logs/internal/decoder/auto_multiline_detection/pattern_table.go new file mode 100644 index 0000000000000..5675829ad07d9 --- /dev/null +++ b/pkg/logs/internal/decoder/auto_multiline_detection/pattern_table.go @@ -0,0 +1,133 @@ +// 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 automultilinedetection contains auto multiline detection and aggregation logic. +package automultilinedetection + +import ( + "github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens" + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +type row struct { + tokens []tokens.Token + label Label + count int64 + lastIndex int64 +} + +// DiagnosticRow is a struct that represents a diagnostic view of a row in the PatternTable. +type DiagnosticRow struct { + TokenString string + LabelString string + Count int64 + LastIndex int64 +} + +// PatternTable is a table of patterns that occur over time from a log source. +// The pattern table is always sorted by the frequency of the patterns. When the table +// becomes full, the least recently updated pattern is evicted. +type PatternTable struct { + table []*row + index int64 + maxTableSize int + matchThreshold float64 +} + +// NewPatternTable returns a new PatternTable heuristic. +func NewPatternTable(maxTableSize int, matchThreshold float64) *PatternTable { + return &PatternTable{ + table: make([]*row, 0, maxTableSize), + index: 0, + maxTableSize: maxTableSize, + matchThreshold: matchThreshold, + } +} + +// insert adds a pattern to the table and returns the index +func (p *PatternTable) insert(tokens []tokens.Token, label Label) int { + p.index++ + foundIdx := -1 + for i, r := range p.table { + if isMatch(r.tokens, tokens, p.matchThreshold) { + r.count++ + r.label = label + r.lastIndex = p.index + foundIdx = i + break + } + } + + if foundIdx == 0 { + return foundIdx + } + + if foundIdx > 0 { + return p.siftUp(foundIdx) + } + + // If the table is full, make room for a new entry + if len(p.table) >= p.maxTableSize { + p.evictLRU() + } + + p.table = append(p.table, &row{ + tokens: tokens, + label: label, + count: 1, + lastIndex: p.index, + }) + return len(p.table) - 1 + +} + +// siftUp moves the row at the given index up the table until it is in the correct position. +func (p *PatternTable) siftUp(idx int) int { + for idx != 0 && p.table[idx].count > p.table[idx-1].count { + p.table[idx], p.table[idx-1] = p.table[idx-1], p.table[idx] + idx-- + } + return idx +} + +// evictLRU removes the least recently updated row from the table. +func (p *PatternTable) evictLRU() { + mini := 0 + minIndex := p.index + for i, r := range p.table { + if r.lastIndex < minIndex { + minIndex = r.lastIndex + mini = i + } + } + p.table = append(p.table[:mini], p.table[mini+1:]...) +} + +// DumpTable returns a slice of DiagnosticRow structs that represent the current state of the table. +func (p *PatternTable) DumpTable() []DiagnosticRow { + debug := make([]DiagnosticRow, 0, len(p.table)) + for _, r := range p.table { + debug = append(debug, DiagnosticRow{ + TokenString: tokensToString(r.tokens), + LabelString: labelToString(r.label), + Count: r.count, + LastIndex: r.lastIndex}) + } + return debug +} + +// ProcessAndContinue adds a pattern to the table and updates its label based on it's frequency. +// This implements the Herustic interface - so we should stop processing if the label was changed +// due to pattern detection. +func (p *PatternTable) ProcessAndContinue(context *messageContext) bool { + + if context.tokens == nil { + log.Error("Tokens are required to process patterns") + return true + } + + p.insert(context.tokens, context.label) + return true +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/pattern_table_test.go b/pkg/logs/internal/decoder/auto_multiline_detection/pattern_table_test.go new file mode 100644 index 0000000000000..b1115761bc909 --- /dev/null +++ b/pkg/logs/internal/decoder/auto_multiline_detection/pattern_table_test.go @@ -0,0 +1,97 @@ +// 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 automultilinedetection contains auto multiline detection and aggregation logic. +package automultilinedetection + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens" +) + +func justTokens(tokens []tokens.Token, _ []int) []tokens.Token { + return tokens +} + +func TestPatternTable(t *testing.T) { + + tokenizer := NewTokenizer(0) + pt := NewPatternTable(5, 1) + + pt.insert(justTokens(tokenizer.tokenize([]byte("abc 123 !"))), aggregate) + pt.insert(justTokens(tokenizer.tokenize([]byte("abc 123 @"))), aggregate) + pt.insert(justTokens(tokenizer.tokenize([]byte("abc 123 $"))), aggregate) + pt.insert(justTokens(tokenizer.tokenize([]byte("abc 123 %"))), aggregate) + pt.insert(justTokens(tokenizer.tokenize([]byte("abc 123 ^"))), aggregate) + + assert.Equal(t, 5, len(pt.table)) + + // Add more of the same pattern - should remain at the top and get it's count updated + pt.insert(justTokens(tokenizer.tokenize([]byte("abc 123 !"))), aggregate) + pt.insert(justTokens(tokenizer.tokenize([]byte("abc 123 !"))), aggregate) + + assert.Equal(t, 5, len(pt.table)) + assert.Equal(t, int64(3), pt.table[0].count) + + // At this point `abc 123 @` was the last updated, so it will be evicted first + pt.insert(justTokens(tokenizer.tokenize([]byte("abc 123 *"))), aggregate) + + assert.Equal(t, 5, len(pt.table), "Table should not grow past limit") + dump := pt.DumpTable() + + assert.Equal(t, 5, len(dump)) + assert.Equal(t, "CCC DDD !", dump[0].TokenString) + assert.Equal(t, "CCC DDD $", dump[1].TokenString) + assert.Equal(t, "CCC DDD %", dump[2].TokenString) + assert.Equal(t, "CCC DDD ^", dump[3].TokenString) + assert.Equal(t, "CCC DDD *", dump[4].TokenString) + + // Should sift up to position #2 + pt.insert(justTokens(tokenizer.tokenize([]byte("abc 123 *"))), aggregate) + + dump = pt.DumpTable() + + assert.Equal(t, 5, len(dump)) + assert.Equal(t, "CCC DDD !", dump[0].TokenString) + assert.Equal(t, "CCC DDD *", dump[1].TokenString) + assert.Equal(t, "CCC DDD $", dump[2].TokenString) + assert.Equal(t, "CCC DDD %", dump[3].TokenString) + assert.Equal(t, "CCC DDD ^", dump[4].TokenString) + + assert.Equal(t, int64(3), dump[0].Count) + assert.Equal(t, int64(2), dump[1].Count) + assert.Equal(t, int64(1), dump[2].Count) + assert.Equal(t, int64(1), dump[3].Count) + assert.Equal(t, int64(1), dump[4].Count) + + // Lets pretend the whole log format totally changes for some reason, and evict the whole table. + pt.insert(justTokens(tokenizer.tokenize([]byte("! acb 123"))), startGroup) + pt.insert(justTokens(tokenizer.tokenize([]byte("@ acb 123"))), aggregate) + pt.insert(justTokens(tokenizer.tokenize([]byte("# acb 123"))), noAggregate) + pt.insert(justTokens(tokenizer.tokenize([]byte("$ acb 123"))), aggregate) + pt.insert(justTokens(tokenizer.tokenize([]byte("% acb 123"))), startGroup) + + dump = pt.DumpTable() + + assert.Equal(t, 5, len(dump)) + assert.Equal(t, "! CCC DDD", dump[0].TokenString) + assert.Equal(t, "@ CCC DDD", dump[1].TokenString) + assert.Equal(t, "# CCC DDD", dump[2].TokenString) + assert.Equal(t, "$ CCC DDD", dump[3].TokenString) + assert.Equal(t, "% CCC DDD", dump[4].TokenString) + assert.Equal(t, int64(1), dump[0].Count) + assert.Equal(t, int64(1), dump[1].Count) + assert.Equal(t, int64(1), dump[2].Count) + assert.Equal(t, int64(1), dump[3].Count) + assert.Equal(t, int64(1), dump[4].Count) + assert.Equal(t, "start_group", dump[0].LabelString) + assert.Equal(t, "aggregate", dump[1].LabelString) + assert.Equal(t, "no_aggregate", dump[2].LabelString) + assert.Equal(t, "aggregate", dump[3].LabelString) + assert.Equal(t, "start_group", dump[4].LabelString) +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/timestamp_detector.go b/pkg/logs/internal/decoder/auto_multiline_detection/timestamp_detector.go new file mode 100644 index 0000000000000..6cae17615f777 --- /dev/null +++ b/pkg/logs/internal/decoder/auto_multiline_detection/timestamp_detector.go @@ -0,0 +1,123 @@ +// 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 automultilinedetection contains auto multiline detection and aggregation logic. +package automultilinedetection + +import ( + "github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens" + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +// knownTimestampFormats is a list of known timestamp formats used to build the TokenGraph. +// Adding similar or partial duplicate timestamps does not impact accuracy since related +// tokens are inherently deduped in the graph. Be sure to test the accuracy of the heuristic +// after adding new formtas. +var knownTimestampFormats = []string{ + "2024-03-28T13:45:30.123456Z", + "28/Mar/2024:13:45:30", + "Sun, 28 Mar 2024 13:45:30", + "2024-03-28 13:45:30", + "2024-03-28 13:45:30,123", + "02 Jan 06 15:04 MST", + "2024-03-28T14:33:53.743350Z", + "2024-03-28T15:19:38.578639+00:00", + "2024-03-28 15:44:53", + "2024-08-20'T'13:20:10*633+0000", + "2024 Mar 03 05:12:41.211 PDT", + "Jan 21 18:20:11 +0000 2024", + "19/Apr/2024:06:36:15", + "Dec 2, 2024 2:39:58 AM", + "Jun 09 2024 15:28:14", + "Apr 20 00:00:35 2010", + "Sep 28 19:00:00 +0000", + "Mar 16 08:12:04", + "Jul 1 09:00:55", + "2024-10-14T22:11:20+0000", + "2024-07-01T14:59:55.711'+0000'", + "2024-07-01T14:59:55.711Z", + "2024-08-19 12:17:55-0400", + "2024-06-26 02:31:29,573", + "2024/04/12*19:37:50", + "2024 Apr 13 22:08:13.211*PDT", + "2024 Mar 10 01:44:20.392", + "2024-03-10 14:30:12,655+0000", + "2024-02-27 15:35:20.311", + "2024-07-22'T'16:28:55.444", + "2024-11-22'T'10:10:15.455", + "2024-02-11'T'18:31:44", + "2024-10-30*02:47:33:899", + "2024-07-04*13:23:55", + "24-02-11 16:47:35,985 +0000", + "24-06-26 02:31:29,573", + "24-04-19 12:00:17", + "06/01/24 04:11:05", + "08/10/24*13:33:56", + "11/24/2024*05:13:11", + "05/09/2024*08:22:14*612", + "04/23/24 04:34:22 +0000", + "2024/04/25 14:57:42", + "11:42:35.173", + "11:42:35,173", + "23/Apr 11:42:35,173", + "23/Apr/2024:11:42:35", + "23/Apr/2024 11:42:35", + "23-Apr-2024 11:42:35", + "23-Apr-2024 11:42:35.883", + "23 Apr 2024 11:42:35", + "23 Apr 2024 10:32:35*311", + "8/5/2024 3:31:18 AM:234", + "9/28/2024 2:23:15 PM", + "2023-03.28T14-33:53-7430Z", + "2017-05-16_13:53:08", +} + +// staticTokenGraph is never mutated after construction so this is safe to share between all instances of TimestampDetector. +var staticTokenGraph = makeStaticTokenGraph() + +// minimumTokenLength is the minimum number of tokens needed to evaluate a timestamp probability. +// This is not configurable because it has a large impact of the relative accuracy of the heuristic. +// For example, a string 12:30:2017 is tokenized to 5 tokens DD:DD:DDDD which can easily be confused +// with other non timestamp string. Enforcing more tokens to determine a likely timetamp decreases +// the likelihood of a false positive. 8 was chosen by iterative testing using the tests in timestamp_detector_test.go. +var minimumTokenLength = 8 + +func makeStaticTokenGraph() *TokenGraph { + tokenizer := NewTokenizer(100) // 100 is arbitrary, anything larger than the longest knownTimestampFormat is fine. + inputData := make([][]tokens.Token, len(knownTimestampFormats)) + for i, format := range knownTimestampFormats { + tokens, _ := tokenizer.tokenize([]byte(format)) + inputData[i] = tokens + } + return NewTokenGraph(minimumTokenLength, inputData) +} + +// TimestampDetector is a heuristic to detect timestamps. +type TimestampDetector struct { + tokenGraph *TokenGraph + matchThreshold float64 +} + +// NewTimestampDetector returns a new Timestamp detection heuristic. +func NewTimestampDetector(matchThreshold float64) *TimestampDetector { + return &TimestampDetector{ + tokenGraph: staticTokenGraph, + matchThreshold: matchThreshold, + } +} + +// ProcessAndContinue checks if a message is likely to be a timestamp. +func (t *TimestampDetector) ProcessAndContinue(context *messageContext) bool { + if context.tokens == nil { + log.Error("Tokens are required to detect timestamps") + return true + } + + if t.tokenGraph.MatchProbability(context.tokens).probability > t.matchThreshold { + context.label = startGroup + } + + return true +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/timestamp_detector_test.go b/pkg/logs/internal/decoder/auto_multiline_detection/timestamp_detector_test.go new file mode 100644 index 0000000000000..3d10b2705f46b --- /dev/null +++ b/pkg/logs/internal/decoder/auto_multiline_detection/timestamp_detector_test.go @@ -0,0 +1,121 @@ +// 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 automultilinedetection contains auto multiline detection and aggregation logic. +package automultilinedetection + +import ( + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/DataDog/datadog-agent/pkg/config" +) + +type testInput struct { + label Label + input string +} + +// Use this dataset to improve the accuracy of the timestamp detector. +// Ideally logs with the start group label should be very close to a 1.0 match probability +// and logs with the aggregate label should be very close to a 0.0 match probability. +var inputs = []testInput{ + // Likely contain timestamps for aggregation + {startGroup, "2021-03-28 13:45:30 App started successfully"}, + {startGroup, "13:45:30 2021-03-28"}, + {startGroup, "foo bar 13:45:30 2021-03-28"}, + {startGroup, "2023-03-28T14:33:53.743350Z App started successfully"}, + {startGroup, "2023-03-27 12:34:56 INFO App started successfully"}, + {startGroup, "2023-03.28T14-33:53-7430Z App started successfully"}, + {startGroup, "Datadog Agent 2023-03.28T14-33:53-7430Z App started successfully"}, + {startGroup, "[2023-03-27 12:34:56] [INFO] App started successfully"}, + {startGroup, "9/28/2022 2:23:15 PM"}, + {startGroup, "2024-05-15 17:04:12,369 - root - DEBUG -"}, + {startGroup, "[2024-05-15T18:03:23.501Z] Info : All routes applied."}, + {startGroup, "2024-05-15 14:03:13 EDT | CORE | INFO | (pkg/logs/tailers/file/tailer.go:353 in forwardMessages) | "}, + {startGroup, "Jun 14 15:16:01 combo sshd(pam_unix)[19939]: authentication failure; logname= uid=0 euid=0 tty=NODEVssh ruser= rhost=123.456.2.4 "}, + {startGroup, "Jul 1 09:00:55 calvisitor-10-105-160-95 kernel[0]: IOThunderboltSwitch<0>(0x0)::listenerCallback -"}, + {startGroup, "[Sun Dec 04 04:47:44 2005] [notice] workerEnv.init() ok /etc/httpd/conf/workers2.properties"}, + {startGroup, "2024/05/16 14:47:42 Datadog Tracer v1.64"}, + {startGroup, "2024/05/16 19:46:15 Datadog Tracer v1.64.0-rc.1 "}, + {startGroup, "127.0.0.1 - - [16/May/2024:19:49:17 +0000]"}, + {startGroup, "127.0.0.1 - - [17/May/2024:13:51:52 +0000] \"GET /probe?debug=1 HTTP/1.1\" 200 0 "}, + {startGroup, "nova-api.log.1.2017-05-16_13:53:08 2017-05-16 00:00:00.008 25746 INFO nova.osapi"}, + + // A case where the timestamp has a non-matching token in the midddle of it. + {startGroup, "acb def 10:10:10 foo 2024-05-15 hijk lmop"}, + + // Likely do not contain timestamps for aggreagtion + {aggregate, "12:30:2017 - info App started successfully"}, + {aggregate, "12:30:20 - info App started successfully"}, + {aggregate, "20171223-22:15:29:606|Step_LSC|30002312|onStandStepChanged 3579"}, + {aggregate, " . a at some log"}, + {aggregate, "abc this 13:45:30 is a log "}, + {aggregate, "abc this 13 45:30 is a log "}, + {aggregate, " [java] 1234-12-12"}, + {aggregate, " at system.com.blah"}, + {aggregate, "Info - this is an info message App started successfully"}, + {aggregate, "[INFO] App started successfully"}, + {aggregate, "[INFO] test.swift:123 App started successfully"}, + {aggregate, "ERROR in | myFile.go:53:123 App started successfully"}, + {aggregate, "a2de9888a8f1fc289547f77d4834e66 - - -] 10.11.10.1 "}, + {aggregate, "'/conf.d/..data/foobar_lifecycle.yaml' "}, + {aggregate, "commit: a2de9888a8f1fc289547f77d4834e669bf993e7e"}, + {aggregate, " auth.handler: auth handler stopped"}, + {aggregate, "10:10:10 foo :10: bar 10:10"}, + {aggregate, "1234-1234-1234-123-21-1"}, +} + +func TestCorrectLabelIsAssigned(t *testing.T) { + tokenizer := NewTokenizer(config.Datadog().GetInt("logs_config.auto_multi_line.tokenizer_max_input_bytes")) + timestampDetector := NewTimestampDetector(config.Datadog().GetFloat64("logs_config.auto_multi_line.timestamp_detector_match_threshold")) + + for _, testInput := range inputs { + context := &messageContext{ + rawMessage: []byte(testInput.input), + label: aggregate, + } + + assert.True(t, tokenizer.ProcessAndContinue(context)) + assert.True(t, timestampDetector.ProcessAndContinue(context)) + match := timestampDetector.tokenGraph.MatchProbability(context.tokens) + assert.Equal(t, testInput.label, context.label, fmt.Sprintf("input: %s had the wrong label with probability: %f", testInput.input, match.probability)) + + // To assist with debugging and tuning - this prints the probability and an underline of where the input was matched + printMatchUnderline(context, testInput.input, match) + } +} + +func printMatchUnderline(context *messageContext, input string, match MatchContext) { + maxLen := config.Datadog().GetInt("logs_config.auto_multi_line.tokenizer_max_input_bytes") + fmt.Printf("%.2f\t\t%v\n", match.probability, input) + + if match.start == match.end { + return + } + + evalStr := input + if len(input) > maxLen { + evalStr = input[:maxLen] + } + dbgStr := "" + printChar := " " + last := context.tokenIndicies[0] + for i, idx := range context.tokenIndicies { + dbgStr += strings.Repeat(printChar, idx-last) + if i == match.start { + printChar = "^" + } + if i == match.end+1 { + printChar = " " + } + last = idx + } + dbgStr += strings.Repeat(printChar, len(evalStr)-last) + fmt.Printf("\t\t\t%v\n", dbgStr) +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/token_graph.go b/pkg/logs/internal/decoder/auto_multiline_detection/token_graph.go new file mode 100644 index 0000000000000..f9c65fcbe8005 --- /dev/null +++ b/pkg/logs/internal/decoder/auto_multiline_detection/token_graph.go @@ -0,0 +1,114 @@ +// 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 automultilinedetection contains auto multiline detection and aggregation logic. +package automultilinedetection + +import "github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens" + +// TokenGraph is a directed cyclic graph of tokens that model the relationship between any two tokens. +// It is used to calculate the probability of an unknown sequence of tokens being represented by the graph. +type TokenGraph struct { + adjacencies [][]bool + minimumTokenLength int +} + +// MatchContext is the context of a match. +type MatchContext struct { + probability float64 + // start and end are the indices of the token subsequence that produced the highest probability. + start int + end int +} + +// NewTokenGraph returns a new TokenGraph. +func NewTokenGraph(minimumTokenLength int, inputData [][]tokens.Token) *TokenGraph { + g := &TokenGraph{ + adjacencies: make([][]bool, tokens.End), + minimumTokenLength: minimumTokenLength, + } + for _, tokens := range inputData { + g.add(tokens) + } + return g +} + +// add adds a sequence of tokens to the graph. +func (m *TokenGraph) add(ts []tokens.Token) { + lastToken := ts[0] + for _, token := range ts[1:] { + if m.adjacencies[lastToken] == nil { + m.adjacencies[lastToken] = make([]bool, tokens.End) + } + m.adjacencies[lastToken][token] = true + lastToken = token + } +} + +// MatchProbability returns the probability of a sequence of tokens being represented by the graph. +func (m *TokenGraph) MatchProbability(ts []tokens.Token) MatchContext { + if len(ts) < m.minimumTokenLength { + return MatchContext{} + } + + lastToken := ts[0] + // A function used by maxSubsequence to look up a match in the graph for a pair of tokens. + matchForIndex := func(idx int) int { + match := -1 + if m.adjacencies[lastToken] != nil && m.adjacencies[lastToken][ts[idx+1]] { + match = 1 + } + lastToken = ts[idx+1] + return match + } + + // Look up each token transition and mark it with a 1 (match) or -1 (no match). From this + // we must compute the subsequences that have the highest probability of being a match. + // This code may seem overcomplicated but it's designed this way to avoid allocating an additional buffer to + // store the matches while remaining testable and clear. + avg, start, end := maxSubsequence(len(ts)-1, matchForIndex) + + // Reject sequences of tokens that are less than the minimum token length. + if end-start < m.minimumTokenLength { + return MatchContext{} + } + + return MatchContext{ + probability: avg, + start: start, + end: end, + } +} + +// maxSubsequence is a modified Kadane’s Algorithm that returns the average, start, and end of the largest subsequence. +// It takes a length of the target input, and a function used to look up values for each index. +func maxSubsequence(length int, matchForIndex func(idx int) int) (float64, int, int) { + if length == 0 { + return 0, 0, 0 + } + maxSum := matchForIndex(0) + currentSum := maxSum + start := 0 + end := 0 + tempStart := 0 + + for i := 1; i < length; i++ { + v := matchForIndex(i) + if v > currentSum+v { + currentSum = v + tempStart = i + } else { + currentSum += v + } + + if currentSum > maxSum { + maxSum = currentSum + start = tempStart + end = i + } + } + end++ + return float64(maxSum) / float64(end-start), start, end +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/token_graph_test.go b/pkg/logs/internal/decoder/auto_multiline_detection/token_graph_test.go new file mode 100644 index 0000000000000..6d86f574fd4d8 --- /dev/null +++ b/pkg/logs/internal/decoder/auto_multiline_detection/token_graph_test.go @@ -0,0 +1,60 @@ +// 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 automultilinedetection contains auto multiline detection and aggregation logic. +package automultilinedetection + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens" +) + +func TestMatchEmpty(t *testing.T) { + emptyTokenGraph := NewTokenGraph(2, nil) + assert.Equal(t, float64(0), emptyTokenGraph.MatchProbability([]tokens.Token{}).probability) +} + +func TestExpectedMatch(t *testing.T) { + graph := NewTokenGraph(0, [][]tokens.Token{{1, 2, 3}}) + assert.Equal(t, float64(1), graph.MatchProbability([]tokens.Token{1, 2, 3}).probability, "Input should match exactly") + assert.Equal(t, float64(-1), graph.MatchProbability([]tokens.Token{3, 2, 1}).probability, "Backwards input should not match because the graph is directed") + assert.Equal(t, float64(-1), graph.MatchProbability([]tokens.Token{4, 5, 6}).probability, "Unknown input should not match") + + graph = NewTokenGraph(0, [][]tokens.Token{{1, 2, 3}, {3, 2, 1}}) + assert.Equal(t, float64(1), graph.MatchProbability([]tokens.Token{1, 2, 3}).probability, "Input should match exactly") + assert.Equal(t, float64(1), graph.MatchProbability([]tokens.Token{3, 2, 1}).probability, "Backwards input should match") + assert.Equal(t, float64(-1), graph.MatchProbability([]tokens.Token{4, 5, 6}).probability, "Unknown input should not match") + + graph = NewTokenGraph(0, [][]tokens.Token{{1, 2, 3, 4, 5, 6}}) + assert.Equal(t, float64(1), graph.MatchProbability([]tokens.Token{7, 2, 3, 4, 5, 8}).probability, "Input should match because unmatch tokens are trimmed") +} + +func TestMaxSubsequence(t *testing.T) { + tests := []struct { + input []int + expected []int + }{ + {[]int{}, []int{}}, + {[]int{1, 1, 1, 1, 1}, []int{1, 1, 1, 1, 1}}, + {[]int{-1, -1, 1, -1, -1}, []int{1}}, + {[]int{-1, 1, 1}, []int{1, 1}}, + {[]int{1, 1, -1}, []int{1, 1}}, + {[]int{-1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1}, []int{1, 1, 1, 1}}, + {[]int{-1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1}, []int{1, 1, 1, -1, -1, -1, 1, 1, 1, 1}}, + {[]int{1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1}, []int{1, 1, 1}}, + {[]int{1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1}, []int{1, -1, 1, 1, 1}}, + } + + for _, test := range tests { + _, start, end := maxSubsequence(len(test.input), func(idx int) int { + return test.input[idx] + }) + + assert.Equal(t, test.expected, test.input[start:end]) + } +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer.go b/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer.go index eb8cadc534385..a798ce44f58d9 100644 --- a/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer.go +++ b/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer.go @@ -8,84 +8,17 @@ package automultilinedetection import ( "bytes" + "math" "strings" "unicode" -) -// Token is the type that represents a single token. -type Token byte + "github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens" +) // maxRun is the maximum run of a char or digit before it is capped. // Note: This must not exceed d10 or c10 below. const maxRun = 10 -const ( - space Token = iota - - // Special Characters - colon // : - semicolon // ; - dash // - - underscore // _ - fslash // / - bslash // \ - period // . - comma // , - singlequote // ' - doublequote // " - backtick // ` - tilda // ~ - star // * - plus // + - equal // = - parenopen // ( - parenclose // ) - braceopen // { - braceclose // } - bracketopen // [ - bracketclose // ] - ampersand // & - exclamation // ! - at // @ - pound // # - dollar // $ - percent // % - uparrow // ^ - - // Digit runs - d1 - d2 - d3 - d4 - d5 - d6 - d7 - d8 - d9 - d10 - - // Char runs - c1 - c2 - c3 - c4 - c5 - c6 - c7 - c8 - c9 - c10 - - // Special tokens - month - day - apm // am or pm - zone // Represents a timezone - t // t (often `T`) denotes a time separator in many timestamp formats - - end // Not a valid token. Used to mark the end of the token list or as a terminator. -) - // Tokenizer is a heuristic to compute tokens from a log message. // The tokenizer is used to convert a log message (string of bytes) into a list of tokens that // represents the underlying structure of the log. The string of tokens is a compact slice of bytes @@ -104,25 +37,30 @@ func NewTokenizer(maxEvalBytes int) *Tokenizer { } } -// Process enriches the message context with tokens. +// ProcessAndContinue enriches the message context with tokens. // This implements the Herustic interface - this heuristic does not stop processing. -func (t *Tokenizer) Process(context *messageContext) bool { +func (t *Tokenizer) ProcessAndContinue(context *messageContext) bool { maxBytes := len(context.rawMessage) if maxBytes > t.maxEvalBytes { maxBytes = t.maxEvalBytes } - context.tokens = t.tokenize(context.rawMessage[:maxBytes]) + tokens, indicies := t.tokenize(context.rawMessage[:maxBytes]) + context.tokens = tokens + context.tokenIndicies = indicies return true } // tokenize converts a byte slice to a list of tokens. -func (t *Tokenizer) tokenize(input []byte) []Token { - // len(tokens) will always be <= len(input) - tokens := make([]Token, 0, len(input)) +// This function return the slice of tokens, and a slice of indices where each token starts. +func (t *Tokenizer) tokenize(input []byte) ([]tokens.Token, []int) { + // len(ts) will always be <= len(input) + ts := make([]tokens.Token, 0, len(input)) + indicies := make([]int, 0, len(input)) if len(input) == 0 { - return tokens + return ts, indicies } + idx := 0 run := 0 lastToken := getToken(input[0]) t.strBuf.Reset() @@ -135,29 +73,33 @@ func (t *Tokenizer) tokenize(input []byte) []Token { }() // Only test for special tokens if the last token was a charcater (Special tokens are currently only A-Z). - if lastToken == c1 { + if lastToken == tokens.C1 { if t.strBuf.Len() == 1 { - if specialToken := getSpecialShortToken(t.strBuf.Bytes()[0]); specialToken != end { - tokens = append(tokens, specialToken) + if specialToken := getSpecialShortToken(t.strBuf.Bytes()[0]); specialToken != tokens.End { + ts = append(ts, specialToken) + indicies = append(indicies, idx) return } } else if t.strBuf.Len() > 1 { // Only test special long tokens if buffer is > 1 token - if specialToken := getSpecialLongToken(t.strBuf.String()); specialToken != end { - tokens = append(tokens, specialToken) + if specialToken := getSpecialLongToken(t.strBuf.String()); specialToken != tokens.End { + ts = append(ts, specialToken) + indicies = append(indicies, idx-run) return } } } // Check for char or digit runs - if lastToken == c1 || lastToken == d1 { + if lastToken == tokens.C1 || lastToken == tokens.D1 { + indicies = append(indicies, idx-run) // Limit max run size if run >= maxRun { run = maxRun - 1 } - tokens = append(tokens, lastToken+Token(run)) + ts = append(ts, lastToken+tokens.Token(run)) } else { - tokens = append(tokens, lastToken) + ts = append(ts, lastToken) + indicies = append(indicies, idx-run) } } @@ -168,211 +110,240 @@ func (t *Tokenizer) tokenize(input []byte) []Token { } else { run++ } - if currentToken == c1 { + if currentToken == tokens.C1 { // Store upper case A-Z characters for matching special tokens t.strBuf.WriteRune(unicode.ToUpper(rune(char))) } else { t.strBuf.WriteByte(char) } lastToken = currentToken + idx++ } // Flush any remaining buffered tokens insertToken() - return tokens + return ts, indicies } // getToken returns a single token from a single byte. -func getToken(char byte) Token { +func getToken(char byte) tokens.Token { if unicode.IsDigit(rune(char)) { - return d1 + return tokens.D1 } else if unicode.IsSpace(rune(char)) { - return space + return tokens.Space } switch char { case ':': - return colon + return tokens.Colon case ';': - return semicolon + return tokens.Semicolon case '-': - return dash + return tokens.Dash case '_': - return underscore + return tokens.Underscore case '/': - return fslash + return tokens.Fslash case '\\': - return bslash + return tokens.Bslash case '.': - return period + return tokens.Period case ',': - return comma + return tokens.Comma case '\'': - return singlequote + return tokens.Singlequote case '"': - return doublequote + return tokens.Doublequote case '`': - return backtick + return tokens.Backtick case '~': - return tilda + return tokens.Tilda case '*': - return star + return tokens.Star case '+': - return plus + return tokens.Plus case '=': - return equal + return tokens.Equal case '(': - return parenopen + return tokens.Parenopen case ')': - return parenclose + return tokens.Parenclose case '{': - return braceopen + return tokens.Braceopen case '}': - return braceclose + return tokens.Braceclose case '[': - return bracketopen + return tokens.Bracketopen case ']': - return bracketclose + return tokens.Bracketclose case '&': - return ampersand + return tokens.Ampersand case '!': - return exclamation + return tokens.Exclamation case '@': - return at + return tokens.At case '#': - return pound + return tokens.Pound case '$': - return dollar + return tokens.Dollar case '%': - return percent + return tokens.Percent case '^': - return uparrow + return tokens.Uparrow } - return c1 + return tokens.C1 } -func getSpecialShortToken(char byte) Token { +func getSpecialShortToken(char byte) tokens.Token { switch char { case 'T': - return t + return tokens.T case 'Z': - return zone + return tokens.Zone } - return end + return tokens.End } // getSpecialLongToken returns a special token that is > 1 character. // NOTE: This set of tokens is non-exhaustive and can be expanded. -func getSpecialLongToken(input string) Token { +func getSpecialLongToken(input string) tokens.Token { switch input { case "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC": - return month + return tokens.Month case "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN": - return day + return tokens.Day case "AM", "PM": - return apm + return tokens.Apm case "UTC", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", "PDT", "JST", "KST", "IST", "MSK", "CEST", "CET", "BST", "NZST", "NZDT", "ACST", "ACDT", "AEST", "AEDT", "AWST", "AWDT", "AKST", "AKDT", "HST", "HDT", "CHST", "CHDT", "NST", "NDT": - return zone + return tokens.Zone } - return end + return tokens.End } // tokenToString converts a single token to a debug string. -func tokenToString(token Token) string { - if token >= d1 && token <= d10 { - return strings.Repeat("D", int(token-d1)+1) - } else if token >= c1 && token <= c10 { - return strings.Repeat("C", int(token-c1)+1) +func tokenToString(token tokens.Token) string { + if token >= tokens.D1 && token <= tokens.D10 { + return strings.Repeat("D", int(token-tokens.D1)+1) + } else if token >= tokens.C1 && token <= tokens.C10 { + return strings.Repeat("C", int(token-tokens.C1)+1) } switch token { - case space: + case tokens.Space: return " " - case colon: + case tokens.Colon: return ":" - case semicolon: + case tokens.Semicolon: return ";" - case dash: + case tokens.Dash: return "-" - case underscore: + case tokens.Underscore: return "_" - case fslash: + case tokens.Fslash: return "/" - case bslash: + case tokens.Bslash: return "\\" - case period: + case tokens.Period: return "." - case comma: + case tokens.Comma: return "," - case singlequote: + case tokens.Singlequote: return "'" - case doublequote: + case tokens.Doublequote: return "\"" - case backtick: + case tokens.Backtick: return "`" - case tilda: + case tokens.Tilda: return "~" - case star: + case tokens.Star: return "*" - case plus: + case tokens.Plus: return "+" - case equal: + case tokens.Equal: return "=" - case parenopen: + case tokens.Parenopen: return "(" - case parenclose: + case tokens.Parenclose: return ")" - case braceopen: + case tokens.Braceopen: return "{" - case braceclose: + case tokens.Braceclose: return "}" - case bracketopen: + case tokens.Bracketopen: return "[" - case bracketclose: + case tokens.Bracketclose: return "]" - case ampersand: + case tokens.Ampersand: return "&" - case exclamation: + case tokens.Exclamation: return "!" - case at: + case tokens.At: return "@" - case pound: + case tokens.Pound: return "#" - case dollar: + case tokens.Dollar: return "$" - case percent: + case tokens.Percent: return "%" - case uparrow: + case tokens.Uparrow: return "^" - case month: + case tokens.Month: return "MTH" - case day: + case tokens.Day: return "DAY" - case apm: + case tokens.Apm: return "PM" - case t: + case tokens.T: return "T" - case zone: + case tokens.Zone: return "ZONE" } - return "" } // tokensToString converts a list of tokens to a debug string. -func tokensToString(tokens []Token) string { +func tokensToString(tokens []tokens.Token) string { str := "" for _, t := range tokens { str += tokenToString(t) } return str } + +// isMatch compares two sequences of tokens and returns true if they match within the +// given threshold. if the token strings are different lengths, the shortest string is +// used for comparison. This function is optimized to exit early if the match is impossible +// without having to compare all of the tokens. +func isMatch(seqA []tokens.Token, seqB []tokens.Token, thresh float64) bool { + count := len(seqA) + if len(seqB) < count { + count = len(seqB) + } + + if count == 0 { + return len(seqA) == len(seqB) + } + + requiredMatches := int(math.Round(thresh * float64(count))) + match := 0 + + for i := 0; i < count; i++ { + if seqA[i] == seqB[i] { + match++ + } + if match+(count-i-1) < requiredMatches { + return false + } + } + + return true +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer_benchamrk_test.go b/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer_benchamrk_test.go index 19b9b8a4beab8..3dca63009ac19 100644 --- a/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer_benchamrk_test.go +++ b/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer_benchamrk_test.go @@ -23,3 +23,36 @@ func BenchmarkTokenizerShort(b *testing.B) { tokenizer.tokenize([]byte("abc123")) } } + +func BenchmarkTokenizerIsMatchNoMatchStart(b *testing.B) { + tokenizer := NewTokenizer(0) + ta, _ := tokenizer.tokenize([]byte("Sun Mar 2PM EST JAN FEB MAR !@#$%^&*()_+[]:-/\\.,\\'{}\"`~ 0123456789 NZST ACDT aaaaaaaaaaaaaaaa CHST T!Z(T)Z#AM 123-abc-[foo] (bar) 12-12-12T12:12:12.12T12:12Z123")) + tb, _ := tokenizer.tokenize([]byte("$ abc foo bar thie beginning is different !@#$%^&*()_+[]:-/\\.,\\'{}\"`~ 0123456789 NZST ACDT aaaaaaaaaaaaaaaa CHST T!Z(T)Z#AM 123-abc-[foo] (bar) 12-12-12T12:12:12.12T12:12Z123")) + + b.ResetTimer() + for n := 0; n < b.N; n++ { + isMatch(ta, tb, 0.75) + } +} + +func BenchmarkTokenizerIsMatchNoMatchEnd(b *testing.B) { + tokenizer := NewTokenizer(0) + ta, _ := tokenizer.tokenize([]byte("Sun Mar 2PM EST JAN FEB MAR !@#$%^&*()_+[]:-/\\.,\\'{}\"`~ 0123456789 NZST ACDT aaaaaaaaaaaaaaaa CHST T!Z(T)Z#AM 123-abc-[foo] (bar) 12-12-12T12:12:12.12T12:12Z123")) + tb, _ := tokenizer.tokenize([]byte("Sun Mar 2PM EST JAN FEB MAR !@#$%^&*()_+[]:-/\\.,\\'{}\"`~ 0123456789 NZST ACDT aaaaaaaaaaaaaaaa CHST But this one is different near the end of the sequence")) + + b.ResetTimer() + for n := 0; n < b.N; n++ { + isMatch(ta, tb, 0.75) + } +} + +func BenchmarkTokenizerIsMatchFullMatch(b *testing.B) { + tokenizer := NewTokenizer(0) + ta, _ := tokenizer.tokenize([]byte("Sun Mar 2PM EST JAN FEB MAR !@#$%^&*()_+[]:-/\\.,\\'{}\"`~ 0123456789 NZST ACDT aaaaaaaaaaaaaaaa CHST T!Z(T)Z#AM 123-abc-[foo] (bar) 12-12-12T12:12:12.12T12:12Z123")) + tb, _ := tokenizer.tokenize([]byte("Sun Mar 2PM EST JAN FEB MAR !@#$%^&*()_+[]:-/\\.,\\'{}\"`~ 0123456789 NZST ACDT aaaaaaaaaaaaaaaa CHST T!Z(T)Z#AM 123-abc-[foo] (bar) 12-12-12T12:12:12.12T12:12Z123")) + + b.ResetTimer() + for n := 0; n < b.N; n++ { + isMatch(ta, tb, 0.75) + } +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer_test.go b/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer_test.go index d48c25fb8f763..26e339bafba94 100644 --- a/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer_test.go +++ b/pkg/logs/internal/decoder/auto_multiline_detection/tokenizer_test.go @@ -10,6 +10,8 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens" ) type testCase struct { @@ -47,40 +49,89 @@ func TestTokenizer(t *testing.T) { tokenizer := NewTokenizer(0) for _, tc := range testCases { - actualToken := tokensToString(tokenizer.tokenize([]byte(tc.input))) + tokens, _ := tokenizer.tokenize([]byte(tc.input)) + actualToken := tokensToString(tokens) assert.Equal(t, tc.expectedToken, actualToken) } } func TestTokenizerMaxCharRun(t *testing.T) { - tokens := tokensToString(NewTokenizer(0).tokenize([]byte("ABCDEFGHIJKLMNOP"))) - assert.Equal(t, "CCCCCCCCCC", tokens) + tokens, indicies := NewTokenizer(0).tokenize([]byte("ABCDEFGHIJKLMNOP")) + assert.Equal(t, "CCCCCCCCCC", tokensToString(tokens)) + assert.Equal(t, []int{0}, indicies) } func TestTokenizerMaxDigitRun(t *testing.T) { - tokens := tokensToString(NewTokenizer(0).tokenize([]byte("0123456789012345"))) - assert.Equal(t, "DDDDDDDDDD", tokens) + tokens, indicies := NewTokenizer(0).tokenize([]byte("0123456789012345")) + assert.Equal(t, "DDDDDDDDDD", tokensToString(tokens)) + assert.Equal(t, []int{0}, indicies) } func TestAllSymbolsAreHandled(t *testing.T) { - for i := space; i < d1; i++ { + for i := tokens.Space; i < tokens.D1; i++ { str := tokenToString(i) assert.NotEmpty(t, str, "Token %d is not converted to a debug string", i) - assert.NotEqual(t, getToken(byte(str[0])), c1, "Token %v is not tokenizable", str) + assert.NotEqual(t, getToken(byte(str[0])), tokens.C1, "Token %v is not tokenizable", str) } } func TestTokenizerHeuristic(t *testing.T) { tokenizer := NewTokenizer(10) msg := &messageContext{rawMessage: []byte("1234567890abcdefg")} - assert.True(t, tokenizer.Process(msg)) + assert.True(t, tokenizer.ProcessAndContinue(msg)) assert.Equal(t, "DDDDDDDDDD", tokensToString(msg.tokens), "Tokens should be limited to 10 digits") msg = &messageContext{rawMessage: []byte("12-12-12T12:12:12.12T12:12Z123")} - assert.True(t, tokenizer.Process(msg)) + assert.True(t, tokenizer.ProcessAndContinue(msg)) assert.Equal(t, "DD-DD-DDTD", tokensToString(msg.tokens), "Tokens should be limited to the first 10 bytes") + assert.Equal(t, []int{0, 2, 3, 5, 6, 8, 9}, msg.tokenIndicies) msg = &messageContext{rawMessage: []byte("abc 123")} - assert.True(t, tokenizer.Process(msg)) + assert.True(t, tokenizer.ProcessAndContinue(msg)) assert.Equal(t, "CCC DDD", tokensToString(msg.tokens)) + assert.Equal(t, []int{0, 3, 4}, msg.tokenIndicies) + + msg = &messageContext{rawMessage: []byte("Jan 123")} + assert.True(t, tokenizer.ProcessAndContinue(msg)) + assert.Equal(t, "MTH DDD", tokensToString(msg.tokens)) + assert.Equal(t, []int{0, 3, 4}, msg.tokenIndicies) + + msg = &messageContext{rawMessage: []byte("123Z")} + assert.True(t, tokenizer.ProcessAndContinue(msg)) + assert.Equal(t, "DDDZONE", tokensToString(msg.tokens)) + assert.Equal(t, []int{0, 3}, msg.tokenIndicies) +} + +func TestIsMatch(t *testing.T) { + tokenizer := NewTokenizer(0) + // A string of 10 tokens to make math easier. + ta, _ := tokenizer.tokenize([]byte("! @ # $ %")) + tb, _ := tokenizer.tokenize([]byte("! @ # $ %")) + + assert.True(t, isMatch(ta, tb, 1)) + + ta, _ = tokenizer.tokenize([]byte("! @ # $ % ")) + tb, _ = tokenizer.tokenize([]byte("! @ #1a1a1")) + + assert.True(t, isMatch(ta, tb, 0.5)) + assert.False(t, isMatch(ta, tb, 0.55)) + + ta, _ = tokenizer.tokenize([]byte("! @ # $ % ")) + tb, _ = tokenizer.tokenize([]byte("#1a1a1$ $ ")) + + assert.False(t, isMatch(ta, tb, 0.5)) + assert.True(t, isMatch(ta, tb, 0.3)) + + ta, _ = tokenizer.tokenize([]byte("! @ # $ % ")) + tb, _ = tokenizer.tokenize([]byte("")) + + assert.False(t, isMatch(ta, tb, 0.5)) + assert.False(t, isMatch(ta, tb, 0)) + assert.False(t, isMatch(ta, tb, 1)) + + ta, _ = tokenizer.tokenize([]byte("! @ # $ % ")) + tb, _ = tokenizer.tokenize([]byte("!")) + + assert.True(t, isMatch(ta, tb, 1)) + assert.True(t, isMatch(ta, tb, 0.01)) } diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/tokens/tokens.go b/pkg/logs/internal/decoder/auto_multiline_detection/tokens/tokens.go new file mode 100644 index 0000000000000..5d12d8ba05bc3 --- /dev/null +++ b/pkg/logs/internal/decoder/auto_multiline_detection/tokens/tokens.go @@ -0,0 +1,82 @@ +// 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 tokens contains the token definitions for the tokenizer. +package tokens + +// Token is the type that represents a single token. +type Token byte + +// Disable linter since the token list is self explanatory, or documented where needed. +// +//revive:disable +const ( + Space Token = iota + + // Special Characters + Colon // : + Semicolon // ; + Dash // - + Underscore // _ + Fslash // / + Bslash // \ + Period // . + Comma // , + Singlequote // ' + Doublequote // " + Backtick // ` + Tilda // ~ + Star // * + Plus // + + Equal // = + Parenopen // ( + Parenclose // ) + Braceopen // { + Braceclose // } + Bracketopen // [ + Bracketclose // ] + Ampersand // & + Exclamation // ! + At // @ + Pound // # + Dollar // $ + Percent // % + Uparrow // ^ + + // Digit runs + D1 + D2 + D3 + D4 + D5 + D6 + D7 + D8 + D9 + D10 + + // Char runs + C1 + C2 + C3 + C4 + C5 + C6 + C7 + C8 + C9 + C10 + + // Special tokens + Month + Day + Apm // am or pm + Zone // Represents a timezone + T // t (often `T`) denotes a time separator in many timestamp formats + + End // Not a valid token. Used to mark the end of the token list or as a terminator. +) + +//revive:enable diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/user_samples.go b/pkg/logs/internal/decoder/auto_multiline_detection/user_samples.go new file mode 100644 index 0000000000000..49dbf2ca8bbb7 --- /dev/null +++ b/pkg/logs/internal/decoder/auto_multiline_detection/user_samples.go @@ -0,0 +1,109 @@ +// 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 automultilinedetection contains auto multiline detection and aggregation logic. +package automultilinedetection + +import ( + "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection/tokens" + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +const defaultMatchThreshold = 0.75 + +// UserSample represents a user-defined sample for auto multi-line detection. +type UserSample struct { + // Sample is a raw log message sample used to aggregate logs. + Sample string `mapstructure:"sample"` + // MatchThreshold is the ratio of tokens that must match between the sample and the log message to consider it a match. + // From a user perspective, this is how similar the log has to be to the sample to be considered a match. + // Optional - Default value is 0.75. + MatchThreshold *float64 `mapstructure:"match_threshold,omitempty"` + // Label is the label to apply to the log message if it matches the sample. + // Optional - Default value is "start_group". + Label *string `mapstructure:"label,omitempty"` + + // Parse fields + tokens []tokens.Token + matchThreshold float64 + label Label +} + +// UserSamples is a heuristic that represents a collection of user-defined samples for auto multi-line aggreagtion. +type UserSamples struct { + samples []*UserSample +} + +// NewUserSamples creates a new UserSamples instance. +func NewUserSamples(config config.Reader) *UserSamples { + tokenizer := NewTokenizer(0) + s := make([]*UserSample, 0) + err := config.UnmarshalKey("logs_config.auto_multi_line_detection_custom_samples", &s) + + if err != nil { + log.Error("Failed to unmarshal custom samples: ", err) + return &UserSamples{ + samples: []*UserSample{}, + } + } + + parsedSamples := make([]*UserSample, 0, len(s)) + for _, sample := range s { + if sample.Sample == "" { + log.Warn("Sample was empty, skipping sample") + continue + } + sample.tokens, _ = tokenizer.tokenize([]byte(sample.Sample)) + if sample.MatchThreshold != nil { + if *sample.MatchThreshold <= 0 || *sample.MatchThreshold > 1 { + log.Warnf("Invalid match threshold %f, skipping sample", *sample.MatchThreshold) + continue + } + sample.matchThreshold = *sample.MatchThreshold + } else { + sample.matchThreshold = defaultMatchThreshold + } + + if sample.Label != nil { + switch *sample.Label { + case "start_group": + sample.label = startGroup + case "no_aggregate": + sample.label = noAggregate + case "aggregate": + sample.label = aggregate + default: + log.Warnf("Unknown label %s, skipping sample", *sample.Label) + continue + } + } else { + sample.label = startGroup + } + + parsedSamples = append(parsedSamples, sample) + } + + return &UserSamples{ + samples: parsedSamples, + } +} + +// ProcessAndContinue applies a user sample to a log message. If it matches, a label is assigned. +// This implements the Herustic interface - so we should stop processing if we detect a user pattern by returning false. +func (j *UserSamples) ProcessAndContinue(context *messageContext) bool { + if context.tokens == nil { + log.Error("Tokens are required to process user samples") + return true + } + + for _, sample := range j.samples { + if isMatch(sample.tokens, context.tokens, sample.matchThreshold) { + context.label = sample.label + return false + } + } + return true +} diff --git a/pkg/logs/internal/decoder/auto_multiline_detection/user_samples_test.go b/pkg/logs/internal/decoder/auto_multiline_detection/user_samples_test.go new file mode 100644 index 0000000000000..e3579cf7bf5e6 --- /dev/null +++ b/pkg/logs/internal/decoder/auto_multiline_detection/user_samples_test.go @@ -0,0 +1,182 @@ +// 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 automultilinedetection contains auto multiline detection and aggregation logic. +package automultilinedetection + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" +) + +func TestUserPatternsInvalidConfig(t *testing.T) { + datadogYaml := ` +logs_config: + auto_multi_line_detection_custom_samples: + - foo bar +` + mockConfig := pkgconfigsetup.ConfFromYAML(datadogYaml) + + samples := NewUserSamples(mockConfig) + assert.Equal(t, 0, len(samples.samples)) +} + +func TestUserPatternsInvalidValues(t *testing.T) { + datadogYaml := ` +logs_config: + auto_multi_line_detection_custom_samples: + - sample: 1234 + match_threshold: "abcd" + label: foo bar +` + mockConfig := pkgconfigsetup.ConfFromYAML(datadogYaml) + + samples := NewUserSamples(mockConfig) + assert.Equal(t, 0, len(samples.samples)) +} + +func TestUserPatternsDefaults(t *testing.T) { + + expectedOutput, _ := NewTokenizer(0).tokenize([]byte("sample")) + + datadogYaml := ` +logs_config: + auto_multi_line_detection_custom_samples: + - sample: "sample" +` + mockConfig := pkgconfigsetup.ConfFromYAML(datadogYaml) + + samples := NewUserSamples(mockConfig) + assert.Equal(t, expectedOutput, samples.samples[0].tokens) + assert.Equal(t, defaultMatchThreshold, samples.samples[0].matchThreshold) + assert.Equal(t, startGroup, samples.samples[0].label) +} + +func TestUserPatternsLabelTypes(t *testing.T) { + + datadogYaml := ` +logs_config: + auto_multi_line_detection_custom_samples: + - sample: "1" + label: "start_group" + - sample: "2" + label: "no_aggregate" + - sample: "3" + label: "aggregate" + - sample: "4" + label: "invalid" +` + mockConfig := pkgconfigsetup.ConfFromYAML(datadogYaml) + + samples := NewUserSamples(mockConfig) + assert.Equal(t, 3, len(samples.samples)) + assert.Equal(t, startGroup, samples.samples[0].label) + assert.Equal(t, noAggregate, samples.samples[1].label) + assert.Equal(t, aggregate, samples.samples[2].label) +} + +func TestUserPatternsMatchThreshold(t *testing.T) { + + datadogYaml := ` +logs_config: + auto_multi_line_detection_custom_samples: + - sample: "default" + - sample: "custom" + match_threshold: 0.1234 + - sample: "invalid1" + match_threshold: -9241 + - sample: "invalid2" + match_threshold: 2 + - sample: + - sample: "" + - match_threshold: 0.1 + - label: no_aggregate +` + mockConfig := pkgconfigsetup.ConfFromYAML(datadogYaml) + + samples := NewUserSamples(mockConfig) + assert.Equal(t, 2, len(samples.samples)) + assert.Equal(t, defaultMatchThreshold, samples.samples[0].matchThreshold) + assert.Equal(t, 0.1234, samples.samples[1].matchThreshold) +} + +func TestUserPatternsProcess(t *testing.T) { + + datadogYaml := ` +logs_config: + auto_multi_line_detection_custom_samples: + - sample: "!!![$my custom prefix%]" +` + + mockConfig := pkgconfigsetup.ConfFromYAML(datadogYaml) + samples := NewUserSamples(mockConfig) + tokenizer := NewTokenizer(60) + + tests := []struct { + expectedLabel Label + shouldStop bool + input string + }{ + {aggregate, true, ""}, + {aggregate, true, "some random log line"}, + {aggregate, true, "2023-03-28T14:33:53.743350Z App started successfully"}, + {startGroup, false, "!!![$my custom prefix%] some other log line"}, + {startGroup, false, "!!![$my slight variation%] some other log line"}, + {aggregate, true, "!!![$Not_close_enough%] some other log line"}, + } + + for _, test := range tests { + context := &messageContext{ + rawMessage: []byte(test.input), + label: aggregate, + } + + assert.True(t, tokenizer.ProcessAndContinue(context)) + assert.Equal(t, test.shouldStop, samples.ProcessAndContinue(context), "Expected stop %v, got %v", test.shouldStop, samples.ProcessAndContinue(context)) + assert.Equal(t, test.expectedLabel, context.label, "Expected label %v, got %v", test.expectedLabel, context.label) + } +} + +func TestUserPatternsProcessCustomSettings(t *testing.T) { + + datadogYaml := ` +logs_config: + auto_multi_line_detection_custom_samples: + - sample: "!!![$my custom prefix%]" + match_threshold: 0.1 + label: no_aggregate +` + + mockConfig := pkgconfigsetup.ConfFromYAML(datadogYaml) + samples := NewUserSamples(mockConfig) + tokenizer := NewTokenizer(60) + + tests := []struct { + expectedLabel Label + shouldStop bool + input string + }{ + {aggregate, true, ""}, + {aggregate, true, "some random log line"}, + {aggregate, true, "2023-03-28T14:33:53.743350Z App started successfully"}, + {noAggregate, false, "!!![$my custom prefix%] some other log line"}, + {noAggregate, false, "!!![$my slight variation%] some other log line"}, + {noAggregate, false, "!!![$Not_close_enough%] some other log line"}, // Now this case works with a lower match threshold + } + + for _, test := range tests { + context := &messageContext{ + rawMessage: []byte(test.input), + label: aggregate, + } + + assert.True(t, tokenizer.ProcessAndContinue(context)) + assert.Equal(t, test.shouldStop, samples.ProcessAndContinue(context), "Expected stop %v, got %v", test.shouldStop, samples.ProcessAndContinue(context)) + assert.Equal(t, test.expectedLabel, context.label, "Expected label %v, got %v", test.expectedLabel, context.label) + } +} diff --git a/pkg/logs/internal/decoder/auto_multiline_handler.go b/pkg/logs/internal/decoder/auto_multiline_handler.go index f3e5a84b2e858..fa694f97dcf17 100644 --- a/pkg/logs/internal/decoder/auto_multiline_handler.go +++ b/pkg/logs/internal/decoder/auto_multiline_handler.go @@ -8,6 +8,7 @@ package decoder import ( "time" + "github.com/DataDog/datadog-agent/pkg/config" automultilinedetection "github.com/DataDog/datadog-agent/pkg/logs/internal/decoder/auto_multiline_detection" "github.com/DataDog/datadog-agent/pkg/logs/message" ) @@ -24,12 +25,23 @@ func NewAutoMultilineHandler(outputFn func(m *message.Message), maxContentSize i // Order is important heuristics := []automultilinedetection.Heuristic{ automultilinedetection.NewJSONDetector(), - automultilinedetection.NewTokenizer(40), // TODO: (brian) this will be configruable in a future change. + automultilinedetection.NewTokenizer(config.Datadog().GetInt("logs_config.auto_multi_line.tokenizer_max_input_bytes")), + automultilinedetection.NewUserSamples(config.Datadog()), + automultilinedetection.NewTimestampDetector(config.Datadog().GetFloat64("logs_config.auto_multi_line.timestamp_detector_match_threshold")), + automultilinedetection.NewPatternTable( + config.Datadog().GetInt("logs_config.auto_multi_line.pattern_table_max_size"), + config.Datadog().GetFloat64("logs_config.auto_multi_line.pattern_table_match_threshold"), + ), } return &AutoMultilineHandler{ - labeler: automultilinedetection.NewLabeler(heuristics), - aggregator: automultilinedetection.NewAggregator(outputFn, maxContentSize, flushTimeout), + labeler: automultilinedetection.NewLabeler(heuristics), + aggregator: automultilinedetection.NewAggregator( + outputFn, + maxContentSize, + flushTimeout, + config.Datadog().GetBool("logs_config.tag_truncated_logs"), + config.Datadog().GetBool("logs_config.tag_auto_multi_line_logs")), } } diff --git a/pkg/logs/internal/decoder/legacy_auto_multiline_handler.go b/pkg/logs/internal/decoder/legacy_auto_multiline_handler.go index 61d9011103463..8e7b0a1321764 100644 --- a/pkg/logs/internal/decoder/legacy_auto_multiline_handler.go +++ b/pkg/logs/internal/decoder/legacy_auto_multiline_handler.go @@ -185,7 +185,7 @@ func (h *LegacyAutoMultilineHandler) processAndTry(message *message.Message) { if matchRatio >= h.matchThreshold { h.autoMultiLineStatus.SetMessage("state", "State: Using multi-line handler") h.autoMultiLineStatus.SetMessage("message", fmt.Sprintf("Pattern %v matched %d lines with a ratio of %f", topMatch.regexp.String(), topMatch.score, matchRatio)) - log.Debug(fmt.Sprintf("Pattern %v matched %d lines with a ratio of %f - using multi-line handler", topMatch.regexp.String(), topMatch.score, matchRatio)) + log.Debugf("Pattern %v matched %d lines with a ratio of %f - using multi-line handler", topMatch.regexp.String(), topMatch.score, matchRatio) telemetry.GetStatsTelemetryProvider().Count(autoMultiLineTelemetryMetricName, 1, []string{"success:true"}) h.detectedPattern.Set(topMatch.regexp) @@ -193,7 +193,7 @@ func (h *LegacyAutoMultilineHandler) processAndTry(message *message.Message) { } else { h.autoMultiLineStatus.SetMessage("state", "State: Using single-line handler") h.autoMultiLineStatus.SetMessage("message", fmt.Sprintf("No pattern met the line match threshold: %f during multiline auto detection. Top match was %v with a match ratio of: %f", h.matchThreshold, topMatch.regexp.String(), matchRatio)) - log.Debugf(fmt.Sprintf("No pattern met the line match threshold: %f during multiline auto detection. Top match was %v with a match ratio of: %f - using single-line handler", h.matchThreshold, topMatch.regexp.String(), matchRatio)) + log.Debugf("No pattern met the line match threshold: %f during multiline auto detection. Top match was %v with a match ratio of: %f - using single-line handler", h.matchThreshold, topMatch.regexp.String(), matchRatio) telemetry.GetStatsTelemetryProvider().Count(autoMultiLineTelemetryMetricName, 1, []string{"success:false"}) // Stay with the single line handler and no longer attempt to detect multiline matches. diff --git a/pkg/logs/internal/decoder/line_handler_test.go b/pkg/logs/internal/decoder/line_handler_test.go index e7de9ba2fb9fb..24584506dfa9d 100644 --- a/pkg/logs/internal/decoder/line_handler_test.go +++ b/pkg/logs/internal/decoder/line_handler_test.go @@ -128,6 +128,7 @@ func TestMultiLineHandler(t *testing.T) { output = <-outputChan assert.Equal(t, "3. stringssssssize20...TRUNCATED...", string(output.GetContent())) + assert.True(t, output.ParsingExtra.IsTruncated) assert.Equal(t, len("3. stringssssssize20"), output.RawDataLen) assertNothingInChannel(t, outputChan) @@ -135,6 +136,7 @@ func TestMultiLineHandler(t *testing.T) { output = <-outputChan assert.Equal(t, "...TRUNCATED...con", string(output.GetContent())) + assert.True(t, output.ParsingExtra.IsTruncated) assert.Equal(t, 4, output.RawDataLen) // second line + TRUNCATED too long @@ -143,10 +145,12 @@ func TestMultiLineHandler(t *testing.T) { output = <-outputChan assert.Equal(t, "4. stringssssssize20...TRUNCATED...", string(output.GetContent())) + assert.True(t, output.ParsingExtra.IsTruncated) assert.Equal(t, len("4. stringssssssize20"), output.RawDataLen) output = <-outputChan assert.Equal(t, "...TRUNCATED...continue...TRUNCATED...", string(output.GetContent())) + assert.True(t, output.ParsingExtra.IsTruncated) assert.Equal(t, 9, output.RawDataLen) // continuous too long lines @@ -159,14 +163,17 @@ func TestMultiLineHandler(t *testing.T) { output = <-outputChan assert.Equal(t, "5. stringssssssize20...TRUNCATED...", string(output.GetContent())) + assert.True(t, output.ParsingExtra.IsTruncated) assert.Equal(t, len("5. stringssssssize20"), output.RawDataLen) output = <-outputChan assert.Equal(t, "...TRUNCATED...continu ...TRUNCATED...", string(output.GetContent())) + assert.True(t, output.ParsingExtra.IsTruncated) assert.Equal(t, len(longLineTracingSpaces), output.RawDataLen) output = <-outputChan assert.Equal(t, "...TRUNCATED...end", string(output.GetContent())) + assert.True(t, output.ParsingExtra.IsTruncated) assert.Equal(t, len("end\n"), output.RawDataLen) assertNothingInChannel(t, outputChan) diff --git a/pkg/logs/internal/decoder/multiline_handler.go b/pkg/logs/internal/decoder/multiline_handler.go index dc36002561215..5fdeb2a80ce3f 100644 --- a/pkg/logs/internal/decoder/multiline_handler.go +++ b/pkg/logs/internal/decoder/multiline_handler.go @@ -10,6 +10,7 @@ import ( "regexp" "time" + coreConfig "github.com/DataDog/datadog-agent/pkg/config" "github.com/DataDog/datadog-agent/pkg/logs/message" status "github.com/DataDog/datadog-agent/pkg/logs/status/utils" "github.com/DataDog/datadog-agent/pkg/telemetry" @@ -29,6 +30,7 @@ type MultiLineHandler struct { flushTimer *time.Timer lineLimit int shouldTruncate bool + isBufferTruncated bool linesLen int status string timestamp string @@ -111,6 +113,7 @@ func (h *MultiLineHandler) process(msg *message.Message) { // the new line is just a remainder, // adding the truncated flag at the beginning of the content h.buffer.Write(message.TruncatedFlag) + h.isBufferTruncated = true } h.buffer.Write(msg.GetContent()) @@ -119,6 +122,7 @@ func (h *MultiLineHandler) process(msg *message.Message) { // the multiline message is too long, it needs to be cut off and send, // adding the truncated flag the end of the content h.buffer.Write(message.TruncatedFlag) + h.isBufferTruncated = true h.sendBuffer() h.shouldTruncate = true } @@ -141,6 +145,7 @@ func (h *MultiLineHandler) sendBuffer() { h.linesLen = 0 h.linesCombined = 0 h.shouldTruncate = false + h.isBufferTruncated = false }() data := bytes.TrimSpace(h.buffer.Bytes()) @@ -156,7 +161,11 @@ func (h *MultiLineHandler) sendBuffer() { telemetry.GetStatsTelemetryProvider().Count(linesCombinedTelemetryMetricName, float64(linesCombined), []string{}) } } - - h.outputFn(message.NewRawMessage(content, h.status, h.linesLen, h.timestamp)) + msg := message.NewRawMessage(content, h.status, h.linesLen, h.timestamp) + msg.ParsingExtra.IsTruncated = h.isBufferTruncated + if h.isBufferTruncated && coreConfig.Datadog().GetBool("logs_config.tag_truncated_logs") { + msg.ParsingExtra.Tags = append(msg.ParsingExtra.Tags, message.TruncatedTag) + } + h.outputFn(msg) } } diff --git a/pkg/logs/internal/decoder/single_line_handler.go b/pkg/logs/internal/decoder/single_line_handler.go index e3192474fe04e..4f2b192561c24 100644 --- a/pkg/logs/internal/decoder/single_line_handler.go +++ b/pkg/logs/internal/decoder/single_line_handler.go @@ -9,6 +9,7 @@ import ( "bytes" "time" + coreConfig "github.com/DataDog/datadog-agent/pkg/config" "github.com/DataDog/datadog-agent/pkg/logs/message" ) @@ -36,6 +37,12 @@ func (h *SingleLineHandler) flush() { // do nothing } +func addTruncatedTag(msg *message.Message) { + if coreConfig.Datadog().GetBool("logs_config.tag_truncated_logs") { + msg.ParsingExtra.Tags = append(msg.ParsingExtra.Tags, message.TruncatedTag) + } +} + // process transforms a raw line into a structured line, // it guarantees that the content of the line won't exceed // the limit and that the length of the line is properly tracked @@ -52,6 +59,7 @@ func (h *SingleLineHandler) process(msg *message.Message) { // the new line is just a remainder, // adding the truncated flag at the beginning of the content content = append(message.TruncatedFlag, content...) + addTruncatedTag(msg) } // how should we detect logs which are too long before rendering them? @@ -63,6 +71,7 @@ func (h *SingleLineHandler) process(msg *message.Message) { // adding the truncated flag the end of the content content = append(content, message.TruncatedFlag...) msg.SetContent(content) // refresh the content in the message + addTruncatedTag(msg) h.outputFn(msg) // make sure the following part of the line will be cut off as well h.shouldTruncate = true diff --git a/pkg/logs/internal/util/adlistener/ad_test.go b/pkg/logs/internal/util/adlistener/ad_test.go index 3966cd37d9f2d..a0a23b62ea7b2 100644 --- a/pkg/logs/internal/util/adlistener/ad_test.go +++ b/pkg/logs/internal/util/adlistener/ad_test.go @@ -28,8 +28,7 @@ func TestListenersGetScheduleCalls(t *testing.T) { ac := fxutil.Test[autodiscovery.Mock](t, fx.Supply(autodiscoveryimpl.MockParams{Scheduler: adsched}), autodiscoveryimpl.MockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), core.MockBundle(), fx.Provide(taggerimpl.NewMock), fx.Supply(tagger.NewFakeTaggerParams()), diff --git a/pkg/logs/internal/util/containersorpods/containers_or_pods.go b/pkg/logs/internal/util/containersorpods/containers_or_pods.go index 4a80c1713faa9..4ee689bff2768 100644 --- a/pkg/logs/internal/util/containersorpods/containers_or_pods.go +++ b/pkg/logs/internal/util/containersorpods/containers_or_pods.go @@ -12,6 +12,7 @@ import ( "time" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/log" ) @@ -167,11 +168,11 @@ func (ch *chooser) preferred() LogWhat { // LogContainers, sending the result to ch.choice. If wait is true, then if no // choice is available yet, it will wait until a choice becomes available. func (ch *chooser) choose(wait bool) { - c := config.IsFeaturePresent(config.Docker) || - config.IsFeaturePresent(config.Containerd) || - config.IsFeaturePresent(config.Cri) || - config.IsFeaturePresent(config.Podman) - k := config.IsFeaturePresent(config.Kubernetes) + c := env.IsFeaturePresent(env.Docker) || + env.IsFeaturePresent(env.Containerd) || + env.IsFeaturePresent(env.Cri) || + env.IsFeaturePresent(env.Podman) + k := env.IsFeaturePresent(env.Kubernetes) makeChoice := func(logWhat LogWhat) { log.Debugf("LogWhat = %s", logWhat.String()) diff --git a/pkg/logs/internal/util/containersorpods/containers_or_pods_test.go b/pkg/logs/internal/util/containersorpods/containers_or_pods_test.go index fc29a3a95941b..5039a6fc4d2b9 100644 --- a/pkg/logs/internal/util/containersorpods/containers_or_pods_test.go +++ b/pkg/logs/internal/util/containersorpods/containers_or_pods_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" configmock "github.com/DataDog/datadog-agent/pkg/config/mock" ) @@ -22,7 +23,7 @@ const ( func TestChoose(t *testing.T) { test := func( - features []config.Feature, + features []env.Feature, k8sContainerUseFile bool, ready int, expected LogWhat, @@ -54,37 +55,37 @@ func TestChoose(t *testing.T) { // return LogContainers t.Run("docker ready, only docker enabled", - test([]config.Feature{config.Docker}, false, dockerReadyBit, LogContainers)) + test([]env.Feature{env.Docker}, false, dockerReadyBit, LogContainers)) t.Run("docker not ready, only docker enabled", - test([]config.Feature{config.Docker}, false, 0, LogUnknown)) + test([]env.Feature{env.Docker}, false, 0, LogUnknown)) t.Run("docker ready, only containerd enabled", - test([]config.Feature{config.Containerd}, false, dockerReadyBit, LogContainers)) + test([]env.Feature{env.Containerd}, false, dockerReadyBit, LogContainers)) t.Run("docker not ready, only containerd enabled", - test([]config.Feature{config.Containerd}, false, 0, LogUnknown)) + test([]env.Feature{env.Containerd}, false, 0, LogUnknown)) t.Run("docker ready, only CRI enabled", - test([]config.Feature{config.Cri}, false, dockerReadyBit, LogContainers)) + test([]env.Feature{env.Cri}, false, dockerReadyBit, LogContainers)) t.Run("docker not ready, only CRI enabled", - test([]config.Feature{config.Cri}, false, 0, LogUnknown)) + test([]env.Feature{env.Cri}, false, 0, LogUnknown)) t.Run("docker ready, only Podman enabled", - test([]config.Feature{config.Podman}, false, dockerReadyBit, LogContainers)) + test([]env.Feature{env.Podman}, false, dockerReadyBit, LogContainers)) t.Run("docker not ready, only Podman enabled", - test([]config.Feature{config.Podman}, false, 0, LogUnknown)) + test([]env.Feature{env.Podman}, false, 0, LogUnknown)) // - if the kubernetes feature is available and no container features are // available, wait for the kubelet service to start, and return LogPods t.Run("k8s ready, only k8s enabled", - test([]config.Feature{config.Kubernetes}, false, kubernetesReadyBit, LogPods)) + test([]env.Feature{env.Kubernetes}, false, kubernetesReadyBit, LogPods)) t.Run("k8s not ready, only k8s enabled", - test([]config.Feature{config.Kubernetes}, false, 0, LogUnknown)) + test([]env.Feature{env.Kubernetes}, false, 0, LogUnknown)) // - if none of the features are available, LogNothing @@ -98,23 +99,23 @@ func TestChoose(t *testing.T) { // LogContainers if the configuration setting is false. t.Run("nothing ready, docker and kubernetes enabled", - test([]config.Feature{config.Docker, config.Kubernetes}, false, 0, LogUnknown)) + test([]env.Feature{env.Docker, env.Kubernetes}, false, 0, LogUnknown)) t.Run("k8s ready, docker and kubernetes enabled", - test([]config.Feature{config.Docker, config.Kubernetes}, false, kubernetesReadyBit, LogPods)) + test([]env.Feature{env.Docker, env.Kubernetes}, false, kubernetesReadyBit, LogPods)) t.Run("docker ready, docker and kubernetes enabled", - test([]config.Feature{config.Docker, config.Kubernetes}, false, dockerReadyBit, LogContainers)) + test([]env.Feature{env.Docker, env.Kubernetes}, false, dockerReadyBit, LogContainers)) t.Run("docker ready, Containerd and kubernetes enabled", - test([]config.Feature{config.Docker, config.Kubernetes}, false, dockerReadyBit, LogContainers)) + test([]env.Feature{env.Docker, env.Kubernetes}, false, dockerReadyBit, LogContainers)) t.Run("both ready, docker and kubernetes enabled, k8s_container_use_file=true", - test([]config.Feature{config.Docker, config.Kubernetes}, true, dockerReadyBit|kubernetesReadyBit, LogPods)) + test([]env.Feature{env.Docker, env.Kubernetes}, true, dockerReadyBit|kubernetesReadyBit, LogPods)) t.Run("both ready, docker and kubernetes enabled, k8s_container_use_file=false", - test([]config.Feature{config.Docker, config.Kubernetes}, false, dockerReadyBit|kubernetesReadyBit, LogContainers)) + test([]env.Feature{env.Docker, env.Kubernetes}, false, dockerReadyBit|kubernetesReadyBit, LogContainers)) t.Run("both ready, Containerds and kubernetes enabled, k8s_container_use_file=false", - test([]config.Feature{config.Docker, config.Kubernetes}, false, dockerReadyBit|kubernetesReadyBit, LogContainers)) + test([]env.Feature{env.Docker, env.Kubernetes}, false, dockerReadyBit|kubernetesReadyBit, LogContainers)) } diff --git a/pkg/logs/launchers/container/tailerfactory/file_test.go b/pkg/logs/launchers/container/tailerfactory/file_test.go index cc336dc04a41e..b98f9102c7308 100644 --- a/pkg/logs/launchers/container/tailerfactory/file_test.go +++ b/pkg/logs/launchers/container/tailerfactory/file_test.go @@ -247,8 +247,7 @@ func TestMakeK8sSource(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), compConfig.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) pod, container := makeTestPod() store.Set(pod) @@ -304,8 +303,7 @@ func TestMakeK8sSource_pod_not_found(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), compConfig.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) tf := &factory{ diff --git a/pkg/logs/launchers/file/launcher.go b/pkg/logs/launchers/file/launcher.go index a2c248050547a..3eef1ab04f637 100644 --- a/pkg/logs/launchers/file/launcher.go +++ b/pkg/logs/launchers/file/launcher.go @@ -277,6 +277,10 @@ func (s *Launcher) launchTailers(source *sources.LogSource) { if s.tailers.Count() >= s.tailingLimit { return } + + if fileprovider.ShouldIgnore(s.validatePodContainerID, file) { + continue + } if tailer, isTailed := s.tailers.Get(file.GetScanKey()); isTailed { // the file is already tailed, update the existing tailer's source so that the tailer // uses this new source going forward diff --git a/pkg/logs/launchers/file/provider/file_provider.go b/pkg/logs/launchers/file/provider/file_provider.go index 2271e933e878f..545098dd8866b 100644 --- a/pkg/logs/launchers/file/provider/file_provider.go +++ b/pkg/logs/launchers/file/provider/file_provider.go @@ -132,7 +132,7 @@ func (p *FileProvider) addFilesToTailList(validatePodContainerID bool, inputFile // Add each file one by one up to the limit for j := 0; j < len(inputFiles) && len(filesToTail) < p.filesLimit; j++ { file := inputFiles[j] - if shouldIgnore(validatePodContainerID, file) { + if ShouldIgnore(validatePodContainerID, file) { continue } filesToTail = append(filesToTail, file) @@ -348,7 +348,7 @@ func (p *FileProvider) applyOrdering(files []*tailer.File) { } } -// shouldIgnore resolves symlinks in /var/log/containers in order to use that redirection +// ShouldIgnore resolves symlinks in /var/log/containers in order to use that redirection // to validate that we will be reading a file for the correct container. // // We have to make sure that the file we just detected is tagged with the correct @@ -361,7 +361,7 @@ func (p *FileProvider) applyOrdering(files []*tailer.File) { // See these links for more info: // - https://github.com/kubernetes/kubernetes/issues/58638 // - https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter/issues/105 -func shouldIgnore(validatePodContainerID bool, file *tailer.File) bool { +func ShouldIgnore(validatePodContainerID bool, file *tailer.File) bool { // this method needs a source config to detect whether we should ignore that file or not if file == nil || file.Source == nil || file.Source.Config() == nil { return false diff --git a/pkg/logs/launchers/file/provider/file_provider_test.go b/pkg/logs/launchers/file/provider/file_provider_test.go index 8694e64eac757..efa0ad125901d 100644 --- a/pkg/logs/launchers/file/provider/file_provider_test.go +++ b/pkg/logs/launchers/file/provider/file_provider_test.go @@ -679,21 +679,21 @@ func TestContainerIDInContainerLogFile(t *testing.T) { } // we've found a symlink validating that the file we have just scanned is concerning the container we're currently processing for this source - assert.False(shouldIgnore(true, &file), "the file existing in ContainersLogsDir is pointing to the same container, scanned file should be tailed") + assert.False(ShouldIgnore(true, &file), "the file existing in ContainersLogsDir is pointing to the same container, scanned file should be tailed") // now, let's change the container for which we are trying to scan files, // because the symlink is pointing from another container, we should ignore // that log file file.Source.Config().Identifier = "1234123412341234123412341234123412341234123412341234123412341234" - assert.True(shouldIgnore(true, &file), "the file existing in ContainersLogsDir is not pointing to the same container, scanned file should be ignored") + assert.True(ShouldIgnore(true, &file), "the file existing in ContainersLogsDir is not pointing to the same container, scanned file should be ignored") // in this scenario, no link is found in /var/log/containers, thus, we should not ignore the file os.Remove("/tmp/myapp_my-namespace_myapp-abcdefabcdefabcdabcdefabcdefabcdabcdefabcdefabcdabcdefabcdefabcd.log") - assert.False(shouldIgnore(true, &file), "no files existing in ContainersLogsDir, we should not ignore the file we have just scanned") + assert.False(ShouldIgnore(true, &file), "no files existing in ContainersLogsDir, we should not ignore the file we have just scanned") // in this scenario, the file we've found doesn't look like a container ID os.Symlink("/var/log/pods/file-uuid-foo-bar.log", "/tmp/myapp_my-namespace_myapp-thisisnotacontainerIDevenifthisispointingtothecorrectfile.log") - assert.False(shouldIgnore(true, &file), "no container ID found, we don't want to ignore this scanned file") + assert.False(ShouldIgnore(true, &file), "no container ID found, we don't want to ignore this scanned file") } func TestContainerPathsAreCorrectlyIgnored(t *testing.T) { diff --git a/pkg/logs/launchers/integration/launcher.go b/pkg/logs/launchers/integration/launcher.go index 42badeabadbd9..1d8a9b15f2079 100644 --- a/pkg/logs/launchers/integration/launcher.go +++ b/pkg/logs/launchers/integration/launcher.go @@ -8,6 +8,7 @@ package integration import ( "os" + "path/filepath" "strings" ddLog "github.com/DataDog/datadog-agent/pkg/util/log" @@ -18,40 +19,50 @@ import ( "github.com/DataDog/datadog-agent/pkg/logs/auditor" "github.com/DataDog/datadog-agent/pkg/logs/launchers" "github.com/DataDog/datadog-agent/pkg/logs/pipeline" + "github.com/DataDog/datadog-agent/pkg/logs/schedulers/ad" "github.com/DataDog/datadog-agent/pkg/logs/sources" "github.com/DataDog/datadog-agent/pkg/logs/tailers" ) +var endOfLine = []byte{'\n'} + // Launcher checks for launcher integrations, creates files for integrations to // write logs to, then creates file sources for the file launcher to tail type Launcher struct { sources *sources.LogSources - addedSources chan *sources.LogSource + addedConfigs chan integrations.IntegrationConfig stop chan struct{} runPath string integrationsLogsChan chan integrations.IntegrationLog integrationToFile map[string]string - // writeLogToFile is used as a function pointer so it can be overridden in + // writeLogToFile is used as a function pointer, so it can be overridden in // testing to make deterministic tests - writeFunction func(filepath, log string) error + writeFunction func(logFilePath, log string) error } -// NewLauncher returns a new launcher +// NewLauncher creates and returns an integrations launcher, and creates the +// path for integrations files to run in func NewLauncher(sources *sources.LogSources, integrationsLogsComp integrations.Component) *Launcher { + runPath := filepath.Join(pkgConfig.Datadog().GetString("logs_config.run_path"), "integrations") + err := os.MkdirAll(runPath, 0755) + if err != nil { + ddLog.Warn("Unable to make integrations logs directory: ", err) + return nil + } + return &Launcher{ sources: sources, - runPath: pkgConfig.Datadog().GetString("logs_config.run_path"), + runPath: runPath, stop: make(chan struct{}), integrationsLogsChan: integrationsLogsComp.Subscribe(), + addedConfigs: integrationsLogsComp.SubscribeIntegration(), integrationToFile: make(map[string]string), writeFunction: writeLogToFile, } } // Start starts the launcher and launches the run loop in a go function -func (s *Launcher) Start(sourceProvider launchers.SourceProvider, _ pipeline.Provider, _ auditor.Registry, _ *tailers.TailerTracker) { - s.addedSources, _ = sourceProvider.SubscribeForType(config.IntegrationType) - +func (s *Launcher) Start(_ launchers.SourceProvider, _ pipeline.Provider, _ auditor.Registry, _ *tailers.TailerTracker) { go s.run() } @@ -64,33 +75,39 @@ func (s *Launcher) Stop() { func (s *Launcher) run() { for { select { - case source := <-s.addedSources: - // Send logs configurations to the file launcher to tail, it will handle - // tailer lifecycle, file rotation, etc. - filepath, err := s.createFile(source) + case cfg := <-s.addedConfigs: + sources, err := ad.CreateSources(cfg.Config) if err != nil { - ddLog.Warn("Failed to create integration log file: ", err) + ddLog.Warn("Failed to create source ", err) continue } - filetypeSource := s.makeFileSource(source, filepath) - s.sources.AddSource(filetypeSource) + for _, source := range sources { + // TODO: integrations should only be allowed to have one IntegrationType config. + if source.Config.Type == config.IntegrationType { + logFilePath, err := s.createFile(cfg.IntegrationID) + if err != nil { + ddLog.Warn("Failed to create integration log file: ", err) + continue + } + filetypeSource := s.makeFileSource(source, logFilePath) + s.sources.AddSource(filetypeSource) + + // file to write the incoming logs to + s.integrationToFile[cfg.IntegrationID] = logFilePath + } + } - // file to write the incoming logs to - s.integrationToFile[source.Name] = filepath case log := <-s.integrationsLogsChan: - // Integrations will come in the form of: check_name:instance_config_hash - integrationSplit := strings.Split(log.IntegrationID, ":") - integrationName := integrationSplit[0] - filepath := s.integrationToFile[integrationName] + logFilePath := s.integrationToFile[log.IntegrationID] - err := s.ensureFileSize(filepath) + err := s.ensureFileSize(logFilePath) if err != nil { ddLog.Warn("Failed to get file size: ", err) continue } - err = s.writeFunction(filepath, log.Log) + err = s.writeFunction(logFilePath, log.Log) if err != nil { ddLog.Warn("Error writing log to file: ", err) } @@ -101,8 +118,8 @@ func (s *Launcher) run() { } // writeLogToFile is used as a function pointer -func writeLogToFile(filepath, log string) error { - file, err := os.OpenFile(filepath, os.O_WRONLY, 0644) +func writeLogToFile(logFilePath, log string) error { + file, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) if err != nil { ddLog.Warn("Failed to open file to write log to: ", err) return err @@ -115,18 +132,22 @@ func writeLogToFile(filepath, log string) error { ddLog.Warn("Failed to write integration log to file: ", err) return err } - + if _, err = file.Write(endOfLine); err != nil { + ddLog.Warn("Failed to write integration log to file: ", err) + return err + } return nil } // makeFileSource Turns an integrations source into a logsSource -func (s *Launcher) makeFileSource(source *sources.LogSource, filepath string) *sources.LogSource { +func (s *Launcher) makeFileSource(source *sources.LogSource, logFilePath string) *sources.LogSource { fileSource := sources.NewLogSource(source.Name, &config.LogsConfig{ Type: config.FileType, TailingMode: source.Config.TailingMode, - Path: filepath, + Path: logFilePath, Name: source.Config.Name, Source: source.Config.Source, + Service: source.Config.Service, Tags: source.Config.Tags, }) @@ -136,46 +157,40 @@ func (s *Launcher) makeFileSource(source *sources.LogSource, filepath string) *s // TODO Change file naming to reflect ID once logs from go interfaces gets merged. // createFile creates a file for the logsource -func (s *Launcher) createFile(source *sources.LogSource) (string, error) { - directory, filepath := s.integrationLogFilePath(*source) - - err := os.MkdirAll(directory, 0755) - if err != nil { - return "", err - } +func (s *Launcher) createFile(id string) (string, error) { + logFilePath := s.integrationLogFilePath(id) - file, err := os.Create(filepath) + file, err := os.Create(logFilePath) if err != nil { return "", nil } defer file.Close() - return filepath, nil + return logFilePath, nil } -// integrationLogFilePath returns a directory and file to use for an integration log file -func (s *Launcher) integrationLogFilePath(source sources.LogSource) (string, string) { - fileName := source.Config.Name + ".log" - directoryComponents := []string{s.runPath, "integrations", source.Config.Service} - directory := strings.Join(directoryComponents, "/") - filepath := strings.Join([]string{directory, fileName}, "/") +// integrationLoglogFilePath returns a file path to use for an integration log file +func (s *Launcher) integrationLogFilePath(id string) string { + fileName := strings.ReplaceAll(id, " ", "-") + fileName = strings.ReplaceAll(fileName, ":", "_") + ".log" + logFilePath := filepath.Join(s.runPath, fileName) - return directory, filepath + return logFilePath } // ensureFileSize enforces the max file size for files integrations logs // files. Files over the set size will be deleted and remade. -func (s *Launcher) ensureFileSize(filepath string) error { +func (s *Launcher) ensureFileSize(logFilePath string) error { maxFileSizeSetting := pkgConfig.Datadog().GetInt64("logs_config.integrations_logs_files_max_size") maxFileSizeBytes := maxFileSizeSetting * 1024 * 1024 - fi, err := os.Stat(filepath) + fi, err := os.Stat(logFilePath) if err != nil { return err } if fi.Size() > int64(maxFileSizeBytes) { - err := os.Remove(filepath) + err := os.Remove(logFilePath) if err != nil { if os.IsNotExist(err) { ddLog.Warn("File does not exist, creating new one: ", err) @@ -186,7 +201,7 @@ func (s *Launcher) ensureFileSize(filepath string) error { ddLog.Info("Successfully deleted oversize log file, creating new one.") } - file, err := os.Create(filepath) + file, err := os.Create(logFilePath) if err != nil { return err } diff --git a/pkg/logs/launchers/integration/launcher_test.go b/pkg/logs/launchers/integration/launcher_test.go index 084575133ea98..1eef9c6eadf3e 100644 --- a/pkg/logs/launchers/integration/launcher_test.go +++ b/pkg/logs/launchers/integration/launcher_test.go @@ -6,34 +6,31 @@ package integration import ( - "fmt" "os" - "strings" + "path/filepath" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/comp/logs/agent/config" - "github.com/DataDog/datadog-agent/comp/logs/integrations/def" - integrationsMock "github.com/DataDog/datadog-agent/comp/logs/integrations/mock" + integrations "github.com/DataDog/datadog-agent/comp/logs/integrations/def" + integrationsmock "github.com/DataDog/datadog-agent/comp/logs/integrations/mock" pkgConfig "github.com/DataDog/datadog-agent/pkg/config" - auditor "github.com/DataDog/datadog-agent/pkg/logs/auditor/mock" "github.com/DataDog/datadog-agent/pkg/logs/internal/util" - "github.com/DataDog/datadog-agent/pkg/logs/launchers" "github.com/DataDog/datadog-agent/pkg/logs/message" "github.com/DataDog/datadog-agent/pkg/logs/pipeline" "github.com/DataDog/datadog-agent/pkg/logs/pipeline/mock" "github.com/DataDog/datadog-agent/pkg/logs/sources" "github.com/DataDog/datadog-agent/pkg/logs/status" - "github.com/DataDog/datadog-agent/pkg/logs/tailers" ) type LauncherTestSuite struct { suite.Suite testDir string testPath string - testFile *os.File outputChan chan *message.Message pipelineProvider pipeline.Provider @@ -45,90 +42,102 @@ type LauncherTestSuite struct { func (suite *LauncherTestSuite) SetupTest() { suite.pipelineProvider = mock.NewMockProvider() suite.outputChan = suite.pipelineProvider.NextPipelineChan() - suite.integrationsComp = integrationsMock.Mock() - - var err error + suite.integrationsComp = integrationsmock.Mock() suite.testDir = suite.T().TempDir() + suite.testPath = filepath.Join(suite.testDir, "logs_integration_test.log") - suite.testPath = fmt.Sprintf("%s/launcher.log", suite.testDir) + suite.source = sources.NewLogSource(suite.T().Name(), &config.LogsConfig{Type: config.IntegrationType, Path: suite.testPath}) - f, err := os.Create(suite.testPath) - suite.Nil(err) - suite.testFile = f + // Override `logs_config.run_path` before calling `sources.NewLogSources()` as otherwise + // it will try and create `/opt/datadog` directory and fail + pkgConfig.Datadog().SetWithoutSource("logs_config.run_path", suite.testDir) - suite.source = sources.NewLogSource("", &config.LogsConfig{Type: config.IntegrationType, Path: suite.testPath}) - suite.s = NewLauncher(nil, suite.integrationsComp) + suite.s = NewLauncher(sources.NewLogSources(), suite.integrationsComp) status.InitStatus(pkgConfig.Datadog(), util.CreateSources([]*sources.LogSource{suite.source})) suite.s.runPath = suite.testDir } -func (suite *LauncherTestSuite) TearDownTest() { - suite.testFile.Close() -} - func (suite *LauncherTestSuite) TestFileCreation() { + id := "123456789" source := sources.NewLogSource("testLogsSource", &config.LogsConfig{Type: config.IntegrationType, Identifier: "123456789", Path: suite.testPath}) sources.NewLogSources().AddSource(source) - filePath, err := suite.s.createFile(source) - assert.Nil(suite.T(), err) - assert.NotNil(suite.T(), filePath) + logFilePath, err := suite.s.createFile(id) + assert.NoError(suite.T(), err) + assert.NotNil(suite.T(), logFilePath) } func (suite *LauncherTestSuite) TestSendLog() { - logsSources := sources.NewLogSources() - suite.s.sources = logsSources - source := sources.NewLogSource("testLogsSource", &config.LogsConfig{Type: config.IntegrationType, Name: "integrationName", Path: suite.testPath}) + + mockConf := &integration.Config{} + mockConf.Provider = "container" + mockConf.LogsConfig = integration.Data(`[{"type": "integration", "source": "foo", "service": "bar"}]`) + filepathChan := make(chan string) fileLogChan := make(chan string) - suite.s.writeFunction = func(filepath, log string) error { + suite.s.writeFunction = func(logFilePath, log string) error { fileLogChan <- log - filepathChan <- filepath + filepathChan <- logFilePath return nil } - filepath, err := suite.s.createFile(source) - assert.Nil(suite.T(), err) - suite.s.integrationToFile[source.Name] = filepath - fileSource := suite.s.makeFileSource(source, filepath) - suite.s.sources.AddSource(fileSource) + id := "123456789" - suite.s.Start(launchers.NewMockSourceProvider(), suite.pipelineProvider, auditor.NewRegistry(), tailers.NewTailerTracker()) + suite.s.Start(nil, nil, nil, nil) + suite.integrationsComp.RegisterIntegration(id, *mockConf) logSample := "hello world" - suite.integrationsComp.SendLog(logSample, "testLogsSource:HASH1234") + suite.integrationsComp.SendLog(logSample, id) + + foundSource := suite.s.sources.GetSources()[0] + assert.Equal(suite.T(), foundSource.Config.Type, config.FileType) + assert.Equal(suite.T(), foundSource.Config.Source, "foo") + assert.Equal(suite.T(), foundSource.Config.Service, "bar") + expectedPath := suite.s.integrationToFile[id] assert.Equal(suite.T(), logSample, <-fileLogChan) - assert.Equal(suite.T(), filepath, <-filepathChan) + assert.Equal(suite.T(), expectedPath, <-filepathChan) } func (suite *LauncherTestSuite) TestWriteLogToFile() { logText := "hello world" - suite.s.writeFunction(suite.testPath, logText) + err := suite.s.writeFunction(suite.testPath, logText) + require.Nil(suite.T(), err) fileContents, err := os.ReadFile(suite.testPath) - assert.Nil(suite.T(), err) - assert.Equal(suite.T(), logText, string(fileContents)) + assert.NoError(suite.T(), err) + assert.Equal(suite.T(), logText+"\n", string(fileContents)) } -// TestIntegrationLogFilePath ensures the filepath for the logs files are correct -func (suite *LauncherTestSuite) TestIntegrationLogFilePath() { - logSource := sources.NewLogSource("testLogsSource", &config.LogsConfig{ - Type: config.IntegrationType, - Name: "test_name", - Service: "test_service", - Path: suite.testPath, - }) +func (suite *LauncherTestSuite) TestWriteMultipleLogsToFile() { + var err error + err = suite.s.writeFunction(suite.testPath, "line 1") + require.Nil(suite.T(), err, "error writing line 1") + + err = suite.s.writeFunction(suite.testPath, "line 2") + require.Nil(suite.T(), err, "error writing line 2") - actualDirectory, actualFilePath := suite.s.integrationLogFilePath(*logSource) + err = suite.s.writeFunction(suite.testPath, "line 3") + require.Nil(suite.T(), err, "error writing line 3") + + fileContents, err := os.ReadFile(suite.testPath) - expectedDirectoryComponents := []string{suite.s.runPath, "integrations", logSource.Config.Service} - expectedDirectory := strings.Join(expectedDirectoryComponents, "/") + assert.NoError(suite.T(), err) + expectedContent := "line 1\nline 2\nline 3\n" + assert.Equal(suite.T(), expectedContent, string(fileContents)) +} - expectedFilePath := strings.Join([]string{expectedDirectory, logSource.Config.Name + ".log"}, "/") +// TestIntegrationLogFilePath ensures the filepath for the logs files are correct +func (suite *LauncherTestSuite) TestIntegrationLogFilePath() { + id := "123456789" + actualFilePath := suite.s.integrationLogFilePath(id) + expectedFilePath := filepath.Join(suite.s.runPath, id+".log") + assert.Equal(suite.T(), expectedFilePath, actualFilePath) - assert.Equal(suite.T(), expectedDirectory, actualDirectory) + id = "1234 5678:myIntegration" + actualFilePath = suite.s.integrationLogFilePath(id) + expectedFilePath = filepath.Join(suite.s.runPath, "1234-5678_myIntegration.log") assert.Equal(suite.T(), expectedFilePath, actualFilePath) } diff --git a/pkg/logs/launchers/listener/tcp.go b/pkg/logs/launchers/listener/tcp.go index fa07e054b107d..9b7e61dad7c29 100644 --- a/pkg/logs/launchers/listener/tcp.go +++ b/pkg/logs/launchers/listener/tcp.go @@ -72,7 +72,9 @@ func (l *TCPListener) Stop() { l.mu.Lock() defer l.mu.Unlock() l.stop <- struct{}{} - l.listener.Close() + if l.listener != nil { + l.listener.Close() + } stopper := startstop.NewParallelStopper() for _, tailer := range l.tailers { stopper.Add(tailer) diff --git a/pkg/logs/launchers/listener/tcp_test.go b/pkg/logs/launchers/listener/tcp_test.go index 031369bab63f9..202d203b8174d 100644 --- a/pkg/logs/launchers/listener/tcp_test.go +++ b/pkg/logs/launchers/listener/tcp_test.go @@ -32,7 +32,7 @@ func TestTCPShouldReceivesMessages(t *testing.T) { defer conn.Close() var msg *message.Message - fmt.Fprintf(conn, "hello world\n") + fmt.Fprint(conn, "hello world\n") msg = <-msgChan assert.Equal(t, "hello world", string(msg.GetContent())) assert.Equal(t, 1, len(listener.tailers)) @@ -50,15 +50,15 @@ func TestTCPDoesNotTruncateMessagesThatAreBiggerThanTheReadBufferSize(t *testing assert.Nil(t, err) var msg *message.Message - fmt.Fprintf(conn, strings.Repeat("a", 80)+"\n") + fmt.Fprint(conn, strings.Repeat("a", 80)+"\n") msg = <-msgChan assert.Equal(t, strings.Repeat("a", 80), string(msg.GetContent())) - fmt.Fprintf(conn, strings.Repeat("a", 200)+"\n") + fmt.Fprint(conn, strings.Repeat("a", 200)+"\n") msg = <-msgChan assert.Equal(t, strings.Repeat("a", 200), string(msg.GetContent())) - fmt.Fprintf(conn, strings.Repeat("a", 70)+"\n") + fmt.Fprint(conn, strings.Repeat("a", 70)+"\n") msg = <-msgChan assert.Equal(t, strings.Repeat("a", 70), string(msg.GetContent())) diff --git a/pkg/logs/launchers/listener/udp_nix_test.go b/pkg/logs/launchers/listener/udp_nix_test.go index bce53e04fcfbc..7423ad918042d 100644 --- a/pkg/logs/launchers/listener/udp_nix_test.go +++ b/pkg/logs/launchers/listener/udp_nix_test.go @@ -47,7 +47,7 @@ func TestUDPShoulProperlyCollectLogSplitPerDatadgram(t *testing.T) { msg = <-msgChan assert.Equal(t, strings.Repeat("a", 10), string(msg.GetContent())) - fmt.Fprintf(conn, strings.Repeat("a", 10)+"\n"+strings.Repeat("a", 10)+"\n") + fmt.Fprint(conn, strings.Repeat("a", 10)+"\n"+strings.Repeat("a", 10)+"\n") msg = <-msgChan assert.Equal(t, strings.Repeat("a", 10), string(msg.GetContent())) msg = <-msgChan @@ -99,13 +99,13 @@ func TestUDPShoulDropTooBigMessages(t *testing.T) { var msg *message.Message - fmt.Fprintf(conn, strings.Repeat("a", maxUDPFrameLen-100)+"\n") + fmt.Fprint(conn, strings.Repeat("a", maxUDPFrameLen-100)+"\n") msg = <-msgChan assert.Equal(t, strings.Repeat("a", maxUDPFrameLen-100), string(msg.GetContent())) // the first frame should be dropped as it's too big compare to the limit. - fmt.Fprintf(conn, strings.Repeat("a", maxUDPFrameLen+100)+"\n") - fmt.Fprintf(conn, strings.Repeat("a", maxUDPFrameLen-200)+"\n") + fmt.Fprint(conn, strings.Repeat("a", maxUDPFrameLen+100)+"\n") + fmt.Fprint(conn, strings.Repeat("a", maxUDPFrameLen-200)+"\n") msg = <-msgChan assert.Equal(t, strings.Repeat("a", maxUDPFrameLen-200), string(msg.GetContent())) diff --git a/pkg/logs/launchers/listener/udp_test.go b/pkg/logs/launchers/listener/udp_test.go index 07a0db2ed3850..638574571548b 100644 --- a/pkg/logs/launchers/listener/udp_test.go +++ b/pkg/logs/launchers/listener/udp_test.go @@ -32,7 +32,7 @@ func TestUDPShouldReceiveMessage(t *testing.T) { var msg *message.Message - fmt.Fprintf(conn, "hello world\n") + fmt.Fprint(conn, "hello world\n") msg = <-msgChan assert.Equal(t, "hello world", string(msg.GetContent())) diff --git a/pkg/logs/message/go.mod b/pkg/logs/message/go.mod index 315978fc48ff4..9e25811e26e28 100644 --- a/pkg/logs/message/go.mod +++ b/pkg/logs/message/go.mod @@ -13,6 +13,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../comp/logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../config/utils @@ -87,12 +88,12 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/logs/message/go.sum b/pkg/logs/message/go.sum index 79c2fcb395d02..77ba213060c82 100644 --- a/pkg/logs/message/go.sum +++ b/pkg/logs/message/go.sum @@ -234,25 +234,25 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -295,11 +295,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -312,8 +312,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/logs/message/message.go b/pkg/logs/message/message.go index 9f7728f768601..bac1ade6202de 100644 --- a/pkg/logs/message/message.go +++ b/pkg/logs/message/message.go @@ -19,6 +19,12 @@ import ( // or/and at the end of every trucated lines. var TruncatedFlag = []byte("...TRUNCATED...") +// TruncatedTag is added to truncated log messages (if enabled). +const TruncatedTag = "truncated" + +// AutoMultiLineTag is added to multiline log messages (if enabled). +const AutoMultiLineTag = "auto_multiline" + // EscapedLineFeed is used to escape new line character // for multiline message. // New line character needs to be escaped because they are used @@ -46,8 +52,7 @@ type Message struct { IngestionTimestamp int64 // RawDataLen tracks the original size of the message content before any trimming/transformation. // This is used when calculating the tailer offset - so this will NOT always be equal to `len(Content)`. - RawDataLen int - IsMultiLine bool + RawDataLen int // Tags added on processing ProcessingTags []string // Extra information from the parsers @@ -166,9 +171,11 @@ func (m *MessageContent) SetEncoded(content []byte) { // E.g. Timestamp is used by the docker parsers to transmit a tailing offset. type ParsingExtra struct { // Used by docker parsers to transmit an offset. - Timestamp string - IsPartial bool - Tags []string + Timestamp string + IsPartial bool + IsTruncated bool + IsMultiLine bool + Tags []string } // ServerlessExtra ships extra information from logs processing in serverless envs. @@ -218,26 +225,9 @@ func NewRawMessage(content []byte, status string, rawDataLen int, readTimestamp RawDataLen: rawDataLen, IngestionTimestamp: time.Now().UnixNano(), ParsingExtra: ParsingExtra{ - Timestamp: readTimestamp, - }, - IsMultiLine: false, - } -} - -// NewRawMultiLineMessage returns a new encoded message. -func NewRawMultiLineMessage(content []byte, status string, rawDataLen int, readTimestamp string) *Message { - return &Message{ - MessageContent: MessageContent{ - content: content, - State: StateUnstructured, - }, - Status: status, - RawDataLen: rawDataLen, - IngestionTimestamp: time.Now().UnixNano(), - ParsingExtra: ParsingExtra{ - Timestamp: readTimestamp, + Timestamp: readTimestamp, + IsMultiLine: false, }, - IsMultiLine: true, } } diff --git a/pkg/logs/metrics/go.mod b/pkg/logs/metrics/go.mod index 6dd7c54ddc08c..5584710f490c2 100644 --- a/pkg/logs/metrics/go.mod +++ b/pkg/logs/metrics/go.mod @@ -42,11 +42,11 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.7.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.23.0 // indirect - golang.org/x/sys v0.23.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/sys v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/logs/metrics/go.sum b/pkg/logs/metrics/go.sum index a0165a70e28ad..3854bdf57a7da 100644 --- a/pkg/logs/metrics/go.sum +++ b/pkg/logs/metrics/go.sum @@ -1,5 +1,3 @@ -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -28,8 +26,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= @@ -65,19 +61,19 @@ go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5 go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/pkg/logs/metrics/metrics.go b/pkg/logs/metrics/metrics.go index 063a4e6afe075..2ba51621ece48 100644 --- a/pkg/logs/metrics/metrics.go +++ b/pkg/logs/metrics/metrics.go @@ -70,6 +70,9 @@ var ( DestinationHttpRespByStatusAndUrl = expvar.Map{} //nolint:revive // TODO(AML) Fix revive linter TlmDestinationHttpRespByStatusAndUrl = telemetry.NewCounter("logs", "destination_http_resp", []string{"status_code", "url"}, "Count of http responses by status code and destination url") + + // TlmLogsDiscardedFromSDSBuffer how many messages were dropped when waiting for an SDS configuration because the buffer is full + TlmLogsDiscardedFromSDSBuffer = telemetry.NewCounter("logs", "sds__dropped_from_buffer", nil, "Count of messages dropped from the buffer while waiting for an SDS configuration") ) func init() { diff --git a/pkg/logs/pipeline/go.mod b/pkg/logs/pipeline/go.mod index 9756b3ff5a8f9..4a1f156e04cae 100644 --- a/pkg/logs/pipeline/go.mod +++ b/pkg/logs/pipeline/go.mod @@ -15,6 +15,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../comp/logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../config/utils @@ -98,7 +99,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/system/socket v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/winutil v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/version v0.56.0-rc.3 // indirect - github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe // indirect + github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 // indirect github.com/DataDog/viper v1.13.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/benbjohnson/clock v1.3.5 // indirect @@ -145,17 +146,17 @@ require ( 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.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/pkg/logs/pipeline/go.sum b/pkg/logs/pipeline/go.sum index a57ca0d0a1d5a..6d9b20fb4b0fa 100644 --- a/pkg/logs/pipeline/go.sum +++ b/pkg/logs/pipeline/go.sum @@ -41,8 +41,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/agent-payload/v5 v5.0.106 h1:A3dGX+JYoL7OJe2crpxznW7hWxLxhOk/17WbYskRWVk= github.com/DataDog/agent-payload/v5 v5.0.106/go.mod h1:COngtbYYCncpIPiE5D93QlXDH/3VAKk10jDNwGHcMRE= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe h1:efzxujZ7VHWFxjmWjcJyUEpPrN8qdiZPYb+dBw547Wo= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 h1:RoH7VLzTnxHEugRPIgnGlxwDFszFGI7b3WZZUtWuPRM= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= github.com/DataDog/viper v1.13.5 h1:SZMcyMknYQN2jRY/40A16gUXexlNJOI8sDs1cWZnI64= github.com/DataDog/viper v1.13.5/go.mod h1:wDdUVJ2SHaMaPrCZrlRCObwkubsX8j5sme3LaR/SGTc= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -368,21 +368,21 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -401,8 +401,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -465,8 +465,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -534,8 +534,8 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -545,8 +545,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -604,8 +604,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/pkg/logs/pipeline/mock/mock.go b/pkg/logs/pipeline/mock/mock.go index 8e7c0bde6387d..3d07560754a79 100644 --- a/pkg/logs/pipeline/mock/mock.go +++ b/pkg/logs/pipeline/mock/mock.go @@ -31,11 +31,15 @@ func (p *mockProvider) Start() {} // Stop does nothing func (p *mockProvider) Stop() {} -func (p *mockProvider) ReconfigureSDSStandardRules(_ []byte) error { - return nil +func (p *mockProvider) ReconfigureSDSStandardRules(_ []byte) (bool, error) { + return false, nil +} + +func (p *mockProvider) ReconfigureSDSAgentConfig(_ []byte) (bool, error) { + return false, nil } -func (p *mockProvider) ReconfigureSDSAgentConfig(_ []byte) error { +func (p *mockProvider) StopSDSProcessing() error { return nil } diff --git a/pkg/logs/pipeline/pipeline.go b/pkg/logs/pipeline/pipeline.go index 096430526c091..0a050d38481ad 100644 --- a/pkg/logs/pipeline/pipeline.go +++ b/pkg/logs/pipeline/pipeline.go @@ -77,7 +77,9 @@ func NewPipeline(outputChan chan *message.Payload, logsSender = sender.NewSender(cfg, senderInput, outputChan, mainDestinations, config.DestinationPayloadChanSize, senderDoneChan, flushWg) inputChan := make(chan *message.Message, config.ChanSize) - processor := processor.New(inputChan, strategyInput, processingRules, encoder, diagnosticMessageReceiver, hostname, pipelineID) + + processor := processor.New(cfg, inputChan, strategyInput, processingRules, + encoder, diagnosticMessageReceiver, hostname, pipelineID) return &Pipeline{ InputChan: inputChan, diff --git a/pkg/logs/pipeline/provider.go b/pkg/logs/pipeline/provider.go index 04812a8aed123..54d3b947a1313 100644 --- a/pkg/logs/pipeline/provider.go +++ b/pkg/logs/pipeline/provider.go @@ -28,8 +28,9 @@ import ( type Provider interface { Start() Stop() - ReconfigureSDSStandardRules(standardRules []byte) error - ReconfigureSDSAgentConfig(config []byte) error + ReconfigureSDSStandardRules(standardRules []byte) (bool, error) + ReconfigureSDSAgentConfig(config []byte) (bool, error) + StopSDSProcessing() error NextPipelineChan() chan *message.Message // Flush flushes all pipeline contained in this Provider Flush(ctx context.Context) @@ -111,8 +112,9 @@ func (p *provider) Stop() { p.outputChan = nil } -func (p *provider) reconfigureSDS(config []byte, orderType sds.ReconfigureOrderType) error { - var responses []chan error +// return true if all processor SDS scanners are active. +func (p *provider) reconfigureSDS(config []byte, orderType sds.ReconfigureOrderType) (bool, error) { + var responses []chan sds.ReconfigureResponse // send a reconfiguration order to every running pipeline @@ -120,7 +122,7 @@ func (p *provider) reconfigureSDS(config []byte, orderType sds.ReconfigureOrderT order := sds.ReconfigureOrder{ Type: orderType, Config: config, - ResponseChan: make(chan error), + ResponseChan: make(chan sds.ReconfigureResponse), } responses = append(responses, order.ResponseChan) @@ -131,28 +133,43 @@ func (p *provider) reconfigureSDS(config []byte, orderType sds.ReconfigureOrderT // reports if at least one error occurred var rerr error + allScannersActive := true for _, response := range responses { - err := <-response - if err != nil { - rerr = multierror.Append(rerr, err) + resp := <-response + + if !resp.IsActive { + allScannersActive = false + } + + if resp.Err != nil { + rerr = multierror.Append(rerr, resp.Err) } + close(response) } - return rerr + return allScannersActive, rerr } // ReconfigureSDSStandardRules stores the SDS standard rules for the given provider. -func (p *provider) ReconfigureSDSStandardRules(standardRules []byte) error { +func (p *provider) ReconfigureSDSStandardRules(standardRules []byte) (bool, error) { return p.reconfigureSDS(standardRules, sds.StandardRules) } // ReconfigureSDSAgentConfig reconfigures the pipeline with the given // configuration received through Remote Configuration. -func (p *provider) ReconfigureSDSAgentConfig(config []byte) error { +// Return true if all SDS scanners are active after applying this configuration. +func (p *provider) ReconfigureSDSAgentConfig(config []byte) (bool, error) { return p.reconfigureSDS(config, sds.AgentConfig) } +// StopSDSProcessing reconfigures the pipeline removing the SDS scanning +// from the processing steps. +func (p *provider) StopSDSProcessing() error { + _, err := p.reconfigureSDS(nil, sds.StopProcessing) + return err +} + // NextPipelineChan returns the next pipeline input channel func (p *provider) NextPipelineChan() chan *message.Message { pipelinesLen := len(p.pipelines) diff --git a/pkg/logs/processor/go.mod b/pkg/logs/processor/go.mod index 4308509e56e8f..24e11c8274253 100644 --- a/pkg/logs/processor/go.mod +++ b/pkg/logs/processor/go.mod @@ -14,6 +14,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../comp/logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../config/utils @@ -46,6 +47,7 @@ require ( github.com/DataDog/agent-payload/v5 v5.0.106 github.com/DataDog/datadog-agent/comp/core/hostname/hostnameinterface v0.56.0-rc.3 github.com/DataDog/datadog-agent/comp/logs/agent/config v0.56.0-rc.3 + github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/logs/diagnostic v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/logs/message v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/logs/metrics v0.56.0-rc.3 @@ -61,7 +63,6 @@ require ( github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect - github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/setup v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/utils v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/logs/status/utils v0.56.0-rc.3 // indirect @@ -78,7 +79,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/system/socket v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/util/winutil v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/version v0.56.0-rc.3 // indirect - github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe // indirect + github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 // indirect github.com/DataDog/viper v1.13.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -124,16 +125,16 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/pkg/logs/processor/go.sum b/pkg/logs/processor/go.sum index a01e038731d76..24e2f0deda878 100644 --- a/pkg/logs/processor/go.sum +++ b/pkg/logs/processor/go.sum @@ -41,8 +41,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/agent-payload/v5 v5.0.106 h1:A3dGX+JYoL7OJe2crpxznW7hWxLxhOk/17WbYskRWVk= github.com/DataDog/agent-payload/v5 v5.0.106/go.mod h1:COngtbYYCncpIPiE5D93QlXDH/3VAKk10jDNwGHcMRE= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe h1:efzxujZ7VHWFxjmWjcJyUEpPrN8qdiZPYb+dBw547Wo= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 h1:RoH7VLzTnxHEugRPIgnGlxwDFszFGI7b3WZZUtWuPRM= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= github.com/DataDog/viper v1.13.5 h1:SZMcyMknYQN2jRY/40A16gUXexlNJOI8sDs1cWZnI64= github.com/DataDog/viper v1.13.5/go.mod h1:wDdUVJ2SHaMaPrCZrlRCObwkubsX8j5sme3LaR/SGTc= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -54,8 +54,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -364,21 +362,21 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -397,8 +395,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -528,8 +526,8 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -539,8 +537,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -598,8 +596,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/pkg/logs/processor/processor.go b/pkg/logs/processor/processor.go index 707e1874cd063..f66a8c0c48a4d 100644 --- a/pkg/logs/processor/processor.go +++ b/pkg/logs/processor/processor.go @@ -11,6 +11,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/hostname/hostnameinterface" "github.com/DataDog/datadog-agent/comp/logs/agent/config" + pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model" "github.com/DataDog/datadog-agent/pkg/logs/diagnostic" "github.com/DataDog/datadog-agent/pkg/logs/message" "github.com/DataDog/datadog-agent/pkg/logs/metrics" @@ -38,13 +39,29 @@ type Processor struct { mu sync.Mutex hostname hostnameinterface.Component - sds *sds.Scanner // configured through RC + sds sdsProcessor +} + +type sdsProcessor struct { + // buffer stores the messages for the buffering mechanism in case we didn't + // receive any SDS configuration & wait_for_configuration == "buffer". + buffer []*message.Message + bufferedBytes int + maxBufferSize int + + /// buffering indicates if we're buffering while waiting for an SDS configuration + buffering bool + + scanner *sds.Scanner // configured through RC } // New returns an initialized Processor. -func New(inputChan, outputChan chan *message.Message, processingRules []*config.ProcessingRule, encoder Encoder, - diagnosticMessageReceiver diagnostic.MessageReceiver, hostname hostnameinterface.Component, pipelineID int) *Processor { - sdsScanner := sds.CreateScanner(pipelineID) +func New(cfg pkgconfigmodel.Reader, inputChan, outputChan chan *message.Message, processingRules []*config.ProcessingRule, + encoder Encoder, diagnosticMessageReceiver diagnostic.MessageReceiver, hostname hostnameinterface.Component, + pipelineID int) *Processor { + + waitForSDSConfig := sds.ShouldBufferUntilSDSConfiguration(cfg) + maxBufferSize := sds.WaitForConfigurationBufferMaxSize(cfg) return &Processor{ pipelineID: pipelineID, @@ -54,9 +71,15 @@ func New(inputChan, outputChan chan *message.Message, processingRules []*config. processingRules: processingRules, encoder: encoder, done: make(chan struct{}), - sds: sdsScanner, diagnosticMessageReceiver: diagnosticMessageReceiver, hostname: hostname, + + sds: sdsProcessor{ + // will immediately starts buffering if it has been configured as so + buffering: waitForSDSConfig, + maxBufferSize: maxBufferSize, + scanner: sds.CreateScanner(pipelineID), + }, } } @@ -72,13 +95,14 @@ func (p *Processor) Stop() { <-p.done // once the processor mainloop is not running, it's safe // to delete the sds scanner instance. - if p.sds != nil { - p.sds.Delete() - p.sds = nil + if p.sds.scanner != nil { + p.sds.scanner.Delete() + p.sds.scanner = nil } } // Flush processes synchronously the messages that this processor has to process. +// Mainly (only?) used by the Serverless Agent. func (p *Processor) Flush(ctx context.Context) { p.mu.Lock() defer p.mu.Unlock() @@ -104,27 +128,94 @@ func (p *Processor) run() { for { select { + // Processing, usual main loop + // --------------------------- + case msg, ok := <-p.inputChan: if !ok { // channel has been closed return } - p.processMessage(msg) + + // if we have to wait for an SDS configuration to start processing & forwarding + // the logs, that's here that we buffer the message + if p.sds.buffering { + // buffer until we receive a configuration + p.sds.bufferMsg(msg) + } else { + // process the message + p.processMessage(msg) + } + p.mu.Lock() // block here if we're trying to flush synchronously //nolint:staticcheck p.mu.Unlock() + + // SDS reconfiguration + // ------------------- + case order := <-p.ReconfigChan: p.mu.Lock() - if err := p.sds.Reconfigure(order); err != nil { - log.Errorf("Error while reconfiguring the SDS scanner: %v", err) - order.ResponseChan <- err - } else { - order.ResponseChan <- nil - } + p.applySDSReconfiguration(order) p.mu.Unlock() } } } +func (p *Processor) applySDSReconfiguration(order sds.ReconfigureOrder) { + isActive, err := p.sds.scanner.Reconfigure(order) + response := sds.ReconfigureResponse{ + IsActive: isActive, + Err: err, + } + + if err != nil { + log.Errorf("Error while reconfiguring the SDS scanner: %v", err) + } else { + // no error while reconfiguring the SDS scanner and since it looks active now, + // we should drain the buffered messages if any and stop the + // buffering mechanism. + if p.sds.buffering && isActive { + log.Debug("Processor ready with an SDS configuration.") + p.sds.buffering = false + + // drain the buffer of messages if anything's in there + if len(p.sds.buffer) > 0 { + log.Info("SDS: sending", len(p.sds.buffer), "buffered messages") + for _, msg := range p.sds.buffer { + p.processMessage(msg) + } + } + + p.sds.resetBuffer() + } + // no else case, the buffering is only a startup mechanism, after having + // enabled the SDS scanners, if they become inactive it is because the + // configuration has been sent like that. + } + + order.ResponseChan <- response +} + +func (s *sdsProcessor) bufferMsg(msg *message.Message) { + s.buffer = append(s.buffer, msg) + s.bufferedBytes += len(msg.GetContent()) + + for len(s.buffer) > 0 { + if s.bufferedBytes > s.maxBufferSize { + s.bufferedBytes -= len(s.buffer[0].GetContent()) + s.buffer = s.buffer[1:] + metrics.TlmLogsDiscardedFromSDSBuffer.Inc() + } else { + break + } + } +} + +func (s *sdsProcessor) resetBuffer() { + s.buffer = nil + s.bufferedBytes = 0 +} + func (p *Processor) processMessage(msg *message.Message) { metrics.LogsDecoded.Add(1) metrics.TlmLogsDecoded.Inc() @@ -184,8 +275,8 @@ func (p *Processor) applyRedactingRules(msg *message.Message) bool { // -------------------------- // Global SDS scanner, applied on all log sources - if p.sds.IsReady() { - mutated, evtProcessed, err := p.sds.Scan(content, msg) + if p.sds.scanner.IsReady() { + mutated, evtProcessed, err := p.sds.scanner.Scan(content, msg) if err != nil { log.Error("while using SDS to scan the log:", err) } else if mutated { diff --git a/pkg/logs/processor/processor_test.go b/pkg/logs/processor/processor_test.go index 5da8a7b989fe2..bb2ff56b02461 100644 --- a/pkg/logs/processor/processor_test.go +++ b/pkg/logs/processor/processor_test.go @@ -7,13 +7,17 @@ package processor import ( "regexp" + "sync/atomic" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/DataDog/datadog-agent/comp/core/hostname/hostnameinterface" "github.com/DataDog/datadog-agent/comp/logs/agent/config" + "github.com/DataDog/datadog-agent/pkg/logs/diagnostic" "github.com/DataDog/datadog-agent/pkg/logs/message" + "github.com/DataDog/datadog-agent/pkg/logs/sds" "github.com/DataDog/datadog-agent/pkg/logs/sources" ) @@ -302,6 +306,161 @@ func TestGetHostname(t *testing.T) { assert.Equal(t, "testHostnameFromEnvVar", p.GetHostname(m)) } +func TestBuffering(t *testing.T) { + assert := assert.New(t) + + if !sds.SDSEnabled { // should not run when SDS is not builtin. + return + } + + hostnameComponent, _ := hostnameinterface.NewMock("testHostnameFromEnvVar") + + p := &Processor{ + encoder: JSONEncoder, + inputChan: make(chan *message.Message), + outputChan: make(chan *message.Message), + ReconfigChan: make(chan sds.ReconfigureOrder), + diagnosticMessageReceiver: diagnostic.NewBufferedMessageReceiver(nil, hostnameComponent), + done: make(chan struct{}), + // configured to buffer (max 3 messages) + sds: sdsProcessor{ + maxBufferSize: len("hello1world") + len("hello2world") + len("hello3world") + 1, + buffering: true, + scanner: sds.CreateScanner(42), + }, + } + + var processedMessages atomic.Int32 + + // consumer + go func() { + for { + <-p.outputChan + processedMessages.Add(1) + } + }() + + // test the buffering when the processor is waiting for an SDS config + // -- + + p.Start() + assert.Len(p.sds.buffer, 0) + + // validates it buffers these 3 messages + src := newSource("exclude_at_match", "", "foobar") + p.inputChan <- newMessage([]byte("hello1world"), &src, "") + p.inputChan <- newMessage([]byte("hello2world"), &src, "") + p.inputChan <- newMessage([]byte("hello3world"), &src, "") + // wait for the other routine to process the messages + messagesDequeue(t, func() bool { return processedMessages.Load() == 0 }, "the messages should not be be procesesd") + + // the limit is configured to 3 messages + p.inputChan <- newMessage([]byte("hello4world"), &src, "") + messagesDequeue(t, func() bool { return processedMessages.Load() == 0 }, "the messages should still not be processed") + + // reconfigure the processor + // -- + + // standard rules + order := sds.ReconfigureOrder{ + Type: sds.StandardRules, + Config: []byte(`{"priority":1,"is_enabled":true,"rules":[ + { + "id":"zero-0", + "description":"zero desc", + "name":"zero", + "definitions": [{"version":1, "pattern":"zero"}] + }]}`), + ResponseChan: make(chan sds.ReconfigureResponse), + } + + p.ReconfigChan <- order + resp := <-order.ResponseChan + assert.Nil(resp.Err) + assert.False(resp.IsActive) + assert.True(p.sds.buffering) + close(order.ResponseChan) + + // agent config, but no active rule + order = sds.ReconfigureOrder{ + Type: sds.AgentConfig, + Config: []byte(` {"is_enabled":true,"rules":[ + { + "id": "random000", + "name":"zero", + "definition":{"standard_rule_id":"zero-0"}, + "match_action":{"type":"Redact","placeholder":"[redacted]"}, + "is_enabled":false + }]}`), + ResponseChan: make(chan sds.ReconfigureResponse), + } + + p.ReconfigChan <- order + resp = <-order.ResponseChan + assert.Nil(resp.Err) + assert.False(resp.IsActive) + assert.True(p.sds.buffering) + close(order.ResponseChan) + + // agent config, but the scanner becomes active: + // * the logs agent should stop buffering + // * it should drains its buffer and process the buffered logs + + // first, check that the buffer is still full + messagesDequeue(t, func() bool { return processedMessages.Load() == 0 }, "no messages should be processed just yet") + + order = sds.ReconfigureOrder{ + Type: sds.AgentConfig, + Config: []byte(` {"is_enabled":true,"rules":[ + { + "id": "random000", + "name":"zero", + "definition":{"standard_rule_id":"zero-0"}, + "match_action":{"type":"Redact","placeholder":"[redacted]"}, + "is_enabled":true + }]}`), + ResponseChan: make(chan sds.ReconfigureResponse), + } + + p.ReconfigChan <- order + resp = <-order.ResponseChan + + assert.Nil(resp.Err) + assert.True(resp.IsActive) + assert.False(p.sds.buffering) // not buffering anymore + close(order.ResponseChan) + + // make sure all messages have been drained and processed + messagesDequeue(t, func() bool { return processedMessages.Load() == 3 }, "all messages must be drained") + + // make sure it continues to process normally without buffering now + p.inputChan <- newMessage([]byte("usual work"), &src, "") + messagesDequeue(t, func() bool { return processedMessages.Load() == 4 }, "should continue processing now") +} + +// messagesDequeue let the other routines being scheduled +// to give some time for the processor routine to dequeue its messages +func messagesDequeue(t *testing.T, f func() bool, errorLog string) { + timerTest := time.NewTimer(10 * time.Millisecond) + timerTimeout := time.NewTimer(5 * time.Second) + for { + select { + case <-timerTimeout.C: + timerTest.Stop() + timerTimeout.Stop() + t.Error("timeout while message dequeuing in the processor") + t.Fatal(errorLog) + break + case <-timerTest.C: + if f() { + timerTest.Stop() + timerTimeout.Stop() + return + } + } + } +} + // helpers // - diff --git a/pkg/logs/schedulers/ad/scheduler.go b/pkg/logs/schedulers/ad/scheduler.go index 94b5bcc05313d..2de2f525df0bd 100644 --- a/pkg/logs/schedulers/ad/scheduler.go +++ b/pkg/logs/schedulers/ad/scheduler.go @@ -65,13 +65,13 @@ func (s *Scheduler) Schedule(configs []integration.Config) { continue } if config.HasFilter(containers.LogsFilter) { - log.Debugf("Config %s is filtered out for logs collection, ignoring it", s.configName(config)) + log.Debugf("Config %s is filtered out for logs collection, ignoring it", configName(config)) continue } switch { case s.newSources(config): - log.Infof("Received a new logs config: %v", s.configName(config)) - sources, err := s.createSources(config) + log.Infof("Received a new logs config: %v", configName(config)) + sources, err := CreateSources(config) if err != nil { log.Warnf("Invalid configuration: %v", err) continue @@ -80,7 +80,7 @@ func (s *Scheduler) Schedule(configs []integration.Config) { s.mgr.AddSource(source) } default: - log.Debugf("Invalid integration config: %s, ignoring it", s.configName(config)) + log.Debugf("Invalid integration config: %s, ignoring it", configName(config)) continue } } @@ -96,7 +96,7 @@ func (s *Scheduler) Unschedule(configs []integration.Config) { case s.newSources(config): log.Infof("New source to remove: entity: %v", config.ServiceID) - _, identifier, err := s.parseServiceID(config.ServiceID) + _, identifier, err := parseServiceID(config.ServiceID) if err != nil { log.Warnf("Invalid configuration: %v", err) continue @@ -128,11 +128,11 @@ func (s *Scheduler) newSources(config integration.Config) bool { } // configName returns the name of the configuration. -func (s *Scheduler) configName(config integration.Config) string { +func configName(config integration.Config) string { if config.Name != "" { return config.Name } - service, err := s.toService(config) + service, err := toService(config) if err == nil { return service.Type } @@ -141,7 +141,7 @@ func (s *Scheduler) configName(config integration.Config) string { // createsSources creates new sources from an integration config, // returns an error if the parsing failed. -func (s *Scheduler) createSources(config integration.Config) ([]*sourcesPkg.LogSource, error) { +func CreateSources(config integration.Config) ([]*sourcesPkg.LogSource, error) { var configs []*logsConfig.LogsConfig var err error @@ -182,13 +182,13 @@ func (s *Scheduler) createSources(config integration.Config) ([]*sourcesPkg.LogS // this entity is used later on by an input to match a service with a source // to start collecting logs. var err error - service, err = s.toService(config) + service, err = toService(config) if err != nil { return nil, fmt.Errorf("invalid entity: %v", err) } } - configName := s.configName(config) + configName := configName(config) var sources []*sourcesPkg.LogSource for _, cfg := range configs { // if no service is set fall back to the global one @@ -229,8 +229,8 @@ func (s *Scheduler) createSources(config integration.Config) ([]*sourcesPkg.LogS } // toService creates a new service for an integrationConfig. -func (s *Scheduler) toService(config integration.Config) (*service.Service, error) { - provider, identifier, err := s.parseServiceID(config.ServiceID) +func toService(config integration.Config) (*service.Service, error) { + provider, identifier, err := parseServiceID(config.ServiceID) if err != nil { return nil, err } @@ -239,7 +239,7 @@ func (s *Scheduler) toService(config integration.Config) (*service.Service, erro // parseServiceID breaks down an AD service ID, assuming it is formatted // as `something://something-else`, into its consituent parts. -func (s *Scheduler) parseServiceID(serviceID string) (string, string, error) { +func parseServiceID(serviceID string) (string, string, error) { components := strings.Split(serviceID, containers.EntitySeparator) if len(components) != 2 { return "", "", fmt.Errorf("service ID does not have the form `xxx://yyy`: %v", serviceID) diff --git a/pkg/logs/schedulers/ad/scheduler_test.go b/pkg/logs/schedulers/ad/scheduler_test.go index 29812c26778c4..477c29b7af2a6 100644 --- a/pkg/logs/schedulers/ad/scheduler_test.go +++ b/pkg/logs/schedulers/ad/scheduler_test.go @@ -167,7 +167,7 @@ func TestUnscheduleConfigRemovesSource(t *testing.T) { } // We need to have a source to remove - sources, _ := scheduler.createSources(configSource) + sources, _ := CreateSources(configSource) spy.Sources = sources scheduler.Unschedule([]integration.Config{configSource}) diff --git a/pkg/logs/schedulers/cca/scheduler_test.go b/pkg/logs/schedulers/cca/scheduler_test.go index a023c6b3a7303..c32165ef276ed 100644 --- a/pkg/logs/schedulers/cca/scheduler_test.go +++ b/pkg/logs/schedulers/cca/scheduler_test.go @@ -29,8 +29,7 @@ func setup(t *testing.T) (scheduler *Scheduler, ac autodiscovery.Component, spy ac = fxutil.Test[autodiscovery.Mock](t, fx.Supply(autodiscoveryimpl.MockParams{}), autodiscoveryimpl.MockModule(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), core.MockBundle(), fx.Supply(tagger.NewFakeTaggerParams()), fx.Provide(taggerimpl.NewMock), diff --git a/pkg/logs/sds/go.mod b/pkg/logs/sds/go.mod index e43c03164d1e0..03e37c5ec16da 100644 --- a/pkg/logs/sds/go.mod +++ b/pkg/logs/sds/go.mod @@ -15,6 +15,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../comp/logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../config/utils @@ -45,10 +46,11 @@ replace ( ) require ( + github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/logs/message v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/telemetry v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/util/log v0.56.0-rc.3 - github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe + github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 github.com/stretchr/testify v1.9.0 ) @@ -59,7 +61,6 @@ require ( github.com/DataDog/datadog-agent/comp/logs/agent/config v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect - github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/setup v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/utils v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/logs/sources v0.56.0-rc.3 // indirect @@ -120,16 +121,16 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/pkg/logs/sds/go.sum b/pkg/logs/sds/go.sum index 7f4a56c218f3c..00f5c6c8590cf 100644 --- a/pkg/logs/sds/go.sum +++ b/pkg/logs/sds/go.sum @@ -39,8 +39,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe h1:efzxujZ7VHWFxjmWjcJyUEpPrN8qdiZPYb+dBw547Wo= -github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240419161837-f1b2f553edfe/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 h1:RoH7VLzTnxHEugRPIgnGlxwDFszFGI7b3WZZUtWuPRM= +github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42/go.mod h1:TX7CTOQ3LbQjfAi4SwqUoR5gY1zfUk7VRBDTuArjaDc= github.com/DataDog/viper v1.13.5 h1:SZMcyMknYQN2jRY/40A16gUXexlNJOI8sDs1cWZnI64= github.com/DataDog/viper v1.13.5/go.mod h1:wDdUVJ2SHaMaPrCZrlRCObwkubsX8j5sme3LaR/SGTc= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= @@ -52,8 +52,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -359,21 +357,21 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -392,8 +390,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -523,8 +521,8 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -534,8 +532,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -591,8 +589,8 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/pkg/logs/sds/reconfigure.go b/pkg/logs/sds/reconfigure.go index 5b3d3fe4c64cd..117aad86090b3 100644 --- a/pkg/logs/sds/reconfigure.go +++ b/pkg/logs/sds/reconfigure.go @@ -6,8 +6,21 @@ //nolint:revive package sds +import ( + "fmt" + + pkgconfigmodel "github.com/DataDog/datadog-agent/pkg/config/model" +) + type ReconfigureOrderType string +const waitForConfigField = "logs_config.sds.wait_for_configuration" +const waitForConfigBufferMaxSizeField = "logs_config.sds.buffer_max_size" +const waitForConfigDefaultBufferMaxSize = 1024 * 1024 * 500 + +const waitForConfigNoCollection = "no_collection" +const waitForConfigBuffer = "buffer" + const ( // StandardRules triggers the storage of a new set of standard rules // and reconfigure the internal SDS scanner with an existing user @@ -15,6 +28,9 @@ const ( StandardRules ReconfigureOrderType = "standard_rules" // AgentConfig triggers a reconfiguration of the SDS scanner. AgentConfig ReconfigureOrderType = "agent_config" + // StopProcessing triggers a reconfiguration of the SDS scanner by destroying + // it to remove the SDS processing step. + StopProcessing ReconfigureOrderType = "stop_processing" ) // ReconfigureOrder are used to trigger a reconfiguration @@ -22,5 +38,68 @@ const ( type ReconfigureOrder struct { Type ReconfigureOrderType Config []byte - ResponseChan chan error + ResponseChan chan ReconfigureResponse +} + +// ReconfigureResponse is used to transmit the result from reconfiguring +// the processors. +type ReconfigureResponse struct { + Err error + IsActive bool +} + +// ValidateConfigField returns true if the configuration value for +// wait_for_configuration is valid. +// Validates its value only when SDS is enabled. +func ValidateConfigField(cfg pkgconfigmodel.Reader) error { + str := cfg.GetString(waitForConfigField) + + if !SDSEnabled || + str == "" || str == waitForConfigBuffer || str == waitForConfigNoCollection { + return nil + } + + return fmt.Errorf("invalid value for '%s': %s. Valid values: %s, %s", + waitForConfigField, str, + waitForConfigBuffer, waitForConfigNoCollection) +} + +// ShouldBlockCollectionUntilSDSConfiguration returns true if we want to start the +// collection only after having received an SDS configuration. +func ShouldBlockCollectionUntilSDSConfiguration(cfg pkgconfigmodel.Reader) bool { + if cfg == nil { + return false + } + + // in case of an invalid value for the `wait_for_configuration` field, + // as a safeguard, we want to block collection until we received an SDS configuration. + if SDSEnabled && ValidateConfigField(cfg) != nil { + return true + } + + return SDSEnabled && cfg.GetString(waitForConfigField) == waitForConfigNoCollection +} + +// ShouldBufferUntilSDSConfiguration returns true if we have to buffer until we've +// received an SDS configuration. +func ShouldBufferUntilSDSConfiguration(cfg pkgconfigmodel.Reader) bool { + if cfg == nil { + return false + } + + return SDSEnabled && cfg.GetString(waitForConfigField) == waitForConfigBuffer +} + +// WaitForConfigurationBufferMaxSize returns a size for the buffer used while +// waiting for an SDS configuration. +func WaitForConfigurationBufferMaxSize(cfg pkgconfigmodel.Reader) int { + if cfg == nil { + return waitForConfigDefaultBufferMaxSize + } + + v := cfg.GetInt(waitForConfigBufferMaxSizeField) + if v <= 0 { + v = waitForConfigDefaultBufferMaxSize + } + return v } diff --git a/pkg/logs/sds/scanner.go b/pkg/logs/sds/scanner.go index effde9e28c544..c8f726b38a18d 100644 --- a/pkg/logs/sds/scanner.go +++ b/pkg/logs/sds/scanner.go @@ -86,11 +86,12 @@ const ( // to apply the reconfiguration. // When receiving standard rules, user configuration are reloaded and scanners are // recreated to use the newly received standard rules. +// The boolean return parameter indicates if the SDS scanner has been destroyed. // This method is thread safe, a scan can't happen at the same time. -func (s *Scanner) Reconfigure(order ReconfigureOrder) error { +func (s *Scanner) Reconfigure(order ReconfigureOrder) (bool, error) { if s == nil { log.Warn("Trying to reconfigure a nil Scanner") - return nil + return false, nil } s.Lock() @@ -102,24 +103,28 @@ func (s *Scanner) Reconfigure(order ReconfigureOrder) error { case StandardRules: // reconfigure the standard rules err := s.reconfigureStandardRules(order.Config) + var isActive bool // if we already received a configuration and no errors happened while // reconfiguring the standard rules: reapply the user configuration now. if err == nil && s.rawConfig != nil { - if rerr := s.reconfigureRules(s.rawConfig); rerr != nil { + var rerr error + if isActive, rerr = s.reconfigureRules(s.rawConfig); rerr != nil { log.Error("Can't reconfigure SDS after having received standard rules:", rerr) - s.rawConfig = nil // we drop this configuration because it is unusable + s.rawConfig = nil // we drop this configuration because it seems unusable if err == nil { err = rerr } } } - return err + return isActive, err case AgentConfig: return s.reconfigureRules(order.Config) + case StopProcessing: + return s.reconfigureRules([]byte("{}")) } - return fmt.Errorf("Scanner.Reconfigure: Unknown order type: %v", order.Type) + return false, fmt.Errorf("Scanner.Reconfigure: Unknown order type: %v", order.Type) } // reconfigureStandardRules stores in-memory standard rules received through RC. @@ -159,25 +164,26 @@ func (s *Scanner) reconfigureStandardRules(rawConfig []byte) error { // reconfigureRules reconfigures the internal SDS scanner using the in-memory // standard rules. Could possibly delete and recreate the internal SDS scanner if // necessary. +// The boolean return parameter returns if an SDS scanner is active. // This method is NOT thread safe, caller has to ensure the thread safety. -func (s *Scanner) reconfigureRules(rawConfig []byte) error { +func (s *Scanner) reconfigureRules(rawConfig []byte) (bool, error) { if rawConfig == nil { tlmSDSReconfigError.Inc(s.pipelineID, string(AgentConfig), "nil_config") - return fmt.Errorf("Invalid nil raw configuration received for user configuration") + return s.Scanner != nil, fmt.Errorf("Invalid nil raw configuration received for user configuration") } if s.standardRules == nil || len(s.standardRules) == 0 { // store it for the next try s.rawConfig = rawConfig tlmSDSReconfigError.Inc(s.pipelineID, string(AgentConfig), "no_std_rules") - log.Info("Received an user configuration but no SDS standard rules available.") - return nil + log.Debug("Received an user configuration but no SDS standard rules available.") + return s.Scanner != nil, nil } var config RulesConfig if err := json.Unmarshal(rawConfig, &config); err != nil { tlmSDSReconfigError.Inc(s.pipelineID, string(AgentConfig), "cant_unmarshal") - return fmt.Errorf("Can't unmarshal raw configuration: %v", err) + return s.Scanner != nil, fmt.Errorf("Can't unmarshal raw configuration: %v", err) } // ignore disabled rules @@ -197,11 +203,11 @@ func (s *Scanner) reconfigureRules(rawConfig []byte) error { s.configuredRules = nil tlmSDSReconfigSuccess.Inc(s.pipelineID, "shutdown") } - return nil + return false, nil } // prepare the scanner rules - var sdsRules []sds.Rule + var sdsRules []sds.RuleConfig var malformedRulesCount int var unknownStdRulesCount int for _, userRule := range config.Rules { @@ -231,7 +237,7 @@ func (s *Scanner) reconfigureRules(rawConfig []byte) error { var err error if scanner, err = sds.CreateScanner(sdsRules); err != nil { tlmSDSReconfigError.Inc(s.pipelineID, string(AgentConfig), "scanner_error") - return fmt.Errorf("while configuring an SDS Scanner: %v", err) + return s.Scanner != nil, fmt.Errorf("while configuring an SDS Scanner: %v", err) } // destroy the old scanner @@ -245,7 +251,7 @@ func (s *Scanner) reconfigureRules(rawConfig []byte) error { s.rawConfig = rawConfig s.configuredRules = config.Rules - log.Info("Created an SDS scanner with", len(scanner.Rules), "enabled rules") + log.Info("Created an SDS scanner with", len(scanner.RuleConfigs), "enabled rules") for _, rule := range s.configuredRules { log.Debug("Configured rule:", rule.Name) } @@ -255,14 +261,13 @@ func (s *Scanner) reconfigureRules(rawConfig []byte) error { tlmSDSRulesState.Set(float64(totalRulesReceived-len(config.Rules)), s.pipelineID, "disabled") tlmSDSReconfigSuccess.Inc(s.pipelineID, string(AgentConfig)) - return nil + return true, nil } -// interpretRCRule interprets a rule as received through RC to return -// an sds.Rule usable with the shared library. +// interpretRCRule interprets a rule as received through RC to return an sds.Rule usable with the shared library. // `standardRule` contains the definition, with the name, pattern, etc. // `userRule` contains the configuration done by the user: match action, etc. -func interpretRCRule(userRule RuleConfig, standardRule StandardRuleConfig, defaults StandardRulesDefaults) (sds.Rule, error) { +func interpretRCRule(userRule RuleConfig, standardRule StandardRuleConfig, defaults StandardRulesDefaults) (sds.RuleConfig, error) { var extraConfig sds.ExtraConfig var defToUse = StandardRuleDefinition{Version: -1} @@ -303,7 +308,7 @@ func interpretRCRule(userRule RuleConfig, standardRule StandardRuleConfig, defau if defToUse.Version == -1 { // TODO(remy): telemetry - return sds.Rule{}, fmt.Errorf("unsupported rule with no compatible definition") + return nil, fmt.Errorf("unsupported rule with no compatible definition") } // we use the filled `CharacterCount` value to decide if we want @@ -341,7 +346,7 @@ func interpretRCRule(userRule RuleConfig, standardRule StandardRuleConfig, defau return sds.NewHashRule(standardRule.Name, defToUse.Pattern, extraConfig), nil } - return sds.Rule{}, fmt.Errorf("Unknown MatchAction type (%v) received through RC for rule '%s':", matchAction, standardRule.Name) + return nil, fmt.Errorf("Unknown MatchAction type (%v) received through RC for rule '%s':", matchAction, standardRule.Name) } // Scan scans the given `event` using the internal SDS scanner. @@ -412,7 +417,7 @@ func (s *Scanner) IsReady() bool { if s.Scanner == nil { return false } - if len(s.Scanner.Rules) == 0 { + if len(s.Scanner.RuleConfigs) == 0 { return false } diff --git a/pkg/logs/sds/scanner_nosds.go b/pkg/logs/sds/scanner_nosds.go index 7ed96c1062525..0f1d256f6917a 100644 --- a/pkg/logs/sds/scanner_nosds.go +++ b/pkg/logs/sds/scanner_nosds.go @@ -29,8 +29,8 @@ func CreateScanner(_ int) *Scanner { } // Reconfigure mocks the Reconfigure function. -func (s *Scanner) Reconfigure(_ ReconfigureOrder) error { - return nil +func (s *Scanner) Reconfigure(_ ReconfigureOrder) (bool, error) { + return false, nil } // Delete mocks the Delete function. diff --git a/pkg/logs/sds/scanner_test.go b/pkg/logs/sds/scanner_test.go index 34a747f0a55e7..3ccc85fe7be4b 100644 --- a/pkg/logs/sds/scanner_test.go +++ b/pkg/logs/sds/scanner_test.go @@ -72,15 +72,16 @@ func TestCreateScanner(t *testing.T) { require.NotNil(s, "the scanner should not be nil after a creation") - err := s.Reconfigure(ReconfigureOrder{ + isActive, err := s.Reconfigure(ReconfigureOrder{ Type: StandardRules, Config: standardRules, }) require.NoError(err, "configuring the standard rules should not fail") + require.False(isActive, "with only standard rules, the scanner can't be active") // now that we have some definitions, we can configure the scanner - err = s.Reconfigure(ReconfigureOrder{ + isActive, err = s.Reconfigure(ReconfigureOrder{ Type: AgentConfig, Config: agentConfig, }) @@ -88,6 +89,7 @@ func TestCreateScanner(t *testing.T) { require.NoError(err, "this one shouldn't fail, all rules are disabled but it's OK as long as there are no rules in the scanner") require.NotNil(s, "the scanner should not become a nil object") + require.False(isActive, "all rules are disabled, the scanner should not be active") if s != nil && len(s.configuredRules) > 0 { t.Errorf("No rules should be configured, they're all disabled. Got (%v) rules configured instead.", len(s.configuredRules)) @@ -98,17 +100,18 @@ func TestCreateScanner(t *testing.T) { agentConfig = bytes.Replace(agentConfig, []byte("\"is_enabled\":false"), []byte("\"is_enabled\":true"), 2) - err = s.Reconfigure(ReconfigureOrder{ + isActive, err = s.Reconfigure(ReconfigureOrder{ Type: AgentConfig, Config: agentConfig, }) require.NoError(err, "this one should not fail since two rules are enabled: %v", err) + require.True(isActive, "the scanner should now be active") require.NotNil(s.Scanner, "the Scanner should've been created, it should not be nil") - require.NotNil(s.Scanner.Rules, "the Scanner should use rules") + require.NotNil(s.Scanner.RuleConfigs, "the Scanner should use rules") - require.Len(s.Scanner.Rules, 2, "the Scanner should use two rules") + require.Len(s.Scanner.RuleConfigs, 2, "the Scanner should use two rules") require.Len(s.configuredRules, 2, "only two rules should be part of this scanner.") // order matters, it's ok to test rules by [] access @@ -152,13 +155,14 @@ func TestCreateScanner(t *testing.T) { ]} `) - err = s.Reconfigure(ReconfigureOrder{ + isActive, err = s.Reconfigure(ReconfigureOrder{ Type: AgentConfig, Config: agentConfig, }) require.NoError(err, "this one should not fail since one rule is enabled") require.Len(s.configuredRules, 1, "only one rules should be part of this scanner") + require.True(isActive, "the scanner should be active as one rule is enabled") // order matters, it's ok to test rules by [] access require.Equal(s.configuredRules[0].Name, "one", "incorrect rule selected for configuration") @@ -194,13 +198,14 @@ func TestCreateScanner(t *testing.T) { ]} `) - err = s.Reconfigure(ReconfigureOrder{ + isActive, err = s.Reconfigure(ReconfigureOrder{ Type: AgentConfig, Config: agentConfig, }) require.NoError(err, "no error should happen") require.Len(s.configuredRules, 0, "The group is disabled, no rules should be configured.") + require.False(isActive, "the scanner should've been disabled") } // TestEmptyConfiguration validates that the scanner is destroyed when receiving @@ -244,27 +249,29 @@ func TestEmptyConfiguration(t *testing.T) { require.NotNil(s, "the scanner should not be nil after a creation") - err := s.Reconfigure(ReconfigureOrder{ + isActive, err := s.Reconfigure(ReconfigureOrder{ Type: StandardRules, Config: standardRules, }) require.NoError(err, "configuring the standard rules should not fail") + require.False(isActive, "with only standard rules, the scanner can't be active") // configure with one rule - err = s.Reconfigure(ReconfigureOrder{ + isActive, err = s.Reconfigure(ReconfigureOrder{ Type: AgentConfig, Config: agentConfig, }) require.NoError(err, "this one should not fail since one rule is enabled") require.Len(s.configuredRules, 1, "only one rules should be part of this scanner") + require.True(isActive, "one rule is enabled, the scanner should be active") require.NotNil(s.Scanner) // empty reconfiguration - err = s.Reconfigure(ReconfigureOrder{ + isActive, err = s.Reconfigure(ReconfigureOrder{ Type: AgentConfig, Config: []byte("{}"), }) @@ -272,6 +279,31 @@ func TestEmptyConfiguration(t *testing.T) { require.NoError(err) require.Len(s.configuredRules, 0) require.Nil(s.Scanner) + require.False(isActive, "no active rule, the scanner should be disabled") + + // re-enabling with on rule + + isActive, err = s.Reconfigure(ReconfigureOrder{ + Type: AgentConfig, + Config: agentConfig, + }) + + require.NoError(err, "this one should not fail since one rule is enabled") + require.Len(s.configuredRules, 1, "only one rules should be part of this scanner") + require.True(isActive, "one rule is enabled, the scanner should be active") + require.NotNil(s.Scanner) + + // the StopProcessing signal + + isActive, err = s.Reconfigure(ReconfigureOrder{ + Type: StopProcessing, + Config: nil, + }) + + require.NoError(err) + require.Len(s.configuredRules, 0) + require.Nil(s.Scanner) + require.False(isActive, "no active rule, the scanner should be disabled") } func TestIsReady(t *testing.T) { @@ -323,21 +355,23 @@ func TestIsReady(t *testing.T) { require.NotNil(s, "the scanner should not be nil after a creation") require.False(s.IsReady(), "at this stage, the scanner should not be considered ready, no definitions received") - err := s.Reconfigure(ReconfigureOrder{ + isActive, err := s.Reconfigure(ReconfigureOrder{ Type: StandardRules, Config: standardRules, }) require.NoError(err, "configuring the definitions should not fail") require.False(s.IsReady(), "at this stage, the scanner should not be considered ready, no user config received") + require.False(isActive, "only standard rules configured, the scanner should not be active") // now that we have some definitions, we can configure the scanner - err = s.Reconfigure(ReconfigureOrder{ + isActive, err = s.Reconfigure(ReconfigureOrder{ Type: AgentConfig, Config: agentConfig, }) require.True(s.IsReady(), "at this stage, the scanner should be considered ready") + require.True(isActive, "the scanner has some enabled rules, it should be active") } // TestScan validates that everything fits and works. It's not validating @@ -389,16 +423,21 @@ func TestScan(t *testing.T) { s := CreateScanner(0) require.NotNil(s, "the returned scanner should not be nil") - _ = s.Reconfigure(ReconfigureOrder{ + isActive, _ := s.Reconfigure(ReconfigureOrder{ Type: StandardRules, Config: standardRules, }) - _ = s.Reconfigure(ReconfigureOrder{ + + require.False(isActive, "only standard rules, the scanner should be disabled") + + isActive, _ = s.Reconfigure(ReconfigureOrder{ Type: AgentConfig, Config: agentConfig, }) require.True(s.IsReady(), "at this stage, the scanner should be considered ready") + require.True(isActive, "rules are configured, the scanner should be active") + type result struct { matched bool event string @@ -473,16 +512,18 @@ func TestCloseCycleScan(t *testing.T) { s := CreateScanner(0) require.NotNil(s, "the returned scanner should not be nil") - _ = s.Reconfigure(ReconfigureOrder{ + _, _ = s.Reconfigure(ReconfigureOrder{ Type: StandardRules, Config: standardRules, }) - _ = s.Reconfigure(ReconfigureOrder{ + isActive, _ := s.Reconfigure(ReconfigureOrder{ Type: AgentConfig, Config: agentConfig, }) require.True(s.IsReady(), "at this stage, the scanner should be considered ready") + require.True(isActive, "the scanner should be active") + type result struct { matched bool event string @@ -556,10 +597,12 @@ func TestInterpretRC(t *testing.T) { rule, err := interpretRCRule(rc, stdRc, StandardRulesDefaults{}) require.NoError(err) + rxRule, ok := rule.(sds.RegexRuleConfig) + require.True(ok) - require.Equal(rule.Id, "Zero") - require.Equal(rule.Pattern, "rule pattern 1") - require.Equal(rule.SecondaryValidator, sds.SecondaryValidator("")) + require.Equal(rxRule.Id, "Zero") + require.Equal(rxRule.Pattern, "rule pattern 1") + require.Equal(rxRule.SecondaryValidator, sds.SecondaryValidator("")) // add a version with a required capability stdRc.Definitions = append(stdRc.Definitions, StandardRuleDefinition{ @@ -570,10 +613,12 @@ func TestInterpretRC(t *testing.T) { rule, err = interpretRCRule(rc, stdRc, StandardRulesDefaults{}) require.NoError(err) + rxRule, ok = rule.(sds.RegexRuleConfig) + require.True(ok) - require.Equal(rule.Id, "Zero") - require.Equal(rule.Pattern, "second pattern") - require.Equal(rule.SecondaryValidator, sds.LuhnChecksum) + require.Equal(rxRule.Id, "Zero") + require.Equal(rxRule.Pattern, "second pattern") + require.Equal(rxRule.SecondaryValidator, sds.LuhnChecksum) // add a third version with an unknown required capability // it should fallback on using the version 2 @@ -598,10 +643,12 @@ func TestInterpretRC(t *testing.T) { rule, err = interpretRCRule(rc, stdRc, StandardRulesDefaults{}) require.NoError(err) + rxRule, ok = rule.(sds.RegexRuleConfig) + require.True(ok) - require.Equal(rule.Id, "Zero") - require.Equal(rule.Pattern, "second pattern") - require.Equal(rule.SecondaryValidator, sds.LuhnChecksum) + require.Equal(rxRule.Id, "Zero") + require.Equal(rxRule.Pattern, "second pattern") + require.Equal(rxRule.SecondaryValidator, sds.LuhnChecksum) // make sure we use the keywords proximity feature if any's configured // in the std rule definition stdRc.Definitions = []StandardRuleDefinition{ @@ -621,13 +668,15 @@ func TestInterpretRC(t *testing.T) { rule, err = interpretRCRule(rc, stdRc, StandardRulesDefaults{IncludedKeywordsCharCount: 10}) require.NoError(err) + rxRule, ok = rule.(sds.RegexRuleConfig) + require.True(ok) - require.Equal(rule.Id, "Zero") - require.Equal(rule.Pattern, "second pattern") - require.Equal(rule.SecondaryValidator, sds.LuhnChecksum) - require.NotNil(rule.ProximityKeywords) - require.Equal(rule.ProximityKeywords.LookAheadCharacterCount, uint32(10)) - require.Equal(rule.ProximityKeywords.IncludedKeywords, []string{"hello"}) + require.Equal(rxRule.Id, "Zero") + require.Equal(rxRule.Pattern, "second pattern") + require.Equal(rxRule.SecondaryValidator, sds.LuhnChecksum) + require.NotNil(rxRule.ProximityKeywords) + require.Equal(rxRule.ProximityKeywords.LookAheadCharacterCount, uint32(10)) + require.Equal(rxRule.ProximityKeywords.IncludedKeywords, []string{"hello"}) // make sure we use the user provided information first // even if there is some in the std rule @@ -638,11 +687,13 @@ func TestInterpretRC(t *testing.T) { rule, err = interpretRCRule(rc, stdRc, StandardRulesDefaults{IncludedKeywordsCharCount: 10}) require.NoError(err) - - require.Equal(rule.Id, "Zero") - require.Equal(rule.Pattern, "second pattern") - require.Equal(rule.SecondaryValidator, sds.LuhnChecksum) - require.NotNil(rule.ProximityKeywords) - require.Equal(rule.ProximityKeywords.LookAheadCharacterCount, uint32(42)) - require.Equal(rule.ProximityKeywords.IncludedKeywords, []string{"custom"}) + rxRule, ok = rule.(sds.RegexRuleConfig) + require.True(ok) + + require.Equal(rxRule.Id, "Zero") + require.Equal(rxRule.Pattern, "second pattern") + require.Equal(rxRule.SecondaryValidator, sds.LuhnChecksum) + require.NotNil(rxRule.ProximityKeywords) + require.Equal(rxRule.ProximityKeywords.LookAheadCharacterCount, uint32(42)) + require.Equal(rxRule.ProximityKeywords.IncludedKeywords, []string{"custom"}) } diff --git a/pkg/logs/sender/go.mod b/pkg/logs/sender/go.mod index 5056a0427f866..a53ad5a116d7d 100644 --- a/pkg/logs/sender/go.mod +++ b/pkg/logs/sender/go.mod @@ -15,6 +15,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../comp/logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../config/utils @@ -125,17 +126,17 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.10.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/pkg/logs/sender/go.sum b/pkg/logs/sender/go.sum index 3435c68d83f5c..9b6cd83d632fb 100644 --- a/pkg/logs/sender/go.sum +++ b/pkg/logs/sender/go.sum @@ -357,21 +357,21 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -390,8 +390,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -454,8 +454,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -523,8 +523,8 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -534,8 +534,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -591,8 +591,8 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/pkg/logs/sources/go.mod b/pkg/logs/sources/go.mod index 551b369ea8cc6..aca5605c063da 100644 --- a/pkg/logs/sources/go.mod +++ b/pkg/logs/sources/go.mod @@ -13,6 +13,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../comp/logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../config/utils @@ -85,12 +86,12 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/logs/sources/go.sum b/pkg/logs/sources/go.sum index 79c2fcb395d02..77ba213060c82 100644 --- a/pkg/logs/sources/go.sum +++ b/pkg/logs/sources/go.sum @@ -234,25 +234,25 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -295,11 +295,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -312,8 +312,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/logs/status/builder.go b/pkg/logs/status/builder.go index 9dc7e1f1db6ee..9dfd646e21891 100644 --- a/pkg/logs/status/builder.go +++ b/pkg/logs/status/builder.go @@ -23,7 +23,7 @@ import ( // Builder is used to build the status. type Builder struct { - isRunning *atomic.Bool + isRunning *atomic.Uint32 endpoints *config.Endpoints sources *sourcesPkg.LogSources tailers *tailers.TailerTracker @@ -33,7 +33,7 @@ type Builder struct { } // NewBuilder returns a new builder. -func NewBuilder(isRunning *atomic.Bool, endpoints *config.Endpoints, sources *sourcesPkg.LogSources, tracker *tailers.TailerTracker, warnings *config.Messages, errors *config.Messages, logExpVars *expvar.Map) *Builder { +func NewBuilder(isRunning *atomic.Uint32, endpoints *config.Endpoints, sources *sourcesPkg.LogSources, tracker *tailers.TailerTracker, warnings *config.Messages, errors *config.Messages, logExpVars *expvar.Map) *Builder { return &Builder{ isRunning: isRunning, endpoints: endpoints, @@ -52,15 +52,16 @@ func (b *Builder) BuildStatus(verbose bool) Status { tailers = b.getTailers() } return Status{ - IsRunning: b.getIsRunning(), - Endpoints: b.getEndpoints(), - Integrations: b.getIntegrations(), - Tailers: tailers, - StatusMetrics: b.getMetricsStatus(), - ProcessFileStats: b.getProcessFileStats(), - Warnings: b.getWarnings(), - Errors: b.getErrors(), - UseHTTP: b.getUseHTTP(), + IsRunning: b.getIsRunning(), + WaitingForSDSConfig: b.getWaitingForSDSConfig(), + Endpoints: b.getEndpoints(), + Integrations: b.getIntegrations(), + Tailers: tailers, + StatusMetrics: b.getMetricsStatus(), + ProcessFileStats: b.getProcessFileStats(), + Warnings: b.getWarnings(), + Errors: b.getErrors(), + UseHTTP: b.getUseHTTP(), } } @@ -68,7 +69,11 @@ func (b *Builder) BuildStatus(verbose bool) Status { // this needs to be thread safe as it can be accessed // from different commands (start, stop, status). func (b *Builder) getIsRunning() bool { - return b.isRunning.Load() + return b.isRunning.Load() == StatusRunning +} + +func (b *Builder) getWaitingForSDSConfig() bool { + return b.isRunning.Load() == StatusCollectionNotStarted } func (b *Builder) getUseHTTP() bool { diff --git a/pkg/logs/status/status.go b/pkg/logs/status/status.go index dac8fb4f848fe..7f7a14c286e4f 100644 --- a/pkg/logs/status/status.go +++ b/pkg/logs/status/status.go @@ -26,6 +26,13 @@ const ( TransportHTTP Transport = "HTTP" // TransportTCP indicates logs-agent is using TCP transport TransportTCP Transport = "TCP" + + // StatusNotStarted means that the logs agent is not started + StatusNotStarted = 0 + // StatusRunning means that the logs agent is running and fully operational + StatusRunning = 1 + // StatusCollectionNotStarted means that the logs agent has not started collecting logs + StatusCollectionNotStarted = 2 ) var ( @@ -69,15 +76,16 @@ type Integration struct { // Status provides some information about logs-agent. type Status struct { - IsRunning bool `json:"is_running"` - Endpoints []string `json:"endpoints"` - StatusMetrics map[string]string `json:"metrics"` - ProcessFileStats map[string]uint64 `json:"process_file_stats"` - Integrations []Integration `json:"integrations"` - Tailers []Tailer `json:"tailers"` - Errors []string `json:"errors"` - Warnings []string `json:"warnings"` - UseHTTP bool `json:"use_http"` + IsRunning bool `json:"is_running"` + WaitingForSDSConfig bool `json:"waiting_for_sds_config"` + Endpoints []string `json:"endpoints"` + StatusMetrics map[string]string `json:"metrics"` + ProcessFileStats map[string]uint64 `json:"process_file_stats"` + Integrations []Integration `json:"integrations"` + Tailers []Tailer `json:"tailers"` + Errors []string `json:"errors"` + Warnings []string `json:"warnings"` + UseHTTP bool `json:"use_http"` } // SetCurrentTransport sets the current transport used by the log agent. @@ -97,7 +105,7 @@ func GetCurrentTransport() Transport { } // Init instantiates the builder that builds the status on the fly. -func Init(isRunning *atomic.Bool, endpoints *config.Endpoints, sources *sources.LogSources, tracker *tailers.TailerTracker, logExpVars *expvar.Map) { +func Init(isRunning *atomic.Uint32, endpoints *config.Endpoints, sources *sources.LogSources, tracker *tailers.TailerTracker, logExpVars *expvar.Map) { globalsLock.Lock() defer globalsLock.Unlock() @@ -123,7 +131,8 @@ func Get(verbose bool) Status { if builder == nil { return Status{ - IsRunning: false, + IsRunning: false, + WaitingForSDSConfig: false, } } return builder.BuildStatus(verbose) diff --git a/pkg/logs/status/test_utils.go b/pkg/logs/status/test_utils.go index cb4bbf3949dae..0c3d6ee515605 100644 --- a/pkg/logs/status/test_utils.go +++ b/pkg/logs/status/test_utils.go @@ -19,7 +19,7 @@ import ( // InitStatus initialize a status builder func InitStatus(coreConfig pkgConfig.Reader, sources *sources.LogSources) { - var isRunning = atomic.NewBool(true) + var isRunning = atomic.NewUint32(StatusRunning) tracker := tailers.NewTailerTracker() endpoints, _ := config.BuildEndpoints(coreConfig, config.HTTPConnectivityFailure, "test-track", "test-proto", "test-source") Init(isRunning, endpoints, sources, tracker, metrics.LogsExpvars) diff --git a/pkg/logs/tailers/docker/tailer.go b/pkg/logs/tailers/docker/tailer.go index 89a5de22ba29e..082821e41fc82 100644 --- a/pkg/logs/tailers/docker/tailer.go +++ b/pkg/logs/tailers/docker/tailer.go @@ -316,7 +316,10 @@ func (t *Tailer) forwardMessages() { origin.Offset = output.ParsingExtra.Timestamp t.setLastSince(output.ParsingExtra.Timestamp) origin.Identifier = t.Identifier() - origin.SetTags(t.tagProvider.GetTags()) + tags := []string{} + tags = append(tags, output.ParsingExtra.Tags...) + tags = append(tags, t.tagProvider.GetTags()...) + origin.SetTags(tags) // XXX(remy): is it OK recreating a message here? t.outputChan <- message.NewMessage(output.GetContent(), origin, output.Status, output.IngestionTimestamp) } diff --git a/pkg/logs/tailers/file/rotate_nix.go b/pkg/logs/tailers/file/rotate_nix.go index db4ac6a66023e..72f1240e6de0e 100644 --- a/pkg/logs/tailers/file/rotate_nix.go +++ b/pkg/logs/tailers/file/rotate_nix.go @@ -22,9 +22,9 @@ import ( // - removed and recreated // - truncated func (t *Tailer) DidRotate() (bool, error) { - f, err := filesystem.OpenShared(t.osFile.Name()) + f, err := filesystem.OpenShared(t.fullpath) if err != nil { - return false, fmt.Errorf("open %q: %w", t.osFile.Name(), err) + return false, fmt.Errorf("open %q: %w", t.fullpath, err) } defer f.Close() lastReadOffset := t.lastReadOffset.Load() diff --git a/pkg/logs/tailers/file/rotate_windows.go b/pkg/logs/tailers/file/rotate_windows.go index 37853d190299a..59ac517a3c240 100644 --- a/pkg/logs/tailers/file/rotate_windows.go +++ b/pkg/logs/tailers/file/rotate_windows.go @@ -21,7 +21,7 @@ import ( func (t *Tailer) DidRotate() (bool, error) { f, err := filesystem.OpenShared(t.fullpath) if err != nil { - return false, fmt.Errorf("open %q: %w", t.osFile.Name(), err) + return false, fmt.Errorf("open %q: %w", t.fullpath, err) } defer f.Close() offset := t.lastReadOffset.Load() diff --git a/pkg/logs/tailers/file/tailer.go b/pkg/logs/tailers/file/tailer.go index 6a9c675f41ee5..b2dacd33ed8ab 100644 --- a/pkg/logs/tailers/file/tailer.go +++ b/pkg/logs/tailers/file/tailer.go @@ -344,7 +344,12 @@ func (t *Tailer) forwardMessages() { origin := message.NewOrigin(t.file.Source.UnderlyingSource()) origin.Identifier = identifier origin.Offset = strconv.FormatInt(offset, 10) - origin.SetTags(append(append(t.tags, t.tagProvider.GetTags()...), output.ParsingExtra.Tags...)) + + tags := make([]string, len(t.tags)) + copy(tags, t.tags) + tags = append(tags, t.tagProvider.GetTags()...) + tags = append(tags, output.ParsingExtra.Tags...) + origin.SetTags(tags) // Ignore empty lines once the registry offset is updated if len(output.GetContent()) == 0 { continue diff --git a/pkg/logs/tailers/file/tailer_test.go b/pkg/logs/tailers/file/tailer_test.go index 66900b2307ced..affdeb992ab65 100644 --- a/pkg/logs/tailers/file/tailer_test.go +++ b/pkg/logs/tailers/file/tailer_test.go @@ -351,6 +351,38 @@ func (suite *TailerTestSuite) TestBuildTagsFileDir() { }, tags) } +func (suite *TailerTestSuite) TestTruncatedTag() { + coreConfig.Datadog().SetWithoutSource("logs_config.max_message_size_bytes", 3) + coreConfig.Datadog().SetWithoutSource("logs_config.tag_truncated_logs", true) + defer coreConfig.Datadog().SetWithoutSource("logs_config.max_message_size_bytes", coreConfig.DefaultMaxMessageSizeBytes) + defer coreConfig.Datadog().SetWithoutSource("logs_config.tag_truncated_logs", false) + + source := sources.NewLogSource("", &config.LogsConfig{ + Type: config.FileType, + Path: suite.testPath, + }) + sleepDuration := 10 * time.Millisecond + info := status.NewInfoRegistry() + + tailerOptions := &TailerOptions{ + OutputChan: suite.outputChan, + File: NewFile(suite.testPath, source, true), + SleepDuration: sleepDuration, + Decoder: decoder.NewDecoderFromSource(suite.source, info), + Info: info, + } + + suite.tailer = NewTailer(tailerOptions) + suite.tailer.StartFromBeginning() + + _, err := suite.testFile.WriteString("1234\n") + suite.Nil(err) + + msg := <-suite.outputChan + tags := msg.Tags() + suite.Contains(tags, message.TruncatedTag) +} + func (suite *TailerTestSuite) TestMutliLineAutoDetect() { lines := "Jul 12, 2021 12:55:15 PM test message 1\n" lines += "Jul 12, 2021 12:55:15 PM test message 2\n" diff --git a/pkg/logs/tailers/socket/tailer.go b/pkg/logs/tailers/socket/tailer.go index 6e23dbad97e91..a2c791997f2df 100644 --- a/pkg/logs/tailers/socket/tailer.go +++ b/pkg/logs/tailers/socket/tailer.go @@ -69,7 +69,9 @@ func (t *Tailer) forwardMessages() { }() for output := range t.decoder.OutputChan { if len(output.GetContent()) > 0 { - t.outputChan <- message.NewMessage(output.GetContent(), output.Origin, output.Status, output.IngestionTimestamp) + origin := message.NewOrigin(t.source) + origin.SetTags(output.ParsingExtra.Tags) + t.outputChan <- message.NewMessage(output.GetContent(), origin, output.Status, output.IngestionTimestamp) } } } @@ -96,7 +98,6 @@ func (t *Tailer) readForever() { log.Warnf("Couldn't read message from connection: %v", err) return } - origin := message.NewOrigin(t.source) copiedTags := make([]string, len(t.source.Config.Tags)) copy(copiedTags, t.source.Config.Tags) if ipAddress != "" && coreConfig.Datadog().GetBool("logs_config.use_sourcehost_tag") { @@ -110,8 +111,9 @@ func (t *Tailer) readForever() { sourceHostTag := fmt.Sprintf("source_host:%s", ipAddressWithoutPort) copiedTags = append(copiedTags, sourceHostTag) } - origin.SetTags(copiedTags) - t.decoder.InputChan <- message.NewMessage(data, origin, message.StatusInfo, 0) + msg := decoder.NewInput(data) + msg.ParsingExtra.Tags = append(msg.ParsingExtra.Tags, copiedTags...) + t.decoder.InputChan <- msg } } } diff --git a/pkg/logs/tailers/windowsevent/tailer_test.go b/pkg/logs/tailers/windowsevent/tailer_test.go index 2d842877acd12..5c8c635314edb 100644 --- a/pkg/logs/tailers/windowsevent/tailer_test.go +++ b/pkg/logs/tailers/windowsevent/tailer_test.go @@ -8,13 +8,15 @@ package windowsevent import ( + "errors" "fmt" "testing" "time" - pkglog "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/cihub/seelog" + pkglog "github.com/DataDog/datadog-agent/pkg/util/log" + "github.com/cenkalti/backoff" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -23,8 +25,8 @@ import ( "github.com/DataDog/datadog-agent/pkg/logs/message" "github.com/DataDog/datadog-agent/pkg/logs/sources" "github.com/DataDog/datadog-agent/pkg/util/testutil/flake" - "github.com/DataDog/datadog-agent/pkg/util/winutil/eventlog/api" - "github.com/DataDog/datadog-agent/pkg/util/winutil/eventlog/test" + evtapi "github.com/DataDog/datadog-agent/pkg/util/winutil/eventlog/api" + eventlog_test "github.com/DataDog/datadog-agent/pkg/util/winutil/eventlog/test" ) type ReadEventsSuite struct { @@ -89,7 +91,7 @@ func newtailer(evtapi evtapi.API, tailerconfig *Config, bookmark string, msgChan if source.Status.IsSuccess() { return nil } else if source.Status.IsError() { - return fmt.Errorf(source.Status.GetError()) + return errors.New(source.Status.GetError()) } return fmt.Errorf("start pending") }, backoff.NewConstantBackOff(50*time.Millisecond)) @@ -198,7 +200,7 @@ func (s *ReadEventsSuite) TestRecoverFromBrokenSubscription() { if tailer.source.Status.IsSuccess() { return nil } else if tailer.source.Status.IsError() { - return fmt.Errorf(tailer.source.Status.GetError()) + return errors.New(tailer.source.Status.GetError()) } return fmt.Errorf("start pending") }, backoff.NewConstantBackOff(50*time.Millisecond)) diff --git a/pkg/logs/util/testutils/go.mod b/pkg/logs/util/testutils/go.mod index be5a2ad4fd7d9..2e1a8cc78da2c 100644 --- a/pkg/logs/util/testutils/go.mod +++ b/pkg/logs/util/testutils/go.mod @@ -14,6 +14,7 @@ replace ( github.com/DataDog/datadog-agent/comp/logs/agent/config => ../../../../comp/logs/agent/config github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../../../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../../../config/env + github.com/DataDog/datadog-agent/pkg/config/mock => ../../../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../../../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../../../config/setup github.com/DataDog/datadog-agent/pkg/config/utils => ../../../config/utils @@ -84,11 +85,11 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/pkg/logs/util/testutils/go.sum b/pkg/logs/util/testutils/go.sum index 79c2fcb395d02..77ba213060c82 100644 --- a/pkg/logs/util/testutils/go.sum +++ b/pkg/logs/util/testutils/go.sum @@ -234,25 +234,25 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -295,11 +295,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -312,8 +312,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/metrics/go.mod b/pkg/metrics/go.mod index b5f58d5bd8bdf..9ddbec9712b46 100644 --- a/pkg/metrics/go.mod +++ b/pkg/metrics/go.mod @@ -74,13 +74,13 @@ require ( 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.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.23.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/pkg/metrics/go.sum b/pkg/metrics/go.sum index f24d81af12b30..a8bc0739ad6c7 100644 --- a/pkg/metrics/go.sum +++ b/pkg/metrics/go.sum @@ -54,8 +54,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -234,7 +232,6 @@ github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -334,24 +331,23 @@ go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5 go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -370,8 +366,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -491,8 +487,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -502,8 +498,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/pkg/metrics/metric_test.go b/pkg/metrics/metric_test.go index bced04754329e..530062011e52e 100644 --- a/pkg/metrics/metric_test.go +++ b/pkg/metrics/metric_test.go @@ -7,7 +7,6 @@ package metrics import ( "encoding/json" - "fmt" "testing" "github.com/stretchr/testify/assert" @@ -35,7 +34,7 @@ func TestAPIMetricTypeMarshal(t *testing.T) { `{"type":"rate"}`, }, } { - t.Run(fmt.Sprintf(tc.Out), func(t *testing.T) { + t.Run(tc.Out, func(t *testing.T) { out, err := json.Marshal(tc.In) assert.NoError(t, err) assert.Equal(t, tc.Out, string(out)) diff --git a/pkg/network/config/config.go b/pkg/network/config/config.go index 026842a9c289f..a5f4c8997c7e3 100644 --- a/pkg/network/config/config.go +++ b/pkg/network/config/config.go @@ -188,6 +188,9 @@ type Config struct { // get flushed on every client request (default 30s check interval) MaxKafkaStatsBuffered int + // MaxPostgresTelemetryBuffer represents the maximum size of the telemetry buffer size for Postgres. + MaxPostgresTelemetryBuffer int + // MaxPostgresStatsBuffered represents the maximum number of Postgres stats we'll buffer in memory. These stats // get flushed on every client request (default 30s check interval) MaxPostgresStatsBuffered int @@ -302,6 +305,8 @@ type Config struct { // buffers (>=5.8) will result in forcing the use of Perf Maps instead. EnableUSMRingBuffers bool + EnableEbpfless bool + // EnableUSMEventStream enables USM to use the event stream instead // of netlink for receiving process events. EnableUSMEventStream bool @@ -360,20 +365,21 @@ func New() *Config { NPMRingbuffersEnabled: cfg.GetBool(join(netNS, "enable_ringbuffers")), - EnableHTTPMonitoring: cfg.GetBool(join(smNS, "enable_http_monitoring")), - EnableHTTP2Monitoring: cfg.GetBool(join(smNS, "enable_http2_monitoring")), - EnableKafkaMonitoring: cfg.GetBool(join(smNS, "enable_kafka_monitoring")), - EnablePostgresMonitoring: cfg.GetBool(join(smNS, "enable_postgres_monitoring")), - EnableRedisMonitoring: cfg.GetBool(join(smNS, "enable_redis_monitoring")), - EnableNativeTLSMonitoring: cfg.GetBool(join(smNS, "tls", "native", "enabled")), - EnableIstioMonitoring: cfg.GetBool(join(smNS, "tls", "istio", "enabled")), - EnvoyPath: cfg.GetString(join(smNS, "tls", "istio", "envoy_path")), - EnableNodeJSMonitoring: cfg.GetBool(join(smNS, "tls", "nodejs", "enabled")), - MaxUSMConcurrentRequests: uint32(cfg.GetInt(join(smNS, "max_concurrent_requests"))), - MaxHTTPStatsBuffered: cfg.GetInt(join(smNS, "max_http_stats_buffered")), - MaxKafkaStatsBuffered: cfg.GetInt(join(smNS, "max_kafka_stats_buffered")), - MaxPostgresStatsBuffered: cfg.GetInt(join(smNS, "max_postgres_stats_buffered")), - MaxRedisStatsBuffered: cfg.GetInt(join(smNS, "max_redis_stats_buffered")), + EnableHTTPMonitoring: cfg.GetBool(join(smNS, "enable_http_monitoring")), + EnableHTTP2Monitoring: cfg.GetBool(join(smNS, "enable_http2_monitoring")), + EnableKafkaMonitoring: cfg.GetBool(join(smNS, "enable_kafka_monitoring")), + EnablePostgresMonitoring: cfg.GetBool(join(smNS, "enable_postgres_monitoring")), + EnableRedisMonitoring: cfg.GetBool(join(smNS, "enable_redis_monitoring")), + EnableNativeTLSMonitoring: cfg.GetBool(join(smNS, "tls", "native", "enabled")), + EnableIstioMonitoring: cfg.GetBool(join(smNS, "tls", "istio", "enabled")), + EnvoyPath: cfg.GetString(join(smNS, "tls", "istio", "envoy_path")), + EnableNodeJSMonitoring: cfg.GetBool(join(smNS, "tls", "nodejs", "enabled")), + MaxUSMConcurrentRequests: uint32(cfg.GetInt(join(smNS, "max_concurrent_requests"))), + MaxHTTPStatsBuffered: cfg.GetInt(join(smNS, "max_http_stats_buffered")), + MaxKafkaStatsBuffered: cfg.GetInt(join(smNS, "max_kafka_stats_buffered")), + MaxPostgresStatsBuffered: cfg.GetInt(join(smNS, "max_postgres_stats_buffered")), + MaxPostgresTelemetryBuffer: cfg.GetInt(join(smNS, "max_postgres_telemetry_buffer")), + MaxRedisStatsBuffered: cfg.GetInt(join(smNS, "max_redis_stats_buffered")), MaxTrackedHTTPConnections: cfg.GetInt64(join(smNS, "max_tracked_http_connections")), HTTPNotificationThreshold: cfg.GetInt64(join(smNS, "http_notification_threshold")), @@ -386,7 +392,7 @@ func New() *Config { EnableConntrackAllNamespaces: cfg.GetBool(join(spNS, "enable_conntrack_all_namespaces")), IgnoreConntrackInitFailure: cfg.GetBool(join(netNS, "ignore_conntrack_init_failure")), ConntrackInitTimeout: cfg.GetDuration(join(netNS, "conntrack_init_timeout")), - EnableEbpfConntracker: true, + EnableEbpfConntracker: cfg.GetBool(join(netNS, "enable_ebpf_conntracker")), EnableGatewayLookup: cfg.GetBool(join(netNS, "enable_gateway_lookup")), @@ -406,6 +412,8 @@ func New() *Config { EnableNPMConnectionRollup: cfg.GetBool(join(netNS, "enable_connection_rollup")), + EnableEbpfless: cfg.GetBool(join(netNS, "enable_ebpfless")), + // Service Monitoring EnableJavaTLSSupport: cfg.GetBool(join(smjtNS, "enabled")), JavaAgentDebug: cfg.GetBool(join(smjtNS, "debug")), diff --git a/pkg/network/config/config_bpf_linux_test.go b/pkg/network/config/config_bpf_linux_test.go index ce380ce174a0d..e37e18136da70 100644 --- a/pkg/network/config/config_bpf_linux_test.go +++ b/pkg/network/config/config_bpf_linux_test.go @@ -14,20 +14,21 @@ import ( "github.com/stretchr/testify/require" sysconfig "github.com/DataDog/datadog-agent/cmd/system-probe/config" + "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/core/telemetry" "github.com/DataDog/datadog-agent/comp/core/telemetry/telemetryimpl" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - aconfig "github.com/DataDog/datadog-agent/pkg/config" + wmmock "github.com/DataDog/datadog-agent/comp/core/workloadmeta/fx-mock" + configmock "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/eventmonitor" emconfig "github.com/DataDog/datadog-agent/pkg/eventmonitor/config" secconfig "github.com/DataDog/datadog-agent/pkg/security/config" "github.com/DataDog/datadog-agent/pkg/util/fxutil" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) func TestEventStreamEnabledForSupportedKernelsLinux(t *testing.T) { t.Setenv("DD_SYSTEM_PROBE_EVENT_MONITORING_NETWORK_PROCESS_ENABLED", strconv.FormatBool(true)) - cfg := aconfig.MockSystemProbe(t) + cfg := configmock.NewSystemProbe(t) sysconfig.Adjust(cfg) if sysconfig.ProcessEventDataStreamSupported() { @@ -38,7 +39,11 @@ func TestEventStreamEnabledForSupportedKernelsLinux(t *testing.T) { opts := eventmonitor.Opts{} telemetry := fxutil.Test[telemetry.Component](t, telemetryimpl.MockModule()) - evm, err := eventmonitor.NewEventMonitor(emconfig, secconfig, opts, optional.NewNoneOption[workloadmeta.Component](), telemetry) + wmeta := fxutil.Test[workloadmeta.Component](t, + core.MockBundle(), + wmmock.MockModule(workloadmeta.NewParams()), + ) + evm, err := eventmonitor.NewEventMonitor(emconfig, secconfig, opts, wmeta, telemetry) require.NoError(t, err) require.NoError(t, evm.Init()) } else { diff --git a/pkg/network/config/config_linux_test.go b/pkg/network/config/config_linux_test.go index 74244d3d06916..3ac7685449ec4 100644 --- a/pkg/network/config/config_linux_test.go +++ b/pkg/network/config/config_linux_test.go @@ -9,15 +9,14 @@ import ( "os" "testing" + "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/stretchr/testify/require" "github.com/vishvananda/netns" - - aconfig "github.com/DataDog/datadog-agent/pkg/config" ) func TestDisableRootNetNamespace(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) t.Setenv("DD_NETWORK_CONFIG_ENABLE_ROOT_NETNS", "false") + mock.NewSystemProbe(t) cfg := New() require.False(t, cfg.EnableConntrackAllNamespaces) diff --git a/pkg/network/config/config_test.go b/pkg/network/config/config_test.go index 30d0598913cde..d732160b00b09 100644 --- a/pkg/network/config/config_test.go +++ b/pkg/network/config/config_test.go @@ -20,8 +20,7 @@ import ( "github.com/stretchr/testify/require" sysconfig "github.com/DataDog/datadog-agent/cmd/system-probe/config" - aconfig "github.com/DataDog/datadog-agent/pkg/config" - "github.com/DataDog/datadog-agent/pkg/config/model" + "github.com/DataDog/datadog-agent/pkg/config/mock" ) // variables for testing config options @@ -33,27 +32,23 @@ const ( invalidHTTPRequestFragment = 600 ) -func makeYamlConfigString(section, entry string, val int) string { - return fmt.Sprintf("\n%s:\n %s: %d", section, entry, val) -} func TestDisablingDNSInspection(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -system_probe_config: - enabled: true - disable_dns_inspection: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("system_probe_config.enabled", true) + mockSystemProbe.SetWithoutSource("system_probe_config.disable_dns_inspection", true) + cfg := New() assert.False(t, cfg.DNSInspection) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_DISABLE_DNS_INSPECTION", "true") + cfg := New() + _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.False(t, cfg.DNSInspection) }) @@ -61,21 +56,19 @@ system_probe_config: func TestDisablingProtocolClassification(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -network_config: - enable_protocol_classification: false -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.enable_protocol_classification", false) + cfg := New() assert.False(t, cfg.ProtocolClassificationEnabled) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_ENABLE_PROTOCOL_CLASSIFICATION", "false") + cfg := New() _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.False(t, cfg.ProtocolClassificationEnabled) }) @@ -83,21 +76,19 @@ network_config: func TestEnableHTTPStatsByStatusCode(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - enable_http_stats_by_status_code: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enable_http_stats_by_status_code", true) + cfg := New() assert.True(t, cfg.EnableHTTPStatsByStatusCode) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_HTTP_STATS_BY_STATUS_CODE", "true") + cfg := New() _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.True(t, cfg.EnableHTTPStatsByStatusCode) }) @@ -105,107 +96,98 @@ service_monitoring_config: func TestEnableHTTPMonitoring(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -network_config: - enable_http_monitoring: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.enable_http_monitoring", true) + cfg := New() assert.True(t, cfg.EnableHTTPMonitoring) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLE_HTTP_MONITORING", "true") + cfg := New() _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.True(t, cfg.EnableHTTPMonitoring) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - enable_http_monitoring: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enable_http_monitoring", true) + cfg := New() assert.True(t, cfg.EnableHTTPMonitoring) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_HTTP_MONITORING", "true") + cfg := New() _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.True(t, cfg.EnableHTTPMonitoring) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLE_HTTP_MONITORING", "true") t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_HTTP_MONITORING", "false") + cfg := New() _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.False(t, cfg.EnableHTTPMonitoring) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLE_HTTP_MONITORING", "false") t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_HTTP_MONITORING", "true") + cfg := New() _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.True(t, cfg.EnableHTTPMonitoring) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLE_HTTP_MONITORING", "true") t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_HTTP_MONITORING", "true") + cfg := New() _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.True(t, cfg.EnableHTTPMonitoring) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() - assert.False(t, cfg.EnableHTTPMonitoring) }) } func TestEnableJavaTLSSupport(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - tls: - java: - enabled: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.tls.java.enabled", true) + cfg := New() + require.True(t, cfg.EnableJavaTLSSupport) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_JAVA_ENABLED", "true") - cfg := New() require.True(t, cfg.EnableJavaTLSSupport) @@ -215,21 +197,20 @@ service_monitoring_config: func TestEnableHTTP2Monitoring(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - enable_http2_monitoring: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enable_http2_monitoring", true) + cfg := New() assert.True(t, cfg.EnableHTTP2Monitoring) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_HTTP2_MONITORING", "true") + cfg := New() + _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.True(t, cfg.EnableHTTP2Monitoring) }) @@ -237,21 +218,20 @@ service_monitoring_config: func TestEnableKafkaMonitoring(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - enable_kafka_monitoring: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enable_kafka_monitoring", true) + cfg := New() assert.True(t, cfg.EnableKafkaMonitoring) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_KAFKA_MONITORING", "true") + cfg := New() + _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.True(t, cfg.EnableKafkaMonitoring) }) @@ -259,27 +239,26 @@ service_monitoring_config: func TestEnablePostgresMonitoring(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - enable_postgres_monitoring: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enable_postgres_monitoring", true) + cfg := New() assert.True(t, cfg.EnablePostgresMonitoring) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_POSTGRES_MONITORING", "true") + cfg := New() + _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.True(t, cfg.EnablePostgresMonitoring) }) t.Run("default", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() assert.False(t, cfg.EnablePostgresMonitoring) @@ -288,27 +267,26 @@ service_monitoring_config: func TestEnableRedisMonitoring(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - enable_redis_monitoring: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enable_redis_monitoring", true) + cfg := New() assert.True(t, cfg.EnableRedisMonitoring) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_REDIS_MONITORING", "true") + cfg := New() + _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.True(t, cfg.EnableRedisMonitoring) }) t.Run("default", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() assert.False(t, cfg.EnableRedisMonitoring) @@ -316,50 +294,47 @@ service_monitoring_config: } func TestDefaultDisabledJavaTLSSupport(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) + cfg := New() _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.False(t, cfg.EnableJavaTLSSupport) } func TestDefaultDisabledHTTP2Support(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) + cfg := New() _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.False(t, cfg.EnableHTTP2Monitoring) } func TestDisableGatewayLookup(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mockSystemProbe := mock.NewSystemProbe(t) + cfg := New() // default config _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.True(t, cfg.EnableGatewayLookup) - aconfig.ResetSystemProbeConfig(t) - cfg = configurationFromYAML(t, ` -network_config: - enable_gateway_lookup: false -`) + mockSystemProbe.SetWithoutSource("network_config.enable_gateway_lookup", false) + cfg = New() assert.False(t, cfg.EnableGatewayLookup) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLE_GATEWAY_LOOKUP", "false") + cfg := New() _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.False(t, cfg.EnableGatewayLookup) }) @@ -367,21 +342,20 @@ network_config: func TestIgnoreConntrackInitFailure(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -network_config: - ignore_conntrack_init_failure: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.ignore_conntrack_init_failure", true) + cfg := New() assert.True(t, cfg.IgnoreConntrackInitFailure) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_IGNORE_CONNTRACK_INIT_FAILURE", "true") + cfg := New() + _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.Nil(t, err) assert.True(t, cfg.IgnoreConntrackInitFailure) @@ -390,56 +364,53 @@ network_config: func TestEnablingDNSStatsCollection(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -system_probe_config: - collect_dns_stats: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("system_probe_config.collect_dns_stats", true) + cfg := New() assert.True(t, cfg.CollectDNSStats) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_COLLECT_DNS_STATS", "false") + cfg := New() + _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.False(t, cfg.CollectDNSStats) - aconfig.ResetSystemProbeConfig(t) t.Setenv("DD_COLLECT_DNS_STATS", "true") _, err = sysconfig.New("", "") require.NoError(t, err) cfg = New() - assert.True(t, cfg.CollectDNSStats) }) } func TestDisablingDNSDomainCollection(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -system_probe_config: - collect_dns_domains: false - max_dns_stats: 100 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("system_probe_config.collect_dns_domains", false) + cfg := New() + + mockSystemProbe.SetWithoutSource("system_probe_config.max_dns_stats", 100) assert.False(t, cfg.CollectDNSDomains) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_COLLECT_DNS_DOMAINS", "false") + cfg := New() + _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.False(t, cfg.CollectDNSDomains) - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_COLLECT_DNS_DOMAINS", "true") _, err = sysconfig.New("", "") require.NoError(t, err) @@ -451,26 +422,23 @@ system_probe_config: func TestSettingMaxDNSStats(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -system_probe_config: - collect_dns_domains: false - max_dns_stats: 100 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("system_probe_config.collect_dns_domains", false) + mockSystemProbe.SetWithoutSource("system_probe_config.max_dns_stats", 100) + cfg := New() assert.Equal(t, 100, cfg.MaxDNSStats) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) + cfg := New() os.Unsetenv("DD_SYSTEM_PROBE_CONFIG_MAX_DNS_STATS") _, err := sysconfig.New("", "") require.NoError(t, err) - cfg := New() assert.Equal(t, 20000, cfg.MaxDNSStats) // default value - aconfig.ResetSystemProbeConfig(t) t.Setenv("DD_SYSTEM_PROBE_CONFIG_MAX_DNS_STATS", "10000") _, err = sysconfig.New("", "") require.NoError(t, err) @@ -512,19 +480,16 @@ func TestHTTPReplaceRules(t *testing.T) { "pattern": "payment_id" } ] - ` + ` t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -network_config: - http_replace_rules: - - pattern: "/users/(.*)" - repl: "/users/?" - - pattern: "foo" - repl: "bar" - - pattern: "payment_id" -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.http_replace_rules", []map[string]string{ + {"pattern": "/users/(.*)", "repl": "/users/?"}, + {"pattern": "foo", "repl": "bar"}, + {"pattern": "payment_id"}, + }) + cfg := New() require.Len(t, cfg.HTTPReplaceRules, 3) for i, r := range expected { @@ -533,9 +498,8 @@ network_config: }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_HTTP_REPLACE_RULES", envContent) - cfg := New() require.Len(t, cfg.HTTPReplaceRules, 3) @@ -545,16 +509,14 @@ network_config: }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - http_replace_rules: - - pattern: "/users/(.*)" - repl: "/users/?" - - pattern: "foo" - repl: "bar" - - pattern: "payment_id" -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.http_replace_rules", []map[string]string{ + {"pattern": "/users/(.*)", "repl": "/users/?"}, + {"pattern": "foo", "repl": "bar"}, + {"pattern": "payment_id"}, + }) + cfg := New() + require.Len(t, cfg.HTTPReplaceRules, 3) for i, r := range expected { assert.Equal(t, r, cfg.HTTPReplaceRules[i]) @@ -562,9 +524,8 @@ service_monitoring_config: }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_REPLACE_RULES", envContent) - cfg := New() require.Len(t, cfg.HTTPReplaceRules, 3) @@ -574,9 +535,8 @@ service_monitoring_config: }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_HTTP_REPLACE_RULES", envContent) - cfg := New() require.Len(t, cfg.HTTPReplaceRules, 3) @@ -586,9 +546,8 @@ service_monitoring_config: }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_REPLACE_RULES", envContent) - cfg := New() require.Len(t, cfg.HTTPReplaceRules, 3) @@ -598,8 +557,10 @@ service_monitoring_config: }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_REPLACE_RULES", envContent) + cfg := New() + // Setting a different value for the old value, as we should override. t.Setenv("DD_SYSTEM_PROBE_NETWORK_HTTP_REPLACE_RULES", ` [ @@ -609,8 +570,6 @@ service_monitoring_config: ] `) - cfg := New() - require.Len(t, cfg.HTTPReplaceRules, 3) for i, r := range expected { assert.Equal(t, r, cfg.HTTPReplaceRules[i]) @@ -618,7 +577,7 @@ service_monitoring_config: }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() assert.Empty(t, cfg.HTTPReplaceRules) @@ -627,75 +586,66 @@ service_monitoring_config: func TestMaxTrackedHTTPConnections(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -network_config: - max_tracked_http_connections: 1025 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.max_tracked_http_connections", 1025) + cfg := New() require.Equal(t, cfg.MaxTrackedHTTPConnections, int64(1025)) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_MAX_TRACKED_HTTP_CONNECTIONS", "1025") - cfg := New() require.Equal(t, cfg.MaxTrackedHTTPConnections, int64(1025)) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - max_tracked_http_connections: 1025 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.max_tracked_http_connections", 1025) + cfg := New() require.Equal(t, cfg.MaxTrackedHTTPConnections, int64(1025)) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_TRACKED_HTTP_CONNECTIONS", "1025") - cfg := New() require.Equal(t, cfg.MaxTrackedHTTPConnections, int64(1025)) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_MAX_TRACKED_HTTP_CONNECTIONS", "1025") - cfg := New() require.Equal(t, cfg.MaxTrackedHTTPConnections, int64(1025)) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_TRACKED_HTTP_CONNECTIONS", "1025") - cfg := New() require.Equal(t, cfg.MaxTrackedHTTPConnections, int64(1025)) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - // Setting a different value + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_MAX_TRACKED_HTTP_CONNECTIONS", "1026") t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_TRACKED_HTTP_CONNECTIONS", "1025") - cfg := New() require.Equal(t, cfg.MaxTrackedHTTPConnections, int64(1025)) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.Equal(t, cfg.MaxTrackedHTTPConnections, int64(1024)) }) @@ -703,27 +653,25 @@ service_monitoring_config: func TestHTTP2DynamicTableMapCleanerInterval(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - http2_dynamic_table_map_cleaner_interval_seconds: 1025 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.http2_dynamic_table_map_cleaner_interval_seconds", 1025) + cfg := New() require.Equal(t, cfg.HTTP2DynamicTableMapCleanerInterval, 1025*time.Second) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP2_DYNAMIC_TABLE_MAP_CLEANER_INTERVAL_SECONDS", "1025") - cfg := New() require.Equal(t, cfg.HTTP2DynamicTableMapCleanerInterval, 1025*time.Second) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.Equal(t, cfg.HTTP2DynamicTableMapCleanerInterval, 30*time.Second) }) @@ -731,75 +679,66 @@ service_monitoring_config: func TestHTTPMapCleanerInterval(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -system_probe_config: - http_map_cleaner_interval_in_s: 1025 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("system_probe_config.http_map_cleaner_interval_in_s", 1025) + cfg := New() require.Equal(t, cfg.HTTPMapCleanerInterval, 1025*time.Second) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_CONFIG_HTTP_MAP_CLEANER_INTERVAL_IN_S", "1025") - cfg := New() require.Equal(t, cfg.HTTPMapCleanerInterval, 1025*time.Second) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - http_map_cleaner_interval_in_s: 1025 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.http_map_cleaner_interval_in_s", 1025) + cfg := New() require.Equal(t, cfg.HTTPMapCleanerInterval, 1025*time.Second) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_MAP_CLEANER_INTERVAL_IN_S", "1025") - cfg := New() require.Equal(t, cfg.HTTPMapCleanerInterval, 1025*time.Second) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_CONFIG_HTTP_MAP_CLEANER_INTERVAL_IN_S", "1025") - cfg := New() require.Equal(t, cfg.HTTPMapCleanerInterval, 1025*time.Second) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_MAP_CLEANER_INTERVAL_IN_S", "1025") - cfg := New() require.Equal(t, cfg.HTTPMapCleanerInterval, 1025*time.Second) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - // Setting a different value + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_CONFIG_HTTP_MAP_CLEANER_INTERVAL_IN_S", "1026") t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_MAP_CLEANER_INTERVAL_IN_S", "1025") - cfg := New() require.Equal(t, cfg.HTTPMapCleanerInterval, 1025*time.Second) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.Equal(t, cfg.HTTPMapCleanerInterval, 300*time.Second) }) @@ -807,74 +746,66 @@ service_monitoring_config: func TestHTTPIdleConnectionTTL(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -system_probe_config: - http_idle_connection_ttl_in_s: 1025 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("system_probe_config.http_idle_connection_ttl_in_s", 1025) + cfg := New() require.Equal(t, cfg.HTTPIdleConnectionTTL, 1025*time.Second) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_CONFIG_HTTP_IDLE_CONNECTION_TTL_IN_S", "1025") - cfg := New() require.Equal(t, cfg.HTTPIdleConnectionTTL, 1025*time.Second) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - http_idle_connection_ttl_in_s: 1025 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.http_idle_connection_ttl_in_s", 1025) + cfg := New() + require.Equal(t, cfg.HTTPIdleConnectionTTL, 1025*time.Second) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_IDLE_CONNECTION_TTL_IN_S", "1025") - cfg := New() require.Equal(t, cfg.HTTPIdleConnectionTTL, 1025*time.Second) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_CONFIG_HTTP_IDLE_CONNECTION_TTL_IN_S", "1025") - cfg := New() require.Equal(t, cfg.HTTPIdleConnectionTTL, 1025*time.Second) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_IDLE_CONNECTION_TTL_IN_S", "1025") - cfg := New() require.Equal(t, cfg.HTTPIdleConnectionTTL, 1025*time.Second) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - // Setting a different value + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_CONFIG_HTTP_IDLE_CONNECTION_TTL_IN_S", "1026") t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_IDLE_CONNECTION_TTL_IN_S", "1025") - cfg := New() require.Equal(t, cfg.HTTPIdleConnectionTTL, 1025*time.Second) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.Equal(t, cfg.HTTPIdleConnectionTTL, 30*time.Second) }) @@ -882,67 +813,64 @@ service_monitoring_config: func TestHTTPNotificationThreshold(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, makeYamlConfigString("network_config", "http_notification_threshold", validNotificationThreshold)) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.http_notification_threshold", validNotificationThreshold) + cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(validNotificationThreshold)) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(validNotificationThreshold)) - cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(validNotificationThreshold)) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, makeYamlConfigString("service_monitoring_config", "http_notification_threshold", validNotificationThreshold)) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.http_notification_threshold", validNotificationThreshold) + cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(validNotificationThreshold)) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(validNotificationThreshold)) - cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(validNotificationThreshold)) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(validNotificationThreshold)) - cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(validNotificationThreshold)) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(validNotificationThreshold)) - cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(validNotificationThreshold)) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - // Setting a different value. + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(validNotificationThreshold+1)) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(validNotificationThreshold)) - cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(validNotificationThreshold)) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.Equal(t, cfg.HTTPNotificationThreshold, int64(driverDefaultNotificationThreshold)) }) @@ -951,69 +879,66 @@ func TestHTTPNotificationThreshold(t *testing.T) { // Testing we're not exceeding the limit for http_notification_threshold. func TestHTTPNotificationThresholdOverLimit(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, makeYamlConfigString("network_config", "http_notification_threshold", invalidNotificationThreshold)) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.http_notification_threshold", invalidNotificationThreshold) + cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(driverDefaultNotificationThreshold)) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(invalidNotificationThreshold)) - cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(driverDefaultNotificationThreshold)) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, makeYamlConfigString("service_monitoring_config", "http_notification_threshold", invalidNotificationThreshold)) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.http_notification_threshold", invalidNotificationThreshold) + cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(driverDefaultNotificationThreshold)) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(invalidNotificationThreshold)) - cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(driverDefaultNotificationThreshold)) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(invalidNotificationThreshold)) - cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(driverDefaultNotificationThreshold)) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(invalidNotificationThreshold)) - cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(driverDefaultNotificationThreshold)) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - // Setting a different value + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(invalidNotificationThreshold+1)) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_NOTIFICATION_THRESHOLD", strconv.Itoa(invalidNotificationThreshold)) - cfg := New() require.Equal(t, cfg.HTTPNotificationThreshold, int64(driverDefaultNotificationThreshold)) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.Equal(t, cfg.HTTPNotificationThreshold, int64(driverDefaultNotificationThreshold)) }) @@ -1021,73 +946,66 @@ func TestHTTPNotificationThresholdOverLimit(t *testing.T) { func TestHTTPMaxRequestFragment(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -network_config: - http_max_request_fragment: 155 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.http_max_request_fragment", 155) + cfg := New() + require.Equal(t, cfg.HTTPMaxRequestFragment, int64(155)) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", "155") - cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(155)) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - http_max_request_fragment: 155 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.http_max_request_fragment", 155) + cfg := New() + require.Equal(t, cfg.HTTPMaxRequestFragment, int64(155)) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", "155") - cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(155)) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", "155") - cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(155)) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", "155") - cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(155)) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - // Setting a different value + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", "151") t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", "155") - cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(155)) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.Equal(t, cfg.HTTPMaxRequestFragment, int64(driverMaxFragmentLimit)) }) @@ -1096,69 +1014,66 @@ service_monitoring_config: // Testing we're not exceeding the hard coded limit of http_max_request_fragment. func TestHTTPMaxRequestFragmentLimit(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, makeYamlConfigString("network_config", "http_max_request_fragment", invalidHTTPRequestFragment)) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.http_max_request_fragment", invalidHTTPRequestFragment) + cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(driverMaxFragmentLimit)) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", strconv.Itoa(invalidHTTPRequestFragment)) - cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(driverMaxFragmentLimit)) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, makeYamlConfigString("service_monitoring_config", "http_max_request_fragment", invalidHTTPRequestFragment)) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.http_max_request_fragment", invalidHTTPRequestFragment) + cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(driverMaxFragmentLimit)) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", strconv.Itoa(invalidHTTPRequestFragment)) - cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(driverMaxFragmentLimit)) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", strconv.Itoa(invalidHTTPRequestFragment)) - cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(512)) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", strconv.Itoa(invalidHTTPRequestFragment)) - cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(driverMaxFragmentLimit)) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - // Setting a different value + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", strconv.Itoa(invalidHTTPRequestFragment)) t.Setenv("DD_SERVICE_MONITORING_CONFIG_HTTP_MAX_REQUEST_FRAGMENT", strconv.Itoa(invalidHTTPRequestFragment+1)) - cfg := New() require.Equal(t, cfg.HTTPMaxRequestFragment, int64(driverMaxFragmentLimit)) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.Equal(t, cfg.HTTPMaxRequestFragment, int64(driverMaxFragmentLimit)) }) @@ -1168,15 +1083,17 @@ func TestMaxClosedConnectionsBuffered(t *testing.T) { maxTrackedConnections := New().MaxTrackedConnections t.Run("value set", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_CONFIG_MAX_CLOSED_CONNECTIONS_BUFFERED", fmt.Sprintf("%d", maxTrackedConnections-1)) cfg := New() + require.Equal(t, maxTrackedConnections-1, cfg.MaxClosedConnectionsBuffered) }) t.Run("value not set", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + require.Equal(t, cfg.MaxTrackedConnections, cfg.MaxClosedConnectionsBuffered) }) } @@ -1185,89 +1102,83 @@ func TestMaxFailedConnectionsBuffered(t *testing.T) { maxTrackedConnections := New().MaxTrackedConnections t.Run("value set", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_NETWORK_CONFIG_MAX_FAILED_CONNECTIONS_BUFFERED", fmt.Sprintf("%d", maxTrackedConnections-1)) cfg := New() + require.Equal(t, maxTrackedConnections-1, cfg.MaxFailedConnectionsBuffered) }) t.Run("value not set", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + require.Equal(t, cfg.MaxTrackedConnections, cfg.MaxFailedConnectionsBuffered) }) } func TestMaxHTTPStatsBuffered(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -network_config: - max_http_stats_buffered: 513 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.max_http_stats_buffered", 513) + cfg := New() require.Equal(t, cfg.MaxHTTPStatsBuffered, 513) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_MAX_HTTP_STATS_BUFFERED", "513") - cfg := New() require.Equal(t, cfg.MaxHTTPStatsBuffered, 513) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - max_http_stats_buffered: 513 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.max_http_stats_buffered", 513) + cfg := New() require.Equal(t, cfg.MaxHTTPStatsBuffered, 513) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_HTTP_STATS_BUFFERED", "513") - cfg := New() require.Equal(t, cfg.MaxHTTPStatsBuffered, 513) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_MAX_HTTP_STATS_BUFFERED", "513") - cfg := New() require.Equal(t, cfg.MaxHTTPStatsBuffered, 513) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_HTTP_STATS_BUFFERED", "513") - cfg := New() require.Equal(t, cfg.MaxHTTPStatsBuffered, 513) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_MAX_HTTP_STATS_BUFFERED", "514") t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_HTTP_STATS_BUFFERED", "513") - cfg := New() require.Equal(t, cfg.MaxHTTPStatsBuffered, 513) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.Equal(t, cfg.MaxHTTPStatsBuffered, 100000) }) @@ -1275,74 +1186,86 @@ service_monitoring_config: func TestMaxKafkaStatsBuffered(t *testing.T) { t.Run("value set through env var", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_KAFKA_STATS_BUFFERED", "50000") - cfg := New() + assert.Equal(t, 50000, cfg.MaxKafkaStatsBuffered) }) t.Run("value set through yaml", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - max_kafka_stats_buffered: 30000 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.max_kafka_stats_buffered", 30000) + cfg := New() assert.Equal(t, 30000, cfg.MaxKafkaStatsBuffered) }) } +func TestMaxPostgresTelemetryBuffered(t *testing.T) { + t.Run("value set through env var", func(t *testing.T) { + mock.NewSystemProbe(t) + t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_POSTGRES_TELEMETRY_BUFFER", "50000") + + cfg := New() + assert.Equal(t, 50000, cfg.MaxPostgresTelemetryBuffer) + }) + + t.Run("value set through yaml", func(t *testing.T) { + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.max_postgres_telemetry_buffer", 30000) + + cfg := New() + assert.Equal(t, 30000, cfg.MaxPostgresTelemetryBuffer) + }) +} + func TestMaxPostgresStatsBuffered(t *testing.T) { t.Run("value set through env var", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_POSTGRES_STATS_BUFFERED", "50000") - cfg := New() + assert.Equal(t, 50000, cfg.MaxPostgresStatsBuffered) }) t.Run("value set through yaml", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - max_postgres_stats_buffered: 30000 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.max_postgres_stats_buffered", 30000) + cfg := New() assert.Equal(t, 30000, cfg.MaxPostgresStatsBuffered) }) t.Run("default", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - + mock.NewSystemProbe(t) cfg := New() + assert.Equal(t, 100000, cfg.MaxPostgresStatsBuffered) }) } func TestMaxRedisStatsBuffered(t *testing.T) { t.Run("value set through env var", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_REDIS_STATS_BUFFERED", "50000") - cfg := New() + assert.Equal(t, 50000, cfg.MaxRedisStatsBuffered) }) t.Run("value set through yaml", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - max_redis_stats_buffered: 30000 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.max_redis_stats_buffered", 30000) + cfg := New() assert.Equal(t, 30000, cfg.MaxRedisStatsBuffered) }) t.Run("default", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - + mock.NewSystemProbe(t) cfg := New() + assert.Equal(t, 100000, cfg.MaxRedisStatsBuffered) }) } @@ -1379,10 +1302,11 @@ func TestNetworkConfigEnabled(t *testing.T) { t.Setenv("DD_SYSTEM_PROBE_SERVICE_MONITORING_ENABLED", strconv.FormatBool(*tc.usmIn)) } - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) + cfg := New() _, err = sysconfig.New(f.Name(), "") require.NoError(t, err) - cfg := New() + assert.Equal(t, tc.npmEnabled, cfg.NPMEnabled, "npm state") assert.Equal(t, tc.usmEnabled, cfg.ServiceMonitoringEnabled, "usm state") }) @@ -1391,200 +1315,184 @@ func TestNetworkConfigEnabled(t *testing.T) { func TestIstioMonitoring(t *testing.T) { t.Run("default value", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + assert.False(t, cfg.EnableIstioMonitoring) }) t.Run("via yaml", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - tls: - istio: - enabled: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.tls.istio.enabled", true) + cfg := New() + assert.True(t, cfg.EnableIstioMonitoring) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_ISTIO_ENABLED", "true") - cfg := New() + assert.True(t, cfg.EnableIstioMonitoring) }) } func TestEnvoyPathConfig(t *testing.T) { t.Run("default value", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + assert.EqualValues(t, cfg.EnvoyPath, "/bin/envoy") }) t.Run("via yaml", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - tls: - istio: - envoy_path: "/test/envoy" -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.tls.istio.envoy_path", "/test/envoy") + cfg := New() + assert.EqualValues(t, "/test/envoy", cfg.EnvoyPath) }) t.Run("value set through env var", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_ISTIO_ENVOY_PATH", "/test/envoy") - cfg := New() + assert.EqualValues(t, "/test/envoy", cfg.EnvoyPath) }) } func TestNodeJSMonitoring(t *testing.T) { t.Run("default value", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + assert.False(t, cfg.EnableNodeJSMonitoring) }) t.Run("via yaml", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - tls: - nodejs: - enabled: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.tls.nodejs.enabled", true) + cfg := New() + assert.True(t, cfg.EnableNodeJSMonitoring) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_NODEJS_ENABLED", "true") - cfg := New() + assert.True(t, cfg.EnableNodeJSMonitoring) }) } func TestUSMEventStream(t *testing.T) { t.Run("default value", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + assert.False(t, cfg.EnableUSMEventStream) }) t.Run("via yaml", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - enable_event_stream: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enable_event_stream", true) + cfg := New() + assert.True(t, cfg.EnableUSMEventStream) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_EVENT_STREAM", "true") - cfg := New() + assert.True(t, cfg.EnableUSMEventStream) }) } func TestMaxUSMConcurrentRequests(t *testing.T) { t.Run("default value", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Assert that if not explicitly set this param defaults to `MaxTrackedConnections` // Note this behavior should be deprecated on 7.50 assert.Equal(t, cfg.MaxTrackedConnections, cfg.MaxUSMConcurrentRequests) }) t.Run("via yaml", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - max_concurrent_requests: 1000 -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.max_concurrent_requests", 1000) + cfg := New() + assert.Equal(t, uint32(1000), cfg.MaxUSMConcurrentRequests) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_MAX_CONCURRENT_REQUESTS", "3000") - cfg := New() + assert.Equal(t, uint32(3000), cfg.MaxUSMConcurrentRequests) }) } func TestUSMTLSNativeEnabled(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -network_config: - enable_https_monitoring: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.enable_https_monitoring", true) + cfg := New() require.True(t, cfg.EnableNativeTLSMonitoring) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLE_HTTPS_MONITORING", "true") - cfg := New() require.True(t, cfg.EnableNativeTLSMonitoring) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - tls: - native: - enabled: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.tls.native.enabled", true) + cfg := New() + require.True(t, cfg.EnableNativeTLSMonitoring) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_NATIVE_ENABLED", "true") - cfg := New() require.True(t, cfg.EnableNativeTLSMonitoring) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLE_HTTPS_MONITORING", "true") t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_NATIVE_ENABLED", "false") - cfg := New() require.False(t, cfg.EnableNativeTLSMonitoring) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLE_HTTPS_MONITORING", "false") t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_NATIVE_ENABLED", "true") - cfg := New() require.True(t, cfg.EnableNativeTLSMonitoring) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - // Setting a different value + mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLE_HTTPS_MONITORING", "true") t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_NATIVE_ENABLED", "true") cfg := New() @@ -1593,8 +1501,9 @@ service_monitoring_config: }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.False(t, cfg.EnableNativeTLSMonitoring) }) @@ -1602,67 +1511,57 @@ service_monitoring_config: func TestUSMTLSGoEnabled(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - enable_go_tls_support: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enable_go_tls_support", true) + cfg := New() require.True(t, cfg.EnableGoTLSSupport) }) t.Run("via deprecated ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_GO_TLS_SUPPORT", "true") - cfg := New() require.True(t, cfg.EnableGoTLSSupport) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - tls: - go: - enabled: true -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.tls.go.enabled", true) + cfg := New() + require.True(t, cfg.EnableGoTLSSupport) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_GO_ENABLED", "true") - cfg := New() require.True(t, cfg.EnableGoTLSSupport) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_GO_TLS_SUPPORT", "true") + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_GO_ENABLED", "false") - + t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_GO_TLS_SUPPORT", "true") cfg := New() require.False(t, cfg.EnableGoTLSSupport) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_GO_TLS_SUPPORT", "false") t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_GO_ENABLED", "true") - cfg := New() require.True(t, cfg.EnableGoTLSSupport) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - // Setting a different value + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_ENABLE_GO_TLS_SUPPORT", "true") t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_GO_ENABLED", "true") cfg := New() @@ -1671,8 +1570,9 @@ service_monitoring_config: }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.False(t, cfg.EnableGoTLSSupport) }) @@ -1680,28 +1580,25 @@ service_monitoring_config: func TestUSMTLSGoExcludeSelf(t *testing.T) { t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := configurationFromYAML(t, ` -service_monitoring_config: - tls: - go: - exclude_self: false -`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.tls.go.exclude_self", false) + cfg := New() + require.False(t, cfg.GoTLSExcludeSelf) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_GO_EXCLUDE_SELF", "false") - cfg := New() require.False(t, cfg.GoTLSExcludeSelf) }) t.Run("Not disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mock.NewSystemProbe(t) cfg := New() + // Default value. require.True(t, cfg.GoTLSExcludeSelf) }) @@ -1709,103 +1606,83 @@ service_monitoring_config: func TestProcessServiceInference(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := modelCfgFromYAML(t, ` -service_monitoring_config: - enabled: true - process_service_inference: - enabled: true`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enabled", true) + mockSystemProbe.SetWithoutSource("service_monitoring_config.process_service_inference.enabled", true) + New() - require.True(t, cfg.GetBool("system_probe_config.process_service_inference.enabled")) + require.True(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.enabled")) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mockSystemProbe := mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLED", "true") t.Setenv("DD_SYSTEM_PROBE_PROCESS_SERVICE_INFERENCE_ENABLED", "true") - cfg := aconfig.SystemProbe() - sysconfig.Adjust(cfg) + New() + sysconfig.Adjust(mockSystemProbe) - require.True(t, cfg.GetBool("system_probe_config.process_service_inference.enabled")) + require.True(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.enabled")) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := modelCfgFromYAML(t, ` -network_config: - enabled: true -system_probe_config: - process_service_inference: - enabled: true`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("network_config.enabled", true) + mockSystemProbe.SetWithoutSource("system_probe_config.process_service_inference.enabled", true) + New() - require.True(t, cfg.GetBool("system_probe_config.process_service_inference.enabled")) + require.True(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.enabled")) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - - cfg := modelCfgFromYAML(t, ` -service_monitoring_config: - enabled: true - process_service_inference: - enabled: true -system_probe_config: - process_service_inference: - enabled: false`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enabled", true) + mockSystemProbe.SetWithoutSource("service_monitoring_config.process_service_inference.enabled", true) + mockSystemProbe.SetWithoutSource("system_probe_config.process_service_inference.enabled", false) + New() - require.False(t, cfg.GetBool("system_probe_config.process_service_inference.enabled")) + require.False(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.enabled")) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enabled", true) + mockSystemProbe.SetWithoutSource("service_monitoring_config.process_service_inference.enabled", false) + mockSystemProbe.SetWithoutSource("system_probe_config.process_service_inference.enabled", true) - cfg := modelCfgFromYAML(t, ` -service_monitoring_config: - enabled: true - process_service_inference: - enabled: false -system_probe_config: - process_service_inference: - enabled: true`) + New() - require.True(t, cfg.GetBool("system_probe_config.process_service_inference.enabled")) + require.True(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.enabled")) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := modelCfgFromYAML(t, ` -service_monitoring_config: - enabled: true - process_service_inference: - enabled: true -system_probe_config: - process_service_inference: - enabled: true`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enabled", true) + mockSystemProbe.SetWithoutSource("service_monitoring_config.process_service_inference.enabled", true) + mockSystemProbe.SetWithoutSource("system_probe_config.process_service_inference.enabled", true) - require.True(t, cfg.GetBool("system_probe_config.process_service_inference.enabled")) + New() + + require.True(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.enabled")) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := modelCfgFromYAML(t, ``) - require.False(t, cfg.GetBool("system_probe_config.process_service_inference.enabled")) + mockSystemProbe := mock.NewSystemProbe(t) + New() + require.False(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.enabled")) }) t.Run("Enabled without net, dsm, sm enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := modelCfgFromYAML(t, ` -system_probe_config: - process_service_inference: - enabled: true`) - require.False(t, cfg.GetBool("system_probe_config.process_service_inference.enabled")) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("system_probe_config.process_service_inference.enabled", true) + New() + require.False(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.enabled")) }) t.Run("test platform specific defaults", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mockSystemProbe := mock.NewSystemProbe(t) // usm or npm must be enabled for the process_service_inference to be enabled - cfg := modelCfgFromYAML(t, ` -service_monitoring_config: - enabled: true`) - sysconfig.Adjust(cfg) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enabled", true) + New() + sysconfig.Adjust(mockSystemProbe) var expected bool if runtime.GOOS == "windows" { @@ -1814,130 +1691,72 @@ service_monitoring_config: expected = false } - require.Equal(t, expected, cfg.GetBool("system_probe_config.process_service_inference.enabled")) + require.Equal(t, expected, mockSystemProbe.GetBool("system_probe_config.process_service_inference.enabled")) }) } func TestProcessServiceInferenceWindows(t *testing.T) { t.Run("via deprecated YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := modelCfgFromYAML(t, ` -service_monitoring_config: - enabled: true - process_service_inference: - use_windows_service_name: true`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enabled", true) + mockSystemProbe.SetWithoutSource("service_monitoring_config.process_service_inference.use_windows_service_name", true) + New() - require.True(t, cfg.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) + require.True(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) }) t.Run("via ENV variable", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mockSystemProbe := mock.NewSystemProbe(t) t.Setenv("DD_SYSTEM_PROBE_NETWORK_ENABLED", "true") t.Setenv("DD_SYSTEM_PROBE_PROCESS_SERVICE_INFERENCE_USE_WINDOWS_SERVICE_NAME", "true") - cfg := aconfig.SystemProbe() - sysconfig.Adjust(cfg) + sysconfig.Adjust(mockSystemProbe) + New() - require.True(t, cfg.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) + require.True(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) }) t.Run("via YAML", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := modelCfgFromYAML(t, ` -network_config: - enabled: true -system_probe_config: - process_service_inference: - use_windows_service_name: true`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enabled", true) + mockSystemProbe.SetWithoutSource("service_monitoring_config.process_service_inference.use_windows_service_name", true) + New() - require.True(t, cfg.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) + require.True(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) }) t.Run("Deprecated is enabled, new is disabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) + mockSystemProbe := mock.NewSystemProbe(t) - cfg := modelCfgFromYAML(t, ` -service_monitoring_config: - enabled: true - process_service_inference: - use_windows_service_name: true -system_probe_config: - process_service_inference: - use_windows_service_name: false`) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enabled", true) + mockSystemProbe.SetWithoutSource("service_monitoring_config.process_service_inference.use_windows_service_name", true) + mockSystemProbe.SetWithoutSource("system_probe_config.process_service_inference.use_windows_service_name", false) + New() - require.False(t, cfg.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) + require.False(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) }) t.Run("Deprecated is disabled, new is enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - - cfg := modelCfgFromYAML(t, ` -service_monitoring_config: - enabled: true - process_service_inference: - use_windows_service_name: false -system_probe_config: - process_service_inference: - use_windows_service_name: true`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enabled", true) + mockSystemProbe.SetWithoutSource("service_monitoring_config.process_service_inference.use_windows_service_name", false) + mockSystemProbe.SetWithoutSource("system_probe_config.process_service_inference.use_windows_service_name", true) + New() - require.True(t, cfg.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) + require.True(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) }) t.Run("Both enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - // Setting a different value - cfg := modelCfgFromYAML(t, ` -service_monitoring_config: - enabled: true - process_service_inference: - use_windows_service_name: true -system_probe_config: - process_service_inference: - use_windows_service_name: true`) + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.enabled", true) + mockSystemProbe.SetWithoutSource("service_monitoring_config.process_service_inference.use_windows_service_name", true) + mockSystemProbe.SetWithoutSource("system_probe_config.process_service_inference.use_windows_service_name", true) - require.True(t, cfg.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) + require.True(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) }) t.Run("Not enabled", func(t *testing.T) { - aconfig.ResetSystemProbeConfig(t) - cfg := modelCfgFromYAML(t, ` -system_probe_config: - process_service_inference: - use_windows_service_name: false`) - require.False(t, cfg.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) - }) -} + mockSystemProbe := mock.NewSystemProbe(t) + mockSystemProbe.SetWithoutSource("service_monitoring_config.process_service_inference.use_windows_service_name", false) -func configurationFromYAML(t *testing.T, yaml string) *Config { - f, err := os.CreateTemp("", "system-probe.*.yaml") - require.NoError(t, err) - defer os.Remove(f.Name()) - - b := []byte(yaml) - n, err := f.Write(b) - require.NoError(t, err) - require.Equal(t, len(b), n) - f.Sync() - - _, err = sysconfig.New(f.Name(), "") - require.NoError(t, err) - return New() -} - -func modelCfgFromYAML(t *testing.T, yaml string) model.Config { - f, err := os.CreateTemp("", "system-probe.*.yaml") - require.NoError(t, err) - defer os.Remove(f.Name()) - - b := []byte(yaml) - n, err := f.Write(b) - require.NoError(t, err) - require.Equal(t, len(b), n) - f.Sync() - - _, err = sysconfig.New(f.Name(), "") - - require.NoError(t, err) - cfg := aconfig.SystemProbe() - sysconfig.Adjust(cfg) - - return cfg + require.False(t, mockSystemProbe.GetBool("system_probe_config.process_service_inference.use_windows_service_name")) + }) } diff --git a/pkg/network/dns/driver_windows.go b/pkg/network/dns/driver_windows.go index 82e0cb3e88529..3056d38c25cdd 100644 --- a/pkg/network/dns/driver_windows.go +++ b/pkg/network/dns/driver_windows.go @@ -23,6 +23,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/telemetry" "github.com/DataDog/datadog-agent/pkg/network/driver" + "github.com/DataDog/datadog-agent/pkg/network/filter" ) const ( @@ -99,7 +100,7 @@ func (d *dnsDriver) SetDataFilters(filters []driver.FilterDefinition) error { } // ReadDNSPacket visits a raw DNS packet if one is available. -func (d *dnsDriver) ReadDNSPacket(visit func([]byte, time.Time) error) (didRead bool, err error) { +func (d *dnsDriver) ReadDNSPacket(visit func(data []byte, info filter.PacketInfo, t time.Time) error) (didRead bool, err error) { var bytesRead uint32 var key uintptr // returned by GetQueuedCompletionStatus, then ignored var ol *windows.Overlapped @@ -125,7 +126,7 @@ func (d *dnsDriver) ReadDNSPacket(visit func([]byte, time.Time) error) (didRead start := driver.FilterPacketHeaderSize - if err := visit(buf.data[start:], captureTime); err != nil { + if err := visit(buf.data[start:], nil, captureTime); err != nil { return false, err } diff --git a/pkg/network/dns/monitor_linux.go b/pkg/network/dns/monitor_linux.go index af87db20f2ee7..bd8c606415f0f 100644 --- a/pkg/network/dns/monitor_linux.go +++ b/pkg/network/dns/monitor_linux.go @@ -11,17 +11,14 @@ import ( "fmt" "math" - "golang.org/x/net/bpf" - - "github.com/vishvananda/netns" - manager "github.com/DataDog/ebpf-manager" + "github.com/vishvananda/netns" "github.com/DataDog/datadog-agent/comp/core/telemetry" ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" "github.com/DataDog/datadog-agent/pkg/network/config" "github.com/DataDog/datadog-agent/pkg/network/ebpf/probes" - filterpkg "github.com/DataDog/datadog-agent/pkg/network/filter" + "github.com/DataDog/datadog-agent/pkg/network/filter" "github.com/DataDog/datadog-agent/pkg/util/kernel" "github.com/DataDog/datadog-agent/pkg/util/log" ) @@ -33,6 +30,26 @@ type dnsMonitor struct { // NewReverseDNS starts snooping on DNS traffic to allow IP -> domain reverse resolution func NewReverseDNS(cfg *config.Config, _ telemetry.Component) (ReverseDNS, error) { + // Create the RAW_SOCKET inside the root network namespace + var ( + packetSrc *filter.AFPacketSource + srcErr error + ns netns.NsHandle + ) + ns, err := cfg.GetRootNetNs() + if err != nil { + return nil, err + } + defer ns.Close() + + err = kernel.WithNS(ns, func() error { + packetSrc, srcErr = filter.NewAFPacketSource(4 << 20) // 4 MB total + return srcErr + }) + if err != nil { + return nil, err + } + currKernelVersion, err := kernel.HostVersion() if err != nil { // if the platform couldn't be determined, treat it as new kernel case @@ -42,12 +59,11 @@ func NewReverseDNS(cfg *config.Config, _ telemetry.Component) (ReverseDNS, error pre410Kernel := currKernelVersion < kernel.VersionCode(4, 1, 0) var p *ebpfProgram - var filter *manager.Probe - var bpfFilter []bpf.RawInstruction - if pre410Kernel { - bpfFilter, err = generateBPFFilter(cfg) - if err != nil { + if pre410Kernel || cfg.EnableEbpfless { + if bpfFilter, err := generateBPFFilter(cfg); err != nil { return nil, fmt.Errorf("error creating bpf classic filter: %w", err) + } else if err = packetSrc.SetBPF(bpfFilter); err != nil { + return nil, fmt.Errorf("could not set BPF filter on packet source: %w", err) } } else { p, err = newEBPFProgram(cfg) @@ -59,35 +75,21 @@ func NewReverseDNS(cfg *config.Config, _ telemetry.Component) (ReverseDNS, error return nil, fmt.Errorf("error initializing ebpf programs: %w", err) } - filter, _ = p.GetProbe(manager.ProbeIdentificationPair{EBPFFuncName: probes.SocketDNSFilter, UID: probeUID}) + filter, _ := p.GetProbe(manager.ProbeIdentificationPair{EBPFFuncName: probes.SocketDNSFilter, UID: probeUID}) if filter == nil { return nil, fmt.Errorf("error retrieving socket filter") } - } - // Create the RAW_SOCKET inside the root network namespace - var ( - packetSrc *filterpkg.AFPacketSource - srcErr error - ns netns.NsHandle - ) - if ns, err = cfg.GetRootNetNs(); err != nil { - return nil, err - } - defer ns.Close() - - err = kernel.WithNS(ns, func() error { - packetSrc, srcErr = filterpkg.NewPacketSource(filter, bpfFilter) - return srcErr - }) - if err != nil { - return nil, err + if err = packetSrc.SetEbpf(filter); err != nil { + return nil, fmt.Errorf("could not set file descriptor for eBPF program: %w", err) + } } snoop, err := newSocketFilterSnooper(cfg, packetSrc) if err != nil { return nil, err } + return &dnsMonitor{ snoop, p, diff --git a/pkg/network/dns/packet_source_windows.go b/pkg/network/dns/packet_source_windows.go index 5a00280591eda..52ae79ffa4cef 100644 --- a/pkg/network/dns/packet_source_windows.go +++ b/pkg/network/dns/packet_source_windows.go @@ -14,16 +14,17 @@ import ( "github.com/google/gopacket/layers" "github.com/DataDog/datadog-agent/comp/core/telemetry" + "github.com/DataDog/datadog-agent/pkg/network/filter" ) -var _ packetSource = &windowsPacketSource{} +var _ filter.PacketSource = &windowsPacketSource{} type windowsPacketSource struct { di *dnsDriver } // newWindowsPacketSource constructs a new packet source -func newWindowsPacketSource(telemetrycomp telemetry.Component) (packetSource, error) { +func newWindowsPacketSource(telemetrycomp telemetry.Component) (filter.PacketSource, error) { di, err := newDriver(telemetrycomp) if err != nil { return nil, err @@ -31,7 +32,7 @@ func newWindowsPacketSource(telemetrycomp telemetry.Component) (packetSource, er return &windowsPacketSource{di: di}, nil } -func (p *windowsPacketSource) VisitPackets(exit <-chan struct{}, visit func([]byte, time.Time) error) error { +func (p *windowsPacketSource) VisitPackets(exit <-chan struct{}, visit func([]byte, filter.PacketInfo, time.Time) error) error { for { didReadPacket, err := p.di.ReadDNSPacket(visit) if err != nil { @@ -50,7 +51,7 @@ func (p *windowsPacketSource) VisitPackets(exit <-chan struct{}, visit func([]by } } -func (p *windowsPacketSource) PacketType() gopacket.LayerType { +func (p *windowsPacketSource) LayerType() gopacket.LayerType { return layers.LayerTypeIPv4 } diff --git a/pkg/network/dns/snooper.go b/pkg/network/dns/snooper.go index e392a96bca550..c1bc700a33b3c 100644 --- a/pkg/network/dns/snooper.go +++ b/pkg/network/dns/snooper.go @@ -11,9 +11,8 @@ import ( "sync" "time" - "github.com/google/gopacket" - "github.com/DataDog/datadog-agent/pkg/network/config" + "github.com/DataDog/datadog-agent/pkg/network/filter" "github.com/DataDog/datadog-agent/pkg/process/util" "github.com/DataDog/datadog-agent/pkg/telemetry" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -45,7 +44,7 @@ var _ ReverseDNS = &socketFilterSnooper{} // socketFilterSnooper is a DNS traffic snooper built on top of an eBPF SOCKET_FILTER type socketFilterSnooper struct { - source packetSource + source filter.PacketSource parser *dnsParser cache *reverseDNSCache statKeeper *dnsStatKeeper @@ -62,24 +61,8 @@ func (s *socketFilterSnooper) WaitForDomain(domain string) error { return s.statKeeper.WaitForDomain(domain) } -// packetSource reads raw packet data -type packetSource interface { - // VisitPackets reads all new raw packets that are available, invoking the given callback for each packet. - // If no packet is available, VisitPacket returns immediately. - // The format of the packet is dependent on the implementation of packetSource -- i.e. it may be an ethernet frame, or a IP frame. - // The data buffer is reused between invocations of VisitPacket and thus should not be pointed to. - // If the cancel channel is closed, VisitPackets will stop reading. - VisitPackets(cancel <-chan struct{}, visitor func(data []byte, timestamp time.Time) error) error - - // PacketType returns the type of packet this source reads - PacketType() gopacket.LayerType - - // Close closes the packet source - Close() -} - // newSocketFilterSnooper returns a new socketFilterSnooper -func newSocketFilterSnooper(cfg *config.Config, source packetSource) (*socketFilterSnooper, error) { +func newSocketFilterSnooper(cfg *config.Config, source filter.PacketSource) (*socketFilterSnooper, error) { cache := newReverseDNSCache(dnsCacheSize, dnsCacheExpirationPeriod) var statKeeper *dnsStatKeeper if cfg.CollectDNSStats { @@ -93,7 +76,7 @@ func newSocketFilterSnooper(cfg *config.Config, source packetSource) (*socketFil } snooper := &socketFilterSnooper{ source: source, - parser: newDNSParser(source.PacketType(), cfg), + parser: newDNSParser(source.LayerType(), cfg), cache: cache, statKeeper: statKeeper, translation: new(translation), @@ -154,7 +137,7 @@ func (s *socketFilterSnooper) Close() { // The *translation is recycled and re-used in subsequent calls and it should not be accessed concurrently. // The second parameter `ts` is the time when the packet was captured off the wire. This is used for latency calculation // and much more reliable than calling time.Now() at the user layer. -func (s *socketFilterSnooper) processPacket(data []byte, ts time.Time) error { +func (s *socketFilterSnooper) processPacket(data []byte, _ filter.PacketInfo, ts time.Time) error { t := s.getCachedTranslation() pktInfo := dnsPacketInfo{} diff --git a/pkg/network/dns/snooper_test.go b/pkg/network/dns/snooper_test.go index 3c79c25bb7e59..3a0d334c80488 100644 --- a/pkg/network/dns/snooper_test.go +++ b/pkg/network/dns/snooper_test.go @@ -390,7 +390,7 @@ func TestParsingError(t *testing.T) { reverseDNS := rdns.(*dnsMonitor) // Pass a byte array of size 1 which should result in parsing error - err = reverseDNS.processPacket(make([]byte, 1), time.Now()) + err = reverseDNS.processPacket(make([]byte, 1), 0, time.Now()) require.NoError(t, err) assert.True(t, cacheTelemetry.length.Load() == 0) assert.True(t, snooperTelemetry.decodingErrors.Load() == 1) diff --git a/pkg/network/ebpf/c/protocols/events-types.h b/pkg/network/ebpf/c/protocols/events-types.h index 6ffa4c28f1f88..5c0e91357fbc2 100644 --- a/pkg/network/ebpf/c/protocols/events-types.h +++ b/pkg/network/ebpf/c/protocols/events-types.h @@ -6,6 +6,9 @@ #define BATCH_BUFFER_SIZE (4*1024) #define BATCH_PAGES_PER_CPU 8 +// Computes the max number of elements of type `Type` in a batch. +#define MAX_BATCH_SIZE(Type) ((BATCH_BUFFER_SIZE) / sizeof(Type)) + typedef struct { // idx is a monotonic counter used for uniquely determining a batch within a CPU core // this is useful for detecting race conditions that result in a batch being overwritten diff --git a/pkg/network/ebpf/c/protocols/http/types.h b/pkg/network/ebpf/c/protocols/http/types.h index d0c288b4ce69f..8da20a8044f16 100644 --- a/pkg/network/ebpf/c/protocols/http/types.h +++ b/pkg/network/ebpf/c/protocols/http/types.h @@ -5,8 +5,6 @@ // This determines the size of the payload fragment that is captured for each HTTP request #define HTTP_BUFFER_SIZE (8 * 26) -// This controls the number of HTTP transactions read from userspace at a time -#define HTTP_BATCH_SIZE 14 // HTTP/1.1 XXX // _________^ diff --git a/pkg/network/ebpf/c/protocols/http/usm-events.h b/pkg/network/ebpf/c/protocols/http/usm-events.h index 9a19fa2d5f1aa..6f6a9e8aa2842 100644 --- a/pkg/network/ebpf/c/protocols/http/usm-events.h +++ b/pkg/network/ebpf/c/protocols/http/usm-events.h @@ -4,6 +4,9 @@ #include "protocols/events.h" #include "protocols/http/types.h" +// This controls the number of HTTP transactions read from userspace at a time +#define HTTP_BATCH_SIZE (MAX_BATCH_SIZE(http_event_t)) + USM_EVENTS_INIT(http, http_event_t, HTTP_BATCH_SIZE); #endif diff --git a/pkg/network/ebpf/c/protocols/http2/decoding-defs.h b/pkg/network/ebpf/c/protocols/http2/decoding-defs.h index 4e39650255fa1..ed795398d5e81 100644 --- a/pkg/network/ebpf/c/protocols/http2/decoding-defs.h +++ b/pkg/network/ebpf/c/protocols/http2/decoding-defs.h @@ -71,11 +71,11 @@ #define HTTP2_END_OF_STREAM 0x1 // Http2 max batch size. -#define HTTP2_BATCH_SIZE 15 +#define HTTP2_BATCH_SIZE (MAX_BATCH_SIZE(http2_event_t)) // The max number of events we can have in a single page in the batch_events array. // See more details in the comments of the USM_EVENTS_INIT. -#define HTTP2_TERMINATED_BATCH_SIZE 80 +#define HTTP2_TERMINATED_BATCH_SIZE (MAX_BATCH_SIZE(conn_tuple_t)) // MAX_4_BITS represents the maximum number that can be represented with 4 bits or less. // 1 << 4 - 1 diff --git a/pkg/network/ebpf/c/protocols/kafka/defs.h b/pkg/network/ebpf/c/protocols/kafka/defs.h index 2dba86ead4d8a..1dc1b8eaf3fd5 100644 --- a/pkg/network/ebpf/c/protocols/kafka/defs.h +++ b/pkg/network/ebpf/c/protocols/kafka/defs.h @@ -42,9 +42,6 @@ // prevent seeing out-of-order packets has seen more testing. #define KAFKA_MAX_ABORTED_TRANSACTIONS 10000 -// This controls the number of Kafka transactions read from userspace at a time -#define KAFKA_BATCH_SIZE 25 - // The amount of buckets we have for the kafka topic name length telemetry. #define KAFKA_TELEMETRY_TOPIC_NAME_NUM_OF_BUCKETS 10 diff --git a/pkg/network/ebpf/c/protocols/kafka/kafka-parsing.h b/pkg/network/ebpf/c/protocols/kafka/kafka-parsing.h index 32f8fe07e1fb5..5ee3697c4aa9a 100644 --- a/pkg/network/ebpf/c/protocols/kafka/kafka-parsing.h +++ b/pkg/network/ebpf/c/protocols/kafka/kafka-parsing.h @@ -784,7 +784,6 @@ static __always_inline enum parse_result kafka_continue_parse_response_record_ba u32 api_version) { u32 orig_offset = offset; - // u32 carry_over_offset = response->carry_over_offset; enum parse_result ret; extra_debug("carry_over_offset %d", response->carry_over_offset); diff --git a/pkg/network/ebpf/c/protocols/kafka/usm-events.h b/pkg/network/ebpf/c/protocols/kafka/usm-events.h index 19a898d48a761..23b018d3e6fb9 100644 --- a/pkg/network/ebpf/c/protocols/kafka/usm-events.h +++ b/pkg/network/ebpf/c/protocols/kafka/usm-events.h @@ -4,6 +4,9 @@ #include "protocols/kafka/types.h" #include "protocols/events.h" +// This controls the number of Kafka transactions read from userspace at a time +#define KAFKA_BATCH_SIZE (MAX_BATCH_SIZE(kafka_event_t)) + USM_EVENTS_INIT(kafka, kafka_event_t, KAFKA_BATCH_SIZE); #endif diff --git a/pkg/network/ebpf/c/protocols/postgres/types.h b/pkg/network/ebpf/c/protocols/postgres/types.h index 40067bd71216f..71521972a22bb 100644 --- a/pkg/network/ebpf/c/protocols/postgres/types.h +++ b/pkg/network/ebpf/c/protocols/postgres/types.h @@ -3,9 +3,6 @@ #include "conn_tuple.h" -// Controls the number of Postgres transactions read from userspace at a time. -#define POSTGRES_BATCH_SIZE 17 - // Maximum length of Postgres query to send to userspace. #define POSTGRES_BUFFER_SIZE 160 diff --git a/pkg/network/ebpf/c/protocols/postgres/usm-events.h b/pkg/network/ebpf/c/protocols/postgres/usm-events.h index 1e178a9a2685c..63a9169ecc35c 100644 --- a/pkg/network/ebpf/c/protocols/postgres/usm-events.h +++ b/pkg/network/ebpf/c/protocols/postgres/usm-events.h @@ -4,6 +4,9 @@ #include "protocols/events.h" #include "protocols/postgres/types.h" +// Controls the number of Postgres transactions read from userspace at a time. +#define POSTGRES_BATCH_SIZE (MAX_BATCH_SIZE(postgres_event_t)) + USM_EVENTS_INIT(postgres, postgres_event_t, POSTGRES_BATCH_SIZE); #endif diff --git a/pkg/network/encoding/encoding_test.go b/pkg/network/encoding/encoding_test.go index a0f2f10d898c5..c23a02a8d3cc2 100644 --- a/pkg/network/encoding/encoding_test.go +++ b/pkg/network/encoding/encoding_test.go @@ -20,6 +20,7 @@ import ( model "github.com/DataDog/agent-payload/v5/process" "github.com/DataDog/datadog-agent/pkg/config" + configmock "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/network" "github.com/DataDog/datadog-agent/pkg/network/dns" "github.com/DataDog/datadog-agent/pkg/network/encoding/marshal" @@ -322,7 +323,7 @@ func testSerialization(t *testing.T, aggregateByStatusCode bool) { require.NoError(t, err) t.Run("requesting application/json serialization (no query types)", func(t *testing.T) { - config.MockSystemProbe(t) + configmock.NewSystemProbe(t) config.SystemProbe().SetWithoutSource("system_probe_config.collect_dns_domains", false) out := getExpectedConnections(false, httpOutBlob) assert := assert.New(t) @@ -344,7 +345,7 @@ func testSerialization(t *testing.T, aggregateByStatusCode bool) { }) t.Run("requesting application/json serialization (with query types)", func(t *testing.T) { - config.MockSystemProbe(t) + configmock.NewSystemProbe(t) config.SystemProbe().SetWithoutSource("system_probe_config.collect_dns_domains", false) config.SystemProbe().SetWithoutSource("network_config.enable_dns_by_querytype", true) out := getExpectedConnections(true, httpOutBlob) @@ -368,7 +369,7 @@ func testSerialization(t *testing.T, aggregateByStatusCode bool) { }) t.Run("requesting empty serialization", func(t *testing.T) { - config.MockSystemProbe(t) + configmock.NewSystemProbe(t) config.SystemProbe().SetWithoutSource("system_probe_config.collect_dns_domains", false) out := getExpectedConnections(false, httpOutBlob) assert := assert.New(t) @@ -399,7 +400,7 @@ func testSerialization(t *testing.T, aggregateByStatusCode bool) { }) t.Run("requesting unsupported serialization format", func(t *testing.T) { - config.MockSystemProbe(t) + configmock.NewSystemProbe(t) config.SystemProbe().SetWithoutSource("system_probe_config.collect_dns_domains", false) out := getExpectedConnections(false, httpOutBlob) @@ -455,7 +456,7 @@ func testSerialization(t *testing.T, aggregateByStatusCode bool) { }) t.Run("requesting application/protobuf serialization (no query types)", func(t *testing.T) { - config.MockSystemProbe(t) + configmock.NewSystemProbe(t) config.SystemProbe().SetWithoutSource("system_probe_config.collect_dns_domains", false) out := getExpectedConnections(false, httpOutBlob) @@ -471,7 +472,7 @@ func testSerialization(t *testing.T, aggregateByStatusCode bool) { assertConnsEqual(t, out, result) }) t.Run("requesting application/protobuf serialization (with query types)", func(t *testing.T) { - config.MockSystemProbe(t) + configmock.NewSystemProbe(t) config.SystemProbe().SetWithoutSource("system_probe_config.collect_dns_domains", false) config.SystemProbe().SetWithoutSource("network_config.enable_dns_by_querytype", true) out := getExpectedConnections(true, httpOutBlob) diff --git a/pkg/network/event_common.go b/pkg/network/event_common.go index 7ec7a5390e34a..3c5c4f9769741 100644 --- a/pkg/network/event_common.go +++ b/pkg/network/event_common.go @@ -30,6 +30,9 @@ const ( maxByteCountChange uint64 = 375 << 30 // use typical small MTU size, 1300, to get max packet count maxPacketCountChange uint64 = maxByteCountChange / 1300 + + // ConnectionByteKeyMaxLen represents the maximum size in bytes of a connection byte key + ConnectionByteKeyMaxLen = 41 ) // ConnectionType will be either TCP or UDP @@ -332,6 +335,15 @@ func (c ConnectionStats) ByteKeyNAT(buf []byte) []byte { return generateConnectionKey(c, buf, true) } +// IsValid returns `true` if the connection has a valid source and dest +// ports and IPs +func (c ConnectionStats) IsValid() bool { + return c.Source.IsValid() && + c.Dest.IsValid() && + c.SPort > 0 && + c.DPort > 0 +} + const keyFmt = "p:%d|src:%s:%d|dst:%s:%d|f:%d|t:%d" // BeautifyKey returns a human readable byte key (used for debugging purposes) diff --git a/pkg/network/event_windows.go b/pkg/network/event_windows.go index 8453dfee338fb..ff9bed37d33f9 100644 --- a/pkg/network/event_windows.go +++ b/pkg/network/event_windows.go @@ -106,7 +106,8 @@ func FlowToConnStat(cs *ConnectionStats, flow *driver.PerFlowData, enableMonoton cs.Monotonic.RecvBytes = monotonicOrTransportBytes(enableMonotonicCounts, flow.MonotonicRecvBytes, flow.TransportBytesIn) cs.Monotonic.SentPackets = flow.PacketsOut cs.Monotonic.RecvPackets = flow.PacketsIn - cs.LastUpdateEpoch = flow.Timestamp + // ok. flow.Timestamp is actually the number of ns that the system has been up. + cs.LastUpdateEpoch = driverTimeToUnixTime(flow.Timestamp) cs.Pid = uint32(flow.ProcessId) cs.SPort = flow.LocalPort cs.DPort = flow.RemotePort diff --git a/pkg/network/events/monitor.go b/pkg/network/events/monitor.go index d27601aa52a17..9a5cbe17c2476 100644 --- a/pkg/network/events/monitor.go +++ b/pkg/network/events/monitor.go @@ -5,7 +5,7 @@ //go:generate go run github.com/DataDog/datadog-agent/pkg/security/generators/event_copy -scope "(h *eventConsumerWrapper)" -pkg events -output event_copy_linux.go Process . -//go:build linux +//go:build linux || windows // Package events handles process events package events @@ -14,7 +14,6 @@ import ( "slices" "strings" "sync" - "time" "go.uber.org/atomic" "go4.org/intern" @@ -115,19 +114,26 @@ func (h *eventConsumerWrapper) Copy(ev *model.Event) any { } // If this consumer subscribes to more event types, this block will have to account for those additional event types - var processStartTime time.Time - if ev.GetEventType() == model.ExecEventType { - processStartTime = ev.GetProcessExecTime() - } - if ev.GetEventType() == model.ForkEventType { - processStartTime = ev.GetProcessForkTime() - } + processStartTime := getProcessStartTime(ev) p := &Process{ Pid: ev.GetProcessPid(), StartTime: processStartTime.UnixNano(), } + // we need to keep looking for settings until all of the desired + // key/value pairs are found, following the precedence order. + + // the precedence order is + // 1. environment variables + // 2. tags from the web.config file + // 3. tags from the datadog.json file + + // keep the map of tagsFound, so that entries found at lower levels + // don't supercede those at higher. However, we must actually parse + // all of the inputs to ensure that we don't miss any tags that are + tagsFound := make(map[string]struct{}) + envs := model.FilterEnvs(ev.GetProcessEnvp(), envFilter) if len(envs) > 0 { p.Tags = make([]*intern.Value, 0, len(envs)) @@ -136,10 +142,17 @@ func (h *eventConsumerWrapper) Copy(ev *model.Event) any { if len(v) > 0 { if t := envTagNames[k]; t != "" { p.Tags = append(p.Tags, intern.GetByString(t+":"+v)) + tagsFound[k] = struct{}{} } } } } + if len(tagsFound) < len(envFilter) { + apmTags := getAPMTags(tagsFound, ev.GetExecFilePath()) + if len(apmTags) > 0 { + p.Tags = append(p.Tags, apmTags...) + } + } if cid := ev.GetContainerId(); cid != "" { p.ContainerID = intern.GetByString(cid) diff --git a/pkg/network/events/monitor_linux.go b/pkg/network/events/monitor_linux.go new file mode 100644 index 0000000000000..c3abc3164b45a --- /dev/null +++ b/pkg/network/events/monitor_linux.go @@ -0,0 +1,29 @@ +// 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 events handles process events +package events + +import ( + "time" + + "go4.org/intern" + + "github.com/DataDog/datadog-agent/pkg/security/secl/model" +) + +func getProcessStartTime(ev *model.Event) time.Time { + if ev.GetEventType() == model.ExecEventType { + return ev.GetProcessExecTime() + } + if ev.GetEventType() == model.ForkEventType { + return ev.GetProcessForkTime() + } + return time.Time{} +} + +func getAPMTags(_ map[string]struct{}, _ string) []*intern.Value { + return nil +} diff --git a/pkg/network/events/monitor_others.go b/pkg/network/events/monitor_others.go index 1675a4e384e91..f87ced0432d27 100644 --- a/pkg/network/events/monitor_others.go +++ b/pkg/network/events/monitor_others.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build !linux +//go:build !linux && !windows // Package events handles process events package events diff --git a/pkg/network/events/monitor_windows.go b/pkg/network/events/monitor_windows.go new file mode 100644 index 0000000000000..3698e001eb40f --- /dev/null +++ b/pkg/network/events/monitor_windows.go @@ -0,0 +1,100 @@ +// 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 events handles process events +package events + +import ( + "errors" + "os" + "path/filepath" + "time" + + "go4.org/intern" + + "github.com/DataDog/datadog-agent/pkg/security/secl/model" + "github.com/DataDog/datadog-agent/pkg/util/log" + "github.com/DataDog/datadog-agent/pkg/util/winutil/iisconfig" +) + +func getProcessStartTime(ev *model.Event) time.Time { + if ev.GetEventType() == model.ExecEventType { + return ev.GetProcessExecTime() + } + // windows does not have a fork event. + return time.Time{} +} + +func makeTagsSlice(already map[string]struct{}, apmtags iisconfig.APMTags) []*intern.Value { + tags := make([]*intern.Value, 0, 3) + if _, found := already["DD_SERVICE"]; !found { + if len(apmtags.DDService) > 0 { + tags = append(tags, intern.GetByString("service"+":"+apmtags.DDService)) + already["DD_SERVICE"] = struct{}{} + } + } + if _, found := already["DD_ENV"]; !found { + if len(apmtags.DDEnv) > 0 { + tags = append(tags, intern.GetByString("env"+":"+apmtags.DDEnv)) + already["DD_ENV"] = struct{}{} + } + } + if _, found := already["DD_VERSION"]; !found { + if len(apmtags.DDVersion) > 0 { + tags = append(tags, intern.GetByString("version"+":"+apmtags.DDVersion)) + already["DD_VERSION"] = struct{}{} + } + } + if len(tags) == 0 { + return nil + } + return tags +} + +func getAPMTags(already map[string]struct{}, filename string) []*intern.Value { + + dir := filepath.Dir(filename) + if dir == "" { + return nil + } + + tags := make([]*intern.Value, 0, 3) + // see if there's an app.config in the directory + appConfig := filepath.Join(dir, "app.config") + ddJSON := filepath.Join(dir, "datadog.json") + if _, err := os.Stat(appConfig); err == nil { + + appcfg, err := iisconfig.ReadDotNetConfig(appConfig) + if err == nil { + found := makeTagsSlice(already, appcfg) + if len(found) > 0 { + tags = append(tags, found...) + } + } + } else if !errors.Is(err, os.ErrNotExist) { + log.Warnf("Error reading app.config: %v", err) + } + if len(already) == len(envFilter) { + // we've seen all we need, no point in looking in datadog.json + return tags + } + // see if there's a datadog.json + if _, err := os.Stat(ddJSON); err == nil { + + appcfg, err := iisconfig.ReadDatadogJSON(ddJSON) + if err == nil { + found := makeTagsSlice(already, appcfg) + if len(found) > 0 { + tags = append(tags, found...) + } + } + } else if !errors.Is(err, os.ErrNotExist) { + log.Warnf("Error reading datadog.json: %v", err) + } + if len(tags) != 0 { + return tags + } + return nil +} diff --git a/pkg/network/events/network_consumer.go b/pkg/network/events/network_consumer.go index 0e91d51f355d2..95129db2c27ed 100644 --- a/pkg/network/events/network_consumer.go +++ b/pkg/network/events/network_consumer.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build linux +//go:build linux || windows // Package events handles process events package events diff --git a/pkg/network/events/network_consumer_others.go b/pkg/network/events/network_consumer_others.go index c0c1288e53314..c1ece0fdbaa82 100644 --- a/pkg/network/events/network_consumer_others.go +++ b/pkg/network/events/network_consumer_others.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build !linux +//go:build !linux && !windows // Package events handles process events package events diff --git a/pkg/network/filter/packet_source.go b/pkg/network/filter/packet_source.go new file mode 100644 index 0000000000000..c75ad1222e9bf --- /dev/null +++ b/pkg/network/filter/packet_source.go @@ -0,0 +1,33 @@ +// 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 2024-present Datadog, Inc. + +// Package filter exposes interfaces and implementations for packet capture +package filter + +import ( + "time" + + "github.com/google/gopacket" +) + +// PacketInfo holds OS dependent packet information +// about a packet +type PacketInfo interface{} + +// PacketSource reads raw packet data +type PacketSource interface { + // VisitPackets reads all new raw packets that are available, invoking the given callback for each packet. + // If no packet is available, VisitPacket returns immediately. + // The format of the packet is dependent on the implementation of PacketSource -- i.e. it may be an ethernet frame, or a IP frame. + // The data buffer is reused between invocations of VisitPacket and thus should not be pointed to. + // If the cancel channel is closed, VisitPackets will stop reading. + VisitPackets(cancel <-chan struct{}, visitor func(data []byte, info PacketInfo, timestamp time.Time) error) error + + // LayerType returns the type of packet this source reads + LayerType() gopacket.LayerType + + // Close closes the packet source + Close() +} diff --git a/pkg/network/filter/packet_source_linux.go b/pkg/network/filter/packet_source_linux.go index 8e21c04e7d5f2..65fbbe9f9270f 100644 --- a/pkg/network/filter/packet_source_linux.go +++ b/pkg/network/filter/packet_source_linux.go @@ -3,13 +3,14 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build linux_bpf +//go:build linux -//nolint:revive // TODO(NET) Fix revive linter +// Package filter exposes interfaces and implementations for packet capture package filter import ( "fmt" + "os" "reflect" "syscall" "time" @@ -19,12 +20,16 @@ import ( "github.com/google/gopacket/afpacket" "github.com/google/gopacket/layers" "golang.org/x/net/bpf" + "golang.org/x/sys/unix" "github.com/DataDog/datadog-agent/pkg/telemetry" "github.com/DataDog/datadog-agent/pkg/util/log" ) -const telemetryModuleName = "network_tracer__dns" +const ( + telemetryModuleName = "network_tracer__filter" + defaultSnapLen = 4096 +) // Telemetry var packetSourceTelemetry = struct { @@ -42,49 +47,91 @@ var packetSourceTelemetry = struct { // AFPacketSource provides a RAW_SOCKET attached to an eBPF SOCKET_FILTER type AFPacketSource struct { *afpacket.TPacket - socketFilter *manager.Probe exit chan struct{} } -// NewPacketSource creates an AFPacketSource using the provided BPF filter -func NewPacketSource(filter *manager.Probe, bpfFilter []bpf.RawInstruction) (*AFPacketSource, error) { +// AFPacketInfo holds information about a packet +type AFPacketInfo struct { + // PktType corresponds to sll_pkttype in the + // sockaddr_ll struct; see packet(7) + // https://man7.org/linux/man-pages/man7/packet.7.html + PktType uint8 +} + +// OptSnapLen specifies the maximum length of the packet to read +// +// Defaults to 4096 bytes +type OptSnapLen int + +// NewAFPacketSource creates an AFPacketSource using the provided BPF filter +func NewAFPacketSource(size int, opts ...interface{}) (*AFPacketSource, error) { + snapLen := defaultSnapLen + for _, opt := range opts { + switch o := opt.(type) { + case OptSnapLen: + snapLen = int(o) + if snapLen <= 0 || snapLen > 65536 { + return nil, fmt.Errorf("snap len should be between 0 and 65536") + } + default: + return nil, fmt.Errorf("unknown option %+v", opt) + } + } + + frameSize, blockSize, numBlocks, err := afpacketComputeSize(size, snapLen, os.Getpagesize()) + if err != nil { + return nil, fmt.Errorf("error computing mmap'ed buffer parameters: %w", err) + } + + log.Debugf("creating tpacket source with frame_size=%d block_size=%d num_blocks=%d", frameSize, blockSize, numBlocks) rawSocket, err := afpacket.NewTPacket( - afpacket.OptPollTimeout(1*time.Second), - // This setup will require ~4Mb that is mmap'd into the process virtual space - // More information here: https://www.kernel.org/doc/Documentation/networking/packet_mmap.txt - afpacket.OptFrameSize(4096), - afpacket.OptBlockSize(4096*128), - afpacket.OptNumBlocks(8), + afpacket.OptPollTimeout(time.Second), + afpacket.OptFrameSize(frameSize), + afpacket.OptBlockSize(blockSize), + afpacket.OptNumBlocks(numBlocks), + afpacket.OptAddPktType(true), ) + if err != nil { return nil, fmt.Errorf("error creating raw socket: %s", err) } - if filter != nil { - // The underlying socket file descriptor is private, hence the use of reflection - // Point socket filter program to the RAW_SOCKET file descriptor - // Note the filter attachment itself is triggered by the ebpf.Manager - filter.SocketFD = int(reflect.ValueOf(rawSocket).Elem().FieldByName("fd").Int()) - } else { - err = rawSocket.SetBPF(bpfFilter) - if err != nil { - return nil, fmt.Errorf("error setting classic bpf filter: %w", err) - } - } - ps := &AFPacketSource{ - TPacket: rawSocket, - socketFilter: filter, - exit: make(chan struct{}), + TPacket: rawSocket, + exit: make(chan struct{}), } go ps.pollStats() return ps, nil } +// SetEbpf attaches an eBPF socket filter to the AFPacketSource +func (p *AFPacketSource) SetEbpf(filter *manager.Probe) error { + // The underlying socket file descriptor is private, hence the use of reflection + // Point socket filter program to the RAW_SOCKET file descriptor + // Note the filter attachment itself is triggered by the ebpf.Manager + f := reflect.ValueOf(p.TPacket).Elem().FieldByName("fd") + if !f.IsValid() { + return fmt.Errorf("could not find fd field in TPacket object") + } + + if !f.CanInt() { + return fmt.Errorf("fd TPacket field is not an int") + } + + filter.SocketFD = int(f.Int()) + return nil +} + +// SetBPF attaches a (classic) BPF socket filter to the AFPacketSource +func (p *AFPacketSource) SetBPF(filter []bpf.RawInstruction) error { + return p.TPacket.SetBPF(filter) +} + // VisitPackets starts reading packets from the source -func (p *AFPacketSource) VisitPackets(exit <-chan struct{}, visit func([]byte, time.Time) error) error { +func (p *AFPacketSource) VisitPackets(exit <-chan struct{}, visit func(data []byte, info PacketInfo, t time.Time) error) error { + pktInfo := &AFPacketInfo{} for { // allow the read loop to be prematurely interrupted select { @@ -108,14 +155,15 @@ func (p *AFPacketSource) VisitPackets(exit <-chan struct{}, visit func([]byte, t return err } - if err := visit(data, stats.Timestamp); err != nil { + pktInfo.PktType = stats.AncillaryData[0].(afpacket.AncillaryPktType).Type + if err := visit(data, pktInfo, stats.Timestamp); err != nil { return err } } } -// PacketType is the gopacket.LayerType for this source -func (p *AFPacketSource) PacketType() gopacket.LayerType { +// LayerType is the gopacket.LayerType for this source +func (p *AFPacketSource) LayerType() gopacket.LayerType { return layers.LayerTypeEthernet } @@ -160,3 +208,57 @@ func (p *AFPacketSource) pollStats() { } } } + +// afpacketComputeSize computes the block_size and the num_blocks in such a way that the +// allocated mmap buffer is close to but smaller than target_size_mb. +// The restriction is that the block_size must be divisible by both the +// frame size and page size. +// +// See https://www.kernel.org/doc/Documentation/networking/packet_mmap.txt +func afpacketComputeSize(targetSize, snaplen, pageSize int) (frameSize, blockSize, numBlocks int, err error) { + frameSize = tpacketAlign(unix.TPACKET_HDRLEN) + tpacketAlign(snaplen) + if frameSize <= pageSize { + frameSize = int(nextPowerOf2(int64(frameSize))) + if frameSize <= pageSize { + blockSize = pageSize + } + } else { + // align frameSize to pageSize + frameSize = (frameSize + pageSize - 1) & ^(pageSize - 1) + blockSize = frameSize + } + + numBlocks = targetSize / blockSize + if numBlocks == 0 { + return 0, 0, 0, fmt.Errorf("buffer size is too small") + } + + blockSizeInc := blockSize + for numBlocks > afpacket.DefaultNumBlocks { + blockSize += blockSizeInc + numBlocks = targetSize / blockSize + } + + return frameSize, blockSize, numBlocks, nil +} + +func tpacketAlign(x int) int { + return (x + unix.TPACKET_ALIGNMENT - 1) & ^(unix.TPACKET_ALIGNMENT - 1) +} + +// nextPowerOf2 rounds up `v` to the next power of 2 +// +// Taken from Hacker's Delight by Henry S. Warren, Jr., +// https://en.wikipedia.org/wiki/Hacker%27s_Delight +func nextPowerOf2(v int64) int64 { + v-- + v |= v >> 1 + v |= v >> 2 + v |= v >> 4 + v |= v >> 8 + v |= v >> 16 + v |= v >> 32 + v++ + + return v +} diff --git a/pkg/network/filter/socket_filter.go b/pkg/network/filter/socket_filter.go index 467cb3931d29f..5c29b2d15cea2 100644 --- a/pkg/network/filter/socket_filter.go +++ b/pkg/network/filter/socket_filter.go @@ -5,15 +5,15 @@ //go:build linux_bpf +// Package filter exposes interfaces and implementations for packet capture package filter import ( "encoding/binary" "runtime" - "golang.org/x/sys/unix" - manager "github.com/DataDog/ebpf-manager" + "golang.org/x/sys/unix" "github.com/DataDog/datadog-agent/pkg/network/config" "github.com/DataDog/datadog-agent/pkg/util/kernel" diff --git a/pkg/network/go/bininspect/newproc.go b/pkg/network/go/bininspect/newproc.go index 6547c8b29cc3c..6b2b24ecf3b22 100644 --- a/pkg/network/go/bininspect/newproc.go +++ b/pkg/network/go/bininspect/newproc.go @@ -53,7 +53,7 @@ func InspectNewProcessBinary(elfFile *elf.File, functions map[string]FunctionCon // This might fail if the binary was stripped. symbols, err := GetAllSymbolsByName(elfFile, symbolsSet) if err != nil { - return nil, fmt.Errorf("failed retrieving symbols: %+v", err) + return nil, err } inspector := newProcessBinaryInspector{ diff --git a/pkg/network/go/bininspect/symbols.go b/pkg/network/go/bininspect/symbols.go index eff36bc5642c2..d1f4aa450774c 100644 --- a/pkg/network/go/bininspect/symbols.go +++ b/pkg/network/go/bininspect/symbols.go @@ -226,6 +226,9 @@ func GetAllSymbolsByName(elfFile *elf.File, symbolSet common.StringSet) (map[str } // Only if we failed getting both regular and dynamic symbols - then we abort. + if regularSymbolsErr == elf.ErrNoSymbols && dynamicSymbolsErr == elf.ErrNoSymbols { + return nil, elf.ErrNoSymbols + } if regularSymbolsErr != nil && dynamicSymbolsErr != nil { return nil, fmt.Errorf("could not open symbol sections to resolve symbol offset: %v, %v", regularSymbolsErr, dynamicSymbolsErr) } diff --git a/pkg/network/netlink/conntracker.go b/pkg/network/netlink/conntracker.go index af4314b800cbd..9f066d2f8cb97 100644 --- a/pkg/network/netlink/conntracker.go +++ b/pkg/network/netlink/conntracker.go @@ -10,6 +10,7 @@ package netlink import ( "container/list" "context" + "errors" "fmt" "net" "net/netip" @@ -17,6 +18,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + "github.com/syndtr/gocapability/capability" "golang.org/x/sys/unix" "github.com/cihub/seelog" @@ -39,6 +41,9 @@ const ( var defaultBuckets = []float64{10, 25, 50, 75, 100, 250, 500, 1000, 10000} +// ErrNotPermitted is the error returned when the current process does not have the required permissions for netlink conntracker +var ErrNotPermitted = errors.New("netlink conntracker requires NET_ADMIN capability") + // Conntracker is a wrapper around go-conntracker that keeps a record of all connections in user space type Conntracker interface { // Describe returns all descriptions of the collector @@ -115,6 +120,18 @@ func NewConntracker(config *config.Config, telemetrycomp telemetryComp.Component conntracker Conntracker ) + // check if we have the right capabilities for the netlink NewConntracker + // NET_ADMIN is required + if caps, err := capability.NewPid2(0); err == nil { + if err = caps.Load(); err != nil { + return nil, fmt.Errorf("could not load process capabilities: %w", err) + } + + if !caps.Get(capability.EFFECTIVE, capability.CAP_NET_ADMIN) { + return nil, ErrNotPermitted + } + } + done := make(chan struct{}) go func() { diff --git a/pkg/network/port.go b/pkg/network/port.go index 6a1ed3f560555..cce191d642382 100644 --- a/pkg/network/port.go +++ b/pkg/network/port.go @@ -30,8 +30,8 @@ var statusMap = map[ConnectionType]int64{ UDP: tcpClose, } -// ReadInitialState reads the /proc filesystem and determines which ports are being listened on -func ReadInitialState(procRoot string, protocol ConnectionType, collectIPv6 bool) (map[PortMapping]uint32, error) { +// ReadListeningPorts reads the /proc filesystem and determines which ports are being listened on +func ReadListeningPorts(procRoot string, protocol ConnectionType, collectIPv6 bool) (map[PortMapping]uint32, error) { start := time.Now() defer func() { log.Debugf("Read initial %s pid->port mapping in %s", protocol.String(), time.Since(start)) diff --git a/pkg/network/port_test.go b/pkg/network/port_test.go index e52c80829cecb..995a4e8ef0a2f 100644 --- a/pkg/network/port_test.go +++ b/pkg/network/port_test.go @@ -89,16 +89,16 @@ func runServerProcess(t *testing.T, proto string, port uint16, ns netns.NsHandle return port, proc } -func TestReadInitialState(t *testing.T) { +func TestReadListeningPorts(t *testing.T) { t.Run("TCP", func(t *testing.T) { - testReadInitialState(t, "tcp") + testReadListeningPorts(t, "tcp") }) t.Run("UDP", func(t *testing.T) { - testReadInitialState(t, "udp") + testReadListeningPorts(t, "udp") }) } -func testReadInitialState(t *testing.T, proto string) { +func testReadListeningPorts(t *testing.T, proto string) { var ns, rootNs netns.NsHandle var err error nsName := netlinktestutil.AddNS(t) @@ -159,7 +159,7 @@ func testReadInitialState(t *testing.T, proto string) { connType, otherConnType = otherConnType, connType } - initialPorts, err := ReadInitialState("/proc", connType, true) + initialPorts, err := ReadListeningPorts("/proc", connType, true) if !assert.NoError(t, err) { return } diff --git a/pkg/network/protocols/http/driver_interface.go b/pkg/network/protocols/http/driver_interface.go index 9063cdcd64d6f..0bca6d58c2543 100644 --- a/pkg/network/protocols/http/driver_interface.go +++ b/pkg/network/protocols/http/driver_interface.go @@ -20,6 +20,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/network/config" "github.com/DataDog/datadog-agent/pkg/network/driver" "github.com/DataDog/datadog-agent/pkg/util/log" + "github.com/DataDog/datadog-agent/pkg/util/winutil/iisconfig" "golang.org/x/sys/windows" ) @@ -45,6 +46,8 @@ type WinHttpTransaction struct { SiteName string // HeaderLength uint32 // ContentLength uint32 + TagsFromJson iisconfig.APMTags + TagsFromConfig iisconfig.APMTags } //nolint:revive // TODO(WKIT) Fix revive linter diff --git a/pkg/network/protocols/http/etw_http_service.go b/pkg/network/protocols/http/etw_http_service.go index 162a8fd16e562..ee913ae4b7c8d 100644 --- a/pkg/network/protocols/http/etw_http_service.go +++ b/pkg/network/protocols/http/etw_http_service.go @@ -140,6 +140,7 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "time" "unsafe" @@ -148,6 +149,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/network/driver" "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/DataDog/datadog-agent/pkg/util/winutil" + "github.com/DataDog/datadog-agent/pkg/util/winutil/iisconfig" ) //nolint:revive // TODO(WKIT) Fix revive linter @@ -200,7 +202,8 @@ type HttpConnLink struct { http WinHttpTransaction - url string + url string + urlPath string // list of etw notifications, in order, that this transaction has been seen // this is for internal debugging; is not surfaced anywhere. @@ -274,7 +277,7 @@ var ( lastSummaryTime time.Time - iisConfig *winutil.DynamicIISConfig + iisConfig atomic.Pointer[iisconfig.DynamicIISConfig] ) func init() { @@ -742,6 +745,8 @@ func httpCallbackOnHTTPRequestTraceTaskParse(eventInfo *etw.DDEventRecord) { if len(urlParsed.Path) == 0 { urlParsed.Path = "/" } + httpConnLink.urlPath = urlParsed.Path + // httpConnLink.http.RequestFragment[0] = 32 is done to simulate // func getPath(reqFragment, buffer []byte) []byte // which expects something like "GET /foo?var=bar HTTP/1.1" @@ -830,7 +835,11 @@ func httpCallbackOnHTTPRequestTraceTaskDeliver(eventInfo *etw.DDEventRecord) { httpConnLink.http.AppPool = appPool httpConnLink.http.SiteID = userData.GetUint32(16) - httpConnLink.http.SiteName = iisConfig.GetSiteNameFromID(httpConnLink.http.SiteID) + cfg := iisConfig.Load() + if cfg != nil { + httpConnLink.http.SiteName = cfg.GetSiteNameFromID(httpConnLink.http.SiteID) + httpConnLink.http.TagsFromJson, httpConnLink.http.TagsFromConfig = cfg.GetAPMTags(httpConnLink.http.SiteID, httpConnLink.urlPath) + } // Parse url if urlOffset > userData.Length() { @@ -977,7 +986,10 @@ func httpCallbackOnHTTPRequestTraceTaskSrvdFrmCache(eventInfo *etw.DDEventRecord // <<>> httpConnLink.http.SiteID = cacheEntry.http.SiteID - httpConnLink.http.SiteName = iisConfig.GetSiteNameFromID(cacheEntry.http.SiteID) + cfg := iisConfig.Load() + if cfg != nil { + httpConnLink.http.SiteName = cfg.GetSiteNameFromID(cacheEntry.http.SiteID) + } completeReqRespTracking(eventInfo, httpConnLink) servedFromCache++ @@ -1427,26 +1439,29 @@ func (hei *EtwInterface) OnStart() { initializeEtwHttpServiceSubscription() httpServiceSubscribed = true var err error - iisConfig, err = winutil.NewDynamicIISConfig() + config, err := iisconfig.NewDynamicIISConfig() if err != nil { log.Warnf("Failed to create iis config %v", err) - iisConfig = nil + config = nil } else { - err = iisConfig.Start() + err = config.Start() if err != nil { log.Warnf("Failed to start iis config %v", err) - iisConfig = nil + config = nil } } + if config != nil { + iisConfig.Store(config) + } } //nolint:revive // TODO(WKIT) Fix revive linter func (hei *EtwInterface) OnStop() { httpServiceSubscribed = false initializeEtwHttpServiceSubscription() - if iisConfig != nil { - iisConfig.Stop() - iisConfig = nil + cfg := iisConfig.Swap(nil) + if cfg != nil { + cfg.Stop() } } func ipAndPortFromTup(tup driver.ConnTupleType, local bool) ([16]uint8, uint16) { diff --git a/pkg/network/protocols/http/model_windows.go b/pkg/network/protocols/http/model_windows.go index 9c21bb1170fd1..685060030600a 100644 --- a/pkg/network/protocols/http/model_windows.go +++ b/pkg/network/protocols/http/model_windows.go @@ -106,14 +106,40 @@ func (tx *WinHttpTransaction) StaticTags() uint64 { // //nolint:revive // TODO(WKIT) Fix revive linter func (tx *WinHttpTransaction) DynamicTags() []string { + tags := make([]string, 0, 6) + if len(tx.AppPool) != 0 || len(tx.SiteName) != 0 { - return []string{ - fmt.Sprintf("http.iis.app_pool:%v", tx.AppPool), - fmt.Sprintf("http.iis.site:%v", tx.SiteID), - fmt.Sprintf("http.iis.sitename:%v", tx.SiteName), + tags = append(tags, fmt.Sprintf("http.iis.site:%v", tx.SiteID)) + if (len(tx.AppPool)) > 0 { + tags = append(tags, fmt.Sprintf("http.iis.app_pool:%v", tx.AppPool)) + } + if (len(tx.SiteName)) > 0 { + tags = append(tags, fmt.Sprintf("http.iis.sitename:%v", tx.SiteName)) } } - return nil + + // tag precedence is web.config -> datadog.json + if (len(tx.TagsFromConfig.DDEnv)) > 0 { + tags = append(tags, fmt.Sprintf("env:%v", tx.TagsFromConfig.DDEnv)) + } else if (len(tx.TagsFromJson.DDEnv)) > 0 { + tags = append(tags, fmt.Sprintf("env:%v", tx.TagsFromJson.DDEnv)) + } + + if (len(tx.TagsFromConfig.DDService)) > 0 { + tags = append(tags, fmt.Sprintf("service:%v", tx.TagsFromConfig.DDService)) + } else if (len(tx.TagsFromJson.DDService)) > 0 { + tags = append(tags, fmt.Sprintf("service:%v", tx.TagsFromJson.DDService)) + } + + if (len(tx.TagsFromConfig.DDVersion)) > 0 { + tags = append(tags, fmt.Sprintf("version:%v", tx.TagsFromConfig.DDVersion)) + } else if (len(tx.TagsFromJson.DDVersion)) > 0 { + tags = append(tags, fmt.Sprintf("version:%v", tx.TagsFromJson.DDVersion)) + } + if len(tags) == 0 { + return nil + } + return tags } //nolint:revive // TODO(WKIT) Fix revive linter diff --git a/pkg/network/protocols/http/testutil/tcp_server.go b/pkg/network/protocols/http/testutil/tcp_server.go index 671d282bd9ca3..c86228e5e55c3 100644 --- a/pkg/network/protocols/http/testutil/tcp_server.go +++ b/pkg/network/protocols/http/testutil/tcp_server.go @@ -86,3 +86,8 @@ func (s *TCPServer) Run(done chan struct{}) error { return nil } + +// Address returns the address of the server. +func (s *TCPServer) Address() string { + return s.address +} diff --git a/pkg/network/protocols/http2/telemetry.go b/pkg/network/protocols/http2/telemetry.go index cb17da6a7a8e4..35f24cfc9878b 100644 --- a/pkg/network/protocols/http2/telemetry.go +++ b/pkg/network/protocols/http2/telemetry.go @@ -14,66 +14,34 @@ import ( "github.com/DataDog/datadog-agent/pkg/util/log" ) -// tlsAwareCounter is a TLS aware counter, it has a plain counter and a counter for TLS. -// It enables the use of a single metric that increments based on the encryption, avoiding the need for separate metrics for eash use-case. -type tlsAwareCounter struct { - counterPlain *libtelemetry.Counter - counterTLS *libtelemetry.Counter -} - -// newTLSAwareCounter creates and returns a new instance of TLSCounter -func newTLSAwareCounter(metricGroup *libtelemetry.MetricGroup, metricName string, tags ...string) *tlsAwareCounter { - return &tlsAwareCounter{ - counterPlain: metricGroup.NewCounter(metricName, append(tags, "encrypted:false")...), - counterTLS: metricGroup.NewCounter(metricName, append(tags, "encrypted:true")...), - } -} - -// add adds the given delta to the counter based on the encryption. -func (c *tlsAwareCounter) add(delta int64, isTLS bool) { - if isTLS { - c.counterTLS.Add(delta) - return - } - c.counterPlain.Add(delta) -} - -// get returns the counter value based on the encryption. -func (c *tlsAwareCounter) get(isTLS bool) int64 { - if isTLS { - return c.counterTLS.Get() - } - return c.counterPlain.Get() -} - type kernelTelemetry struct { // metricGroup is used here mostly for building the log message below metricGroup *libtelemetry.MetricGroup // http2requests Count of HTTP/2 requests seen - http2requests *tlsAwareCounter + http2requests *libtelemetry.TLSAwareCounter // http2responses Count of HTTP/2 responses seen - http2responses *tlsAwareCounter + http2responses *libtelemetry.TLSAwareCounter // endOfStream Count of END_OF_STREAM flags seen - endOfStream *tlsAwareCounter + endOfStream *libtelemetry.TLSAwareCounter // endOfStreamRST Count of RST flags seen - endOfStreamRST *tlsAwareCounter + endOfStreamRST *libtelemetry.TLSAwareCounter // pathSizeBucket Count of path sizes divided into buckets. - pathSizeBucket [http2PathBuckets + 1]*tlsAwareCounter + pathSizeBucket [http2PathBuckets + 1]*libtelemetry.TLSAwareCounter // literalValueExceedsFrame Count of times we couldn't retrieve the literal value due to reaching the end of the frame. - literalValueExceedsFrame *tlsAwareCounter + literalValueExceedsFrame *libtelemetry.TLSAwareCounter // exceedingMaxInterestingFrames Count of times we reached the max number of frames per iteration. - exceedingMaxInterestingFrames *tlsAwareCounter + exceedingMaxInterestingFrames *libtelemetry.TLSAwareCounter // exceedingMaxFramesToFilter Count of times we have left with more frames to filter than the max number of frames to filter. - exceedingMaxFramesToFilter *tlsAwareCounter + exceedingMaxFramesToFilter *libtelemetry.TLSAwareCounter // fragmentedFrameCountRST Count of times we have seen a fragmented RST frame. - fragmentedFrameCountRST *tlsAwareCounter + fragmentedFrameCountRST *libtelemetry.TLSAwareCounter // fragmentedHeadersFrameEOSCount Count of times we have seen a fragmented headers frame with EOS. - fragmentedHeadersFrameEOSCount *tlsAwareCounter + fragmentedHeadersFrameEOSCount *libtelemetry.TLSAwareCounter // fragmentedHeadersFrameCount Count of times we have seen a fragmented headers frame. - fragmentedHeadersFrameCount *tlsAwareCounter + fragmentedHeadersFrameCount *libtelemetry.TLSAwareCounter // fragmentedDataFrameEOSCount Count of times we have seen a fragmented data frame with EOS. - fragmentedDataFrameEOSCount *tlsAwareCounter + fragmentedDataFrameEOSCount *libtelemetry.TLSAwareCounter // telemetryLastState represents the latest HTTP2 eBPF Kernel telemetry observed from the kernel telemetryLastState HTTP2Telemetry } @@ -83,20 +51,20 @@ func newHTTP2KernelTelemetry() *kernelTelemetry { metricGroup := libtelemetry.NewMetricGroup("usm.http2", libtelemetry.OptPrometheus) http2KernelTel := &kernelTelemetry{ metricGroup: metricGroup, - http2requests: newTLSAwareCounter(metricGroup, "requests"), - http2responses: newTLSAwareCounter(metricGroup, "responses"), - endOfStream: newTLSAwareCounter(metricGroup, "eos"), - endOfStreamRST: newTLSAwareCounter(metricGroup, "rst"), - literalValueExceedsFrame: newTLSAwareCounter(metricGroup, "literal_value_exceeds_frame"), - exceedingMaxInterestingFrames: newTLSAwareCounter(metricGroup, "exceeding_max_interesting_frames"), - exceedingMaxFramesToFilter: newTLSAwareCounter(metricGroup, "exceeding_max_frames_to_filter"), - fragmentedDataFrameEOSCount: newTLSAwareCounter(metricGroup, "exceeding_data_end_data_eos"), - fragmentedHeadersFrameCount: newTLSAwareCounter(metricGroup, "exceeding_data_end_headers"), - fragmentedHeadersFrameEOSCount: newTLSAwareCounter(metricGroup, "exceeding_data_end_headers_eos"), - fragmentedFrameCountRST: newTLSAwareCounter(metricGroup, "exceeding_data_end_rst")} + http2requests: libtelemetry.NewTLSAwareCounter(metricGroup, "requests"), + http2responses: libtelemetry.NewTLSAwareCounter(metricGroup, "responses"), + endOfStream: libtelemetry.NewTLSAwareCounter(metricGroup, "eos"), + endOfStreamRST: libtelemetry.NewTLSAwareCounter(metricGroup, "rst"), + literalValueExceedsFrame: libtelemetry.NewTLSAwareCounter(metricGroup, "literal_value_exceeds_frame"), + exceedingMaxInterestingFrames: libtelemetry.NewTLSAwareCounter(metricGroup, "exceeding_max_interesting_frames"), + exceedingMaxFramesToFilter: libtelemetry.NewTLSAwareCounter(metricGroup, "exceeding_max_frames_to_filter"), + fragmentedDataFrameEOSCount: libtelemetry.NewTLSAwareCounter(metricGroup, "exceeding_data_end_data_eos"), + fragmentedHeadersFrameCount: libtelemetry.NewTLSAwareCounter(metricGroup, "exceeding_data_end_headers"), + fragmentedHeadersFrameEOSCount: libtelemetry.NewTLSAwareCounter(metricGroup, "exceeding_data_end_headers_eos"), + fragmentedFrameCountRST: libtelemetry.NewTLSAwareCounter(metricGroup, "exceeding_data_end_rst")} for bucketIndex := range http2KernelTel.pathSizeBucket { - http2KernelTel.pathSizeBucket[bucketIndex] = newTLSAwareCounter(metricGroup, "path_size_bucket_"+(strconv.Itoa(bucketIndex+1))) + http2KernelTel.pathSizeBucket[bucketIndex] = libtelemetry.NewTLSAwareCounter(metricGroup, "path_size_bucket_"+(strconv.Itoa(bucketIndex+1))) } return http2KernelTel @@ -106,15 +74,15 @@ func newHTTP2KernelTelemetry() *kernelTelemetry { func (t *kernelTelemetry) update(tel *HTTP2Telemetry, isTLS bool) { // We should only add the delta between the current eBPF map state and the last seen eBPF map state telemetryDelta := tel.Sub(t.telemetryLastState) - t.http2requests.add(int64(telemetryDelta.Request_seen), isTLS) - t.http2responses.add(int64(telemetryDelta.Response_seen), isTLS) - t.endOfStream.add(int64(telemetryDelta.End_of_stream), isTLS) - t.endOfStreamRST.add(int64(telemetryDelta.End_of_stream_rst), isTLS) - t.literalValueExceedsFrame.add(int64(telemetryDelta.Literal_value_exceeds_frame), isTLS) - t.exceedingMaxInterestingFrames.add(int64(telemetryDelta.Exceeding_max_interesting_frames), isTLS) - t.exceedingMaxFramesToFilter.add(int64(telemetryDelta.Exceeding_max_frames_to_filter), isTLS) + t.http2requests.Add(int64(telemetryDelta.Request_seen), isTLS) + t.http2responses.Add(int64(telemetryDelta.Response_seen), isTLS) + t.endOfStream.Add(int64(telemetryDelta.End_of_stream), isTLS) + t.endOfStreamRST.Add(int64(telemetryDelta.End_of_stream_rst), isTLS) + t.literalValueExceedsFrame.Add(int64(telemetryDelta.Literal_value_exceeds_frame), isTLS) + t.exceedingMaxInterestingFrames.Add(int64(telemetryDelta.Exceeding_max_interesting_frames), isTLS) + t.exceedingMaxFramesToFilter.Add(int64(telemetryDelta.Exceeding_max_frames_to_filter), isTLS) for bucketIndex := range t.pathSizeBucket { - t.pathSizeBucket[bucketIndex].add(int64(telemetryDelta.Path_size_bucket[bucketIndex]), isTLS) + t.pathSizeBucket[bucketIndex].Add(int64(telemetryDelta.Path_size_bucket[bucketIndex]), isTLS) } // Create a deep copy of the 'tel' parameter to prevent changes from the outer scope affecting the last state t.telemetryLastState = *tel diff --git a/pkg/network/protocols/http2/telemetry_test.go b/pkg/network/protocols/http2/telemetry_test.go index 01b7a011eddf2..fdcb054bbdb3d 100644 --- a/pkg/network/protocols/http2/telemetry_test.go +++ b/pkg/network/protocols/http2/telemetry_test.go @@ -67,14 +67,14 @@ func testKernelTelemetryUpdate(t *testing.T, isTLS bool) { } func assertTelemetryEquality(t *testing.T, http2Telemetry *HTTP2Telemetry, kernelTelemetryGroup *kernelTelemetry, isTLS bool) { - assert.Equal(t, http2Telemetry.Request_seen, uint64(kernelTelemetryGroup.http2requests.get(isTLS))) - assert.Equal(t, http2Telemetry.Response_seen, uint64(kernelTelemetryGroup.http2responses.get(isTLS))) - assert.Equal(t, http2Telemetry.End_of_stream, uint64(kernelTelemetryGroup.endOfStream.get(isTLS))) - assert.Equal(t, http2Telemetry.End_of_stream_rst, uint64(kernelTelemetryGroup.endOfStreamRST.get(isTLS))) - assert.Equal(t, http2Telemetry.Literal_value_exceeds_frame, uint64(kernelTelemetryGroup.literalValueExceedsFrame.get(isTLS))) - assert.Equal(t, http2Telemetry.Exceeding_max_interesting_frames, uint64(kernelTelemetryGroup.exceedingMaxInterestingFrames.get(isTLS))) - assert.Equal(t, http2Telemetry.Exceeding_max_frames_to_filter, uint64(kernelTelemetryGroup.exceedingMaxFramesToFilter.get(isTLS))) + assert.Equal(t, http2Telemetry.Request_seen, uint64(kernelTelemetryGroup.http2requests.Get(isTLS))) + assert.Equal(t, http2Telemetry.Response_seen, uint64(kernelTelemetryGroup.http2responses.Get(isTLS))) + assert.Equal(t, http2Telemetry.End_of_stream, uint64(kernelTelemetryGroup.endOfStream.Get(isTLS))) + assert.Equal(t, http2Telemetry.End_of_stream_rst, uint64(kernelTelemetryGroup.endOfStreamRST.Get(isTLS))) + assert.Equal(t, http2Telemetry.Literal_value_exceeds_frame, uint64(kernelTelemetryGroup.literalValueExceedsFrame.Get(isTLS))) + assert.Equal(t, http2Telemetry.Exceeding_max_interesting_frames, uint64(kernelTelemetryGroup.exceedingMaxInterestingFrames.Get(isTLS))) + assert.Equal(t, http2Telemetry.Exceeding_max_frames_to_filter, uint64(kernelTelemetryGroup.exceedingMaxFramesToFilter.Get(isTLS))) for i, bucket := range kernelTelemetryGroup.pathSizeBucket { - assert.Equal(t, http2Telemetry.Path_size_bucket[i], uint64(bucket.get(isTLS))) + assert.Equal(t, http2Telemetry.Path_size_bucket[i], uint64(bucket.Get(isTLS))) } } diff --git a/pkg/network/protocols/http2/types.go b/pkg/network/protocols/http2/types.go index dde3cdbdfdecb..5f167e83cbb73 100644 --- a/pkg/network/protocols/http2/types.go +++ b/pkg/network/protocols/http2/types.go @@ -9,6 +9,7 @@ package http2 /* #include "../../ebpf/c/conn_tuple.h" +#include "../../ebpf/c/protocols/events-types.h" #include "../../ebpf/c/protocols/http2/decoding-defs.h" */ import "C" diff --git a/pkg/network/protocols/http2/types_linux.go b/pkg/network/protocols/http2/types_linux.go index 7fc1f573449a3..2e08cc9d46797 100644 --- a/pkg/network/protocols/http2/types_linux.go +++ b/pkg/network/protocols/http2/types_linux.go @@ -7,7 +7,7 @@ const ( maxHTTP2Path = 0xa0 http2PathBuckets = 0x7 - HTTP2TerminatedBatchSize = 0x50 + HTTP2TerminatedBatchSize = 0x55 http2RawStatusCodeMaxLength = 0x3 diff --git a/pkg/network/protocols/postgres/ebpf/types_test.go b/pkg/network/protocols/postgres/ebpf/types_test.go new file mode 100644 index 0000000000000..9e64129b2402e --- /dev/null +++ b/pkg/network/protocols/postgres/ebpf/types_test.go @@ -0,0 +1,27 @@ +// 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 2024-present Datadog, Inc. + +//go:build linux_bpf + +package ebpf + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/DataDog/datadog-agent/pkg/network/config" +) + +// TestMaxPostgresTelemetryDefaultConfig validates that the default value matches the one in the Postgres eBPF package. +// This test is located here to avoid importing /pkg/network/protocols/postgres/ebpf/ +// into the /pkg/network/config package. +func TestMaxPostgresTelemetryDefaultConfig(t *testing.T) { + // Validating that the default value matches the one in the Postgres ebpf package. + t.Run("default", func(t *testing.T) { + cfg := config.New() + assert.Equal(t, BufferSize, cfg.MaxPostgresTelemetryBuffer) + }) +} diff --git a/pkg/network/protocols/postgres/pgx_testclient.go b/pkg/network/protocols/postgres/pgx_testclient.go index 03dbb4c4d7ff0..7c8c7c1a9fc1e 100644 --- a/pkg/network/protocols/postgres/pgx_testclient.go +++ b/pkg/network/protocols/postgres/pgx_testclient.go @@ -12,6 +12,7 @@ import ( "errors" "time" + "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" ) @@ -44,6 +45,24 @@ func (c *PGXClient) Ping() error { return c.DB.Ping(ctx) } +// Begin starts a new transaction. +func (c *PGXClient) Begin() (pgx.Tx, error) { + if c.DB == nil { + return nil, errors.New("db handle is nil") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + return c.DB.Begin(ctx) +} + +// Commit commits the transaction. +func (c *PGXClient) Commit(tx pgx.Tx) error { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + return tx.Commit(ctx) +} + // Close closes the connection to the database. func (c *PGXClient) Close() { c.DB.Close() @@ -51,9 +70,38 @@ func (c *PGXClient) Close() { // RunQuery runs a query on the database. func (c *PGXClient) RunQuery(query string, args ...any) error { - ctx, cancel := context.WithTimeout(context.Background(), 300*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() res, err := c.DB.Query(ctx, query, args...) res.Close() return err } + +// RunQueryTX runs a query on the database in the context of a transaction. +func (c *PGXClient) RunQueryTX(tx pgx.Tx, query string, args ...any) error { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + res, err := tx.Query(ctx, query, args...) + res.Close() + return err +} + +// SendBatch sends a batch of queries to the database. +func (c *PGXClient) SendBatch(queries ...string) error { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + batch := &pgx.Batch{} + for _, query := range queries { + batch.Queue(query) + } + batchObj := c.DB.SendBatch(ctx, batch) + defer batchObj.Close() + for i := 0; i < len(queries); i++ { + _, err := batchObj.Exec() + if err != nil { + return err + } + } + + return nil +} diff --git a/pkg/network/protocols/postgres/protocol.go b/pkg/network/protocols/postgres/protocol.go index cd26e0b9a5a3a..af1a51d688536 100644 --- a/pkg/network/protocols/postgres/protocol.go +++ b/pkg/network/protocols/postgres/protocol.go @@ -114,7 +114,7 @@ func newPostgresProtocol(cfg *config.Config) (protocols.Protocol, error) { return &protocol{ cfg: cfg, - telemetry: NewTelemetry(), + telemetry: NewTelemetry(cfg), statskeeper: NewStatkeeper(cfg), }, nil } diff --git a/pkg/network/protocols/postgres/telemetry.go b/pkg/network/protocols/postgres/telemetry.go index ed7bd9ddd95c2..bfdd93030c078 100644 --- a/pkg/network/protocols/postgres/telemetry.go +++ b/pkg/network/protocols/postgres/telemetry.go @@ -10,6 +10,7 @@ package postgres import ( "fmt" + "github.com/DataDog/datadog-agent/pkg/network/config" "github.com/DataDog/datadog-agent/pkg/network/protocols/postgres/ebpf" libtelemetry "github.com/DataDog/datadog-agent/pkg/network/protocols/telemetry" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -19,11 +20,6 @@ const ( numberOfBuckets = 10 bucketLength = 15 numberOfBucketsSmallerThanMaxBufferSize = 3 - // firstBucketLowerBoundary is the lower boundary of the first bucket. - // We add 1 in order to include BufferSize as the upper boundary of the third bucket. - // Then the first three buckets will include query lengths shorter or equal to BufferSize, - // and the rest will include sizes equal to or above the buffer size. - firstBucketLowerBoundary = ebpf.BufferSize - numberOfBucketsSmallerThanMaxBufferSize*bucketLength + 1 ) // Telemetry is a struct to hold the telemetry for the postgres protocol @@ -36,6 +32,11 @@ type Telemetry struct { failedTableNameExtraction *libtelemetry.Counter // failedOperationExtraction holds the counter for the failed operation extraction failedOperationExtraction *libtelemetry.Counter + // firstBucketLowerBoundary is the lower boundary of the first bucket. + // We add 1 in order to include BufferSize as the upper boundary of the third bucket. + // Then the first three buckets will include query lengths shorter or equal to BufferSize, + // and the rest will include sizes equal to or above the buffer size. + firstBucketLowerBoundary int } // createQueryLengthBuckets initializes the query length buckets @@ -59,20 +60,27 @@ func createQueryLengthBuckets(metricGroup *libtelemetry.MetricGroup) [numberOfBu } // NewTelemetry creates a new Telemetry -func NewTelemetry() *Telemetry { +func NewTelemetry(cfg *config.Config) *Telemetry { metricGroup := libtelemetry.NewMetricGroup("usm.postgres") + firstBucketLowerBoundary := cfg.MaxPostgresTelemetryBuffer - numberOfBucketsSmallerThanMaxBufferSize*bucketLength + 1 + if firstBucketLowerBoundary < 0 { + log.Warnf("The first bucket lower boundary is negative: %d", firstBucketLowerBoundary) + firstBucketLowerBoundary = ebpf.BufferSize - numberOfBucketsSmallerThanMaxBufferSize*bucketLength + 1 + } + return &Telemetry{ metricGroup: metricGroup, queryLengthBuckets: createQueryLengthBuckets(metricGroup), failedTableNameExtraction: metricGroup.NewCounter("failed_table_name_extraction", libtelemetry.OptStatsd), failedOperationExtraction: metricGroup.NewCounter("failed_operation_extraction", libtelemetry.OptStatsd), + firstBucketLowerBoundary: firstBucketLowerBoundary, } } // getBucketIndex returns the index of the bucket for the given query size -func getBucketIndex(querySize int) int { - bucketIndex := max(0, querySize-firstBucketLowerBoundary) / bucketLength +func (t *Telemetry) getBucketIndex(querySize int) int { + bucketIndex := max(0, querySize-t.firstBucketLowerBoundary) / bucketLength return min(bucketIndex, numberOfBuckets-1) } @@ -80,7 +88,7 @@ func getBucketIndex(querySize int) int { func (t *Telemetry) Count(tx *ebpf.EbpfEvent, eventWrapper *EventWrapper) { querySize := int(tx.Tx.Original_query_size) - bucketIndex := getBucketIndex(querySize) + bucketIndex := t.getBucketIndex(querySize) if bucketIndex >= 0 && bucketIndex < len(t.queryLengthBuckets) { t.queryLengthBuckets[bucketIndex].Add(1) } diff --git a/pkg/network/protocols/postgres/telemetry_test.go b/pkg/network/protocols/postgres/telemetry_test.go index 2680f465e5cfe..f1e5f9cf58a04 100644 --- a/pkg/network/protocols/postgres/telemetry_test.go +++ b/pkg/network/protocols/postgres/telemetry_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/DataDog/datadog-agent/pkg/network/config" "github.com/DataDog/datadog-agent/pkg/network/protocols/postgres/ebpf" "github.com/DataDog/datadog-agent/pkg/network/protocols/telemetry" ) @@ -40,17 +41,24 @@ func Test_getBucketIndex(t *testing.T) { {ebpf.BufferSize + 6*bucketLength + 1, ebpf.BufferSize + 7*bucketLength, 9}, } + cfg := config.New() + telemetry := NewTelemetry(cfg) + for _, tc := range testCases { for i := tc.start; i <= tc.end; i++ { - require.Equal(t, tc.expected, getBucketIndex(i), "query length %d should be in bucket %d", i, tc.expected) + require.Equal(t, tc.expected, telemetry.getBucketIndex(i), "query length %d should be in bucket %d", i, tc.expected) } } } +// telemetryTestBufferSize serves as example configuration for the telemetry buffer size. +const telemetryTestBufferSize = 2 * ebpf.BufferSize + func TestTelemetry_Count(t *testing.T) { tests := []struct { name string query string + maxBufferSize int tx []*ebpf.EbpfEvent expectedTelemetry telemetryResults }{ @@ -75,6 +83,50 @@ func TestTelemetry_Count(t *testing.T) { failedTableNameExtraction: 10, }, }, + { + name: "exceeded query length bucket for each bucket ones with telemetry config", + tx: []*ebpf.EbpfEvent{ + createEbpfEvent(telemetryTestBufferSize - 2*bucketLength), + createEbpfEvent(telemetryTestBufferSize - bucketLength), + createEbpfEvent(telemetryTestBufferSize), + createEbpfEvent(telemetryTestBufferSize + 1), + createEbpfEvent(telemetryTestBufferSize + bucketLength + 1), + createEbpfEvent(telemetryTestBufferSize + 2*bucketLength + 1), + createEbpfEvent(telemetryTestBufferSize + 3*bucketLength + 1), + createEbpfEvent(telemetryTestBufferSize + 4*bucketLength + 1), + createEbpfEvent(telemetryTestBufferSize + 5*bucketLength + 1), + createEbpfEvent(telemetryTestBufferSize + 6*bucketLength + 1), + }, + maxBufferSize: telemetryTestBufferSize, + + expectedTelemetry: telemetryResults{ + queryLength: [bucketLength]int64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + failedOperationExtraction: 10, + failedTableNameExtraction: 10, + }, + }, + { + name: "validating max buffer size which creates negative first bucket lower boundary", + tx: []*ebpf.EbpfEvent{ + createEbpfEvent(ebpf.BufferSize - 2*bucketLength), + createEbpfEvent(ebpf.BufferSize - bucketLength), + createEbpfEvent(ebpf.BufferSize), + createEbpfEvent(ebpf.BufferSize + 1), + createEbpfEvent(ebpf.BufferSize + bucketLength + 1), + createEbpfEvent(ebpf.BufferSize + 2*bucketLength + 1), + createEbpfEvent(ebpf.BufferSize + 3*bucketLength + 1), + createEbpfEvent(ebpf.BufferSize + 4*bucketLength + 1), + createEbpfEvent(ebpf.BufferSize + 5*bucketLength + 1), + createEbpfEvent(ebpf.BufferSize + 6*bucketLength + 1), + }, + maxBufferSize: 1, + + expectedTelemetry: telemetryResults{ + queryLength: [bucketLength]int64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + failedOperationExtraction: 10, + failedTableNameExtraction: 10, + }, + }, { name: "failed operation extraction", tx: []*ebpf.EbpfEvent{{}}, @@ -107,7 +159,12 @@ func TestTelemetry_Count(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { telemetry.Clear() - tel := NewTelemetry() + + cfg := config.New() + if tt.maxBufferSize > 0 { + cfg.MaxPostgresTelemetryBuffer = tt.maxBufferSize + } + tel := NewTelemetry(cfg) if tt.query != "" { tt.tx[0].Tx.Original_query_size = uint32(len(tt.query)) copy(tt.tx[0].Tx.Request_fragment[:], tt.query) diff --git a/pkg/network/protocols/telemetry/metric.go b/pkg/network/protocols/telemetry/metric.go index c610a141e6b8b..b44b0de0690ef 100644 --- a/pkg/network/protocols/telemetry/metric.go +++ b/pkg/network/protocols/telemetry/metric.go @@ -104,3 +104,35 @@ func (m *metricBase) Get() int64 { type metric interface { base() *metricBase } + +// TLSAwareCounter is a TLS aware counter, it has a plain counter and a counter for TLS. +// It enables the use of a single metric that increments based on the encryption, avoiding the need for separate metrics for eash use-case. +type TLSAwareCounter struct { + counterPlain *Counter + counterTLS *Counter +} + +// NewTLSAwareCounter creates and returns a new instance of TLSCounter +func NewTLSAwareCounter(metricGroup *MetricGroup, metricName string, tags ...string) *TLSAwareCounter { + return &TLSAwareCounter{ + counterPlain: metricGroup.NewCounter(metricName, append(tags, "encrypted:false")...), + counterTLS: metricGroup.NewCounter(metricName, append(tags, "encrypted:true")...), + } +} + +// Add adds the given delta to the counter based on the encryption. +func (c *TLSAwareCounter) Add(delta int64, isTLS bool) { + if isTLS { + c.counterTLS.Add(delta) + return + } + c.counterPlain.Add(delta) +} + +// Get returns the counter value based on the encryption. +func (c *TLSAwareCounter) Get(isTLS bool) int64 { + if isTLS { + return c.counterTLS.Get() + } + return c.counterPlain.Get() +} diff --git a/pkg/network/protocols/tls/nodejs/testdata/package.json b/pkg/network/protocols/tls/nodejs/testdata/package.json new file mode 100644 index 0000000000000..c4fe3a0a118da --- /dev/null +++ b/pkg/network/protocols/tls/nodejs/testdata/package.json @@ -0,0 +1,4 @@ +{ + "name": "nodejs-https-server" +} + diff --git a/pkg/network/state.go b/pkg/network/state.go index 708e535adeec5..7bd2684022837 100644 --- a/pkg/network/state.go +++ b/pkg/network/state.go @@ -74,9 +74,6 @@ const ( // constant is not worth the increased memory cost. DNSResponseCodeNoError = 0 - // ConnectionByteKeyMaxLen represents the maximum size in bytes of a connection byte key - ConnectionByteKeyMaxLen = 41 - stateModuleName = "network_tracer__state" shortLivedConnectionThreshold = 2 * time.Minute diff --git a/pkg/network/time_converter_windows.go b/pkg/network/time_converter_windows.go new file mode 100644 index 0000000000000..a3474d97d6d48 --- /dev/null +++ b/pkg/network/time_converter_windows.go @@ -0,0 +1,40 @@ +// 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. + +// Portions of this code are taken from the gopsutil project +// https://github.com/shirou/gopsutil . This code is licensed under the New BSD License +// copyright WAKAYAMA Shirou, and the gopsutil contributors + +package network + +import ( + "time" + + "golang.org/x/sys/windows" +) + +var ( + modkernel32 = windows.NewLazyDLL("kernel32.dll") + procGetTickCount64 = modkernel32.NewProc("GetTickCount64") + bootTime = time.Now().Add(-time.Duration(getTickCount64()) * time.Millisecond) +) + +// getTickCount64() returns the time, in milliseconds, that have elapsed since +// the system was started +func getTickCount64() int64 { + ret, _, _ := procGetTickCount64.Call() + return int64(ret) +} + +func driverTimeToUnixTime(t uint64) uint64 { + + // t is the number of microseconds since the system was started. + + // convert this to a unix timestamp + + opTime := bootTime.Add(time.Duration(t) * time.Microsecond) + return uint64(opTime.UnixNano()) + +} diff --git a/pkg/network/tracer/connection/cookie.go b/pkg/network/tracer/connection/cookie.go new file mode 100644 index 0000000000000..5e98858b46350 --- /dev/null +++ b/pkg/network/tracer/connection/cookie.go @@ -0,0 +1,44 @@ +// 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 2024-present Datadog, Inc. + +//go:build linux_bpf + +package connection + +import ( + "encoding/binary" + "hash" + + "github.com/twmb/murmur3" + + "github.com/DataDog/datadog-agent/pkg/network" + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +type cookieHasher struct { + hash hash.Hash64 + buf []byte +} + +func newCookieHasher() *cookieHasher { + return &cookieHasher{ + hash: murmur3.New64(), + buf: make([]byte, network.ConnectionByteKeyMaxLen), + } +} + +func (h *cookieHasher) Hash(stats *network.ConnectionStats) { + h.hash.Reset() + if err := binary.Write(h.hash, binary.BigEndian, stats.Cookie); err != nil { + log.Errorf("error writing cookie to hash: %s", err) + return + } + key := stats.ByteKey(h.buf) + if _, err := h.hash.Write(key); err != nil { + log.Errorf("error writing byte key to hash: %s", err) + return + } + stats.Cookie = h.hash.Sum64() +} diff --git a/pkg/network/tracer/connection/ebpf_tracer.go b/pkg/network/tracer/connection/ebpf_tracer.go new file mode 100644 index 0000000000000..0d6ad30bf5b81 --- /dev/null +++ b/pkg/network/tracer/connection/ebpf_tracer.go @@ -0,0 +1,733 @@ +// 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 2024-present Datadog, Inc. + +//go:build linux_bpf + +package connection + +import ( + "errors" + "fmt" + "io" + "math" + "sync" + "time" + + manager "github.com/DataDog/ebpf-manager" + "github.com/DataDog/ebpf-manager/tracefs" + "github.com/cihub/seelog" + "github.com/cilium/ebpf" + "github.com/prometheus/client_golang/prometheus" + "go.uber.org/atomic" + "golang.org/x/sys/unix" + + telemetryComponent "github.com/DataDog/datadog-agent/comp/core/telemetry" + ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" + "github.com/DataDog/datadog-agent/pkg/ebpf/maps" + ebpftelemetry "github.com/DataDog/datadog-agent/pkg/ebpf/telemetry" + "github.com/DataDog/datadog-agent/pkg/network" + "github.com/DataDog/datadog-agent/pkg/network/config" + netebpf "github.com/DataDog/datadog-agent/pkg/network/ebpf" + "github.com/DataDog/datadog-agent/pkg/network/ebpf/probes" + "github.com/DataDog/datadog-agent/pkg/network/protocols" + "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/failure" + "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/fentry" + "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/kprobe" + "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/util" + "github.com/DataDog/datadog-agent/pkg/telemetry" + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +const ( + defaultClosedChannelSize = 500 + defaultFailedChannelSize = 500 + connTracerModuleName = "network_tracer__ebpf" +) + +//nolint:revive // TODO(NET) Fix revive linter +var EbpfTracerTelemetry = struct { + connections telemetry.Gauge + tcpFailedConnects *prometheus.Desc + //nolint:revive // TODO(NET) Fix revive linter + TcpSentMiscounts *prometheus.Desc + //nolint:revive // TODO(NET) Fix revive linter + unbatchedTcpClose *prometheus.Desc + //nolint:revive // TODO(NET) Fix revive linter + unbatchedUdpClose *prometheus.Desc + //nolint:revive // TODO(NET) Fix revive linter + UdpSendsProcessed *prometheus.Desc + //nolint:revive // TODO(NET) Fix revive linter + UdpSendsMissed *prometheus.Desc + //nolint:revive // TODO(NET) Fix revive linter + UdpDroppedConns *prometheus.Desc + // doubleFlushAttemptsClose is a counter measuring the number of attempts to flush a closed connection twice from tcp_close + doubleFlushAttemptsClose *prometheus.Desc + // doubleFlushAttemptsDone is a counter measuring the number of attempts to flush a closed connection twice from tcp_done + doubleFlushAttemptsDone *prometheus.Desc + // unsupportedTcpFailures is a counter measuring the number of attempts to flush a TCP failure that is not supported + unsupportedTcpFailures *prometheus.Desc + // tcpDonePidMismatch is a counter measuring the number of TCP connections with a PID mismatch between tcp_connect and tcp_done + tcpDonePidMismatch *prometheus.Desc + PidCollisions *telemetry.StatCounterWrapper + iterationDups telemetry.Counter + iterationAborts telemetry.Counter + + //nolint:revive // TODO(NET) Fix revive linter + lastTcpFailedConnects *atomic.Int64 + //nolint:revive // TODO(NET) Fix revive linter + LastTcpSentMiscounts *atomic.Int64 + //nolint:revive // TODO(NET) Fix revive linter + lastUnbatchedTcpClose *atomic.Int64 + //nolint:revive // TODO(NET) Fix revive linter + lastUnbatchedUdpClose *atomic.Int64 + //nolint:revive // TODO(NET) Fix revive linter + lastUdpSendsProcessed *atomic.Int64 + //nolint:revive // TODO(NET) Fix revive linter + lastUdpSendsMissed *atomic.Int64 + //nolint:revive // TODO(NET) Fix revive linter + lastUdpDroppedConns *atomic.Int64 + // lastDoubleFlushAttemptsClose is a counter measuring the diff between the last two values of doubleFlushAttemptsClose + lastDoubleFlushAttemptsClose *atomic.Int64 + // lastDoubleFlushAttemptsDone is a counter measuring the diff between the last two values of doubleFlushAttemptsDone + lastDoubleFlushAttemptsDone *atomic.Int64 + // lastUnsupportedTcpFailures is a counter measuring the diff between the last two values of unsupportedTcpFailures + lastUnsupportedTcpFailures *atomic.Int64 + // lastTcpDonePidMismatch is a counter measuring the diff between the last two values of tcpDonePidMismatch + lastTcpDonePidMismatch *atomic.Int64 +}{ + telemetry.NewGauge(connTracerModuleName, "connections", []string{"ip_proto", "family"}, "Gauge measuring the number of active connections in the EBPF map"), + prometheus.NewDesc(connTracerModuleName+"__tcp_failed_connects", "Counter measuring the number of failed TCP connections in the EBPF map", nil, nil), + prometheus.NewDesc(connTracerModuleName+"__tcp_sent_miscounts", "Counter measuring the number of miscounted tcp sends in the EBPF map", nil, nil), + prometheus.NewDesc(connTracerModuleName+"__unbatched_tcp_close", "Counter measuring the number of missed TCP close events in the EBPF map", nil, nil), + prometheus.NewDesc(connTracerModuleName+"__unbatched_udp_close", "Counter measuring the number of missed UDP close events in the EBPF map", nil, nil), + prometheus.NewDesc(connTracerModuleName+"__udp_sends_processed", "Counter measuring the number of processed UDP sends in EBPF", nil, nil), + prometheus.NewDesc(connTracerModuleName+"__udp_sends_missed", "Counter measuring failures to process UDP sends in EBPF", nil, nil), + prometheus.NewDesc(connTracerModuleName+"__udp_dropped_conns", "Counter measuring the number of dropped UDP connections in the EBPF map", nil, nil), + prometheus.NewDesc(connTracerModuleName+"__double_flush_attempts_close", "Counter measuring the number of attempts to flush a closed connection twice from tcp_close", nil, nil), + prometheus.NewDesc(connTracerModuleName+"__double_flush_attempts_done", "Counter measuring the number of attempts to flush a closed connection twice from tcp_done", nil, nil), + prometheus.NewDesc(connTracerModuleName+"__unsupported_tcp_failures", "Counter measuring the number of attempts to flush a TCP failure that is not supported", nil, nil), + prometheus.NewDesc(connTracerModuleName+"__tcp_done_pid_mismatch", "Counter measuring the number of TCP connections with a PID mismatch between tcp_connect and tcp_done", nil, nil), + telemetry.NewStatCounterWrapper(connTracerModuleName, "pid_collisions", []string{}, "Counter measuring number of process collisions"), + telemetry.NewCounter(connTracerModuleName, "iteration_dups", []string{}, "Counter measuring the number of connections iterated more than once"), + telemetry.NewCounter(connTracerModuleName, "iteration_aborts", []string{}, "Counter measuring how many times ebpf iteration of connection map was aborted"), + atomic.NewInt64(0), + atomic.NewInt64(0), + atomic.NewInt64(0), + atomic.NewInt64(0), + atomic.NewInt64(0), + atomic.NewInt64(0), + atomic.NewInt64(0), + atomic.NewInt64(0), + atomic.NewInt64(0), + atomic.NewInt64(0), + atomic.NewInt64(0), +} + +type ebpfTracer struct { + m *manager.Manager + + conns *maps.GenericMap[netebpf.ConnTuple, netebpf.ConnStats] + tcpStats *maps.GenericMap[netebpf.ConnTuple, netebpf.TCPStats] + tcpRetransmits *maps.GenericMap[netebpf.ConnTuple, uint32] + config *config.Config + + // tcp_close events + closeConsumer *tcpCloseConsumer + // tcp failure events + failedConnConsumer *failure.TCPFailedConnConsumer + + removeTuple *netebpf.ConnTuple + + closeTracer func() + stopOnce sync.Once + + ebpfTracerType TracerType + + exitTelemetry chan struct{} + + ch *cookieHasher +} + +// NewTracer creates a new tracer +func newEbpfTracer(config *config.Config, _ telemetryComponent.Component) (Tracer, error) { + if _, err := tracefs.Root(); err != nil { + return nil, fmt.Errorf("eBPF based network tracer unsupported: %s", err) + } + + mgrOptions := manager.Options{ + // Extend RLIMIT_MEMLOCK (8) size + // On some systems, the default for RLIMIT_MEMLOCK may be as low as 64 bytes. + // This will result in an EPERM (Operation not permitted) error, when trying to create an eBPF map + // using bpf(2) with BPF_MAP_CREATE. + // + // We are setting the limit to infinity until we have a better handle on the true requirements. + RLimit: &unix.Rlimit{ + Cur: math.MaxUint64, + Max: math.MaxUint64, + }, + MapSpecEditors: map[string]manager.MapSpecEditor{ + probes.ConnMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, + probes.TCPStatsMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, + probes.TCPRetransmitsMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, + probes.PortBindingsMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, + probes.UDPPortBindingsMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, + probes.ConnectionProtocolMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, + probes.ConnectionTupleToSocketSKBConnMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, + }, + ConstantEditors: []manager.ConstantEditor{ + boolConst("tcpv6_enabled", config.CollectTCPv6Conns), + boolConst("udpv6_enabled", config.CollectUDPv6Conns), + }, + DefaultKProbeMaxActive: maxActive, + BypassEnabled: config.BypassEnabled, + } + + begin, end := network.EphemeralRange() + mgrOptions.ConstantEditors = append(mgrOptions.ConstantEditors, + manager.ConstantEditor{Name: "ephemeral_range_begin", Value: uint64(begin)}, + manager.ConstantEditor{Name: "ephemeral_range_end", Value: uint64(end)}) + + closedChannelSize := defaultClosedChannelSize + if config.ClosedChannelSize > 0 { + closedChannelSize = config.ClosedChannelSize + } + var connCloseEventHandler ddebpf.EventHandler + var failedConnsHandler ddebpf.EventHandler + if config.RingBufferSupportedNPM() { + connCloseEventHandler = ddebpf.NewRingBufferHandler(closedChannelSize) + failedConnsHandler = ddebpf.NewRingBufferHandler(defaultFailedChannelSize) + } else { + connCloseEventHandler = ddebpf.NewPerfHandler(closedChannelSize) + failedConnsHandler = ddebpf.NewPerfHandler(defaultFailedChannelSize) + } + + var m *manager.Manager + //nolint:revive // TODO(NET) Fix revive linter + var tracerType TracerType = TracerTypeFentry + var closeTracerFn func() + m, closeTracerFn, err := fentry.LoadTracer(config, mgrOptions, connCloseEventHandler) + if err != nil && !errors.Is(err, fentry.ErrorNotSupported) { + // failed to load fentry tracer + return nil, err + } + + if err != nil { + // load the kprobe tracer + log.Info("loading kprobe-based tracer") + var kprobeTracerType kprobe.TracerType + m, closeTracerFn, kprobeTracerType, err = kprobe.LoadTracer(config, mgrOptions, connCloseEventHandler, failedConnsHandler) + if err != nil { + return nil, err + } + tracerType = TracerType(kprobeTracerType) + } + m.DumpHandler = dumpMapsHandler + ddebpf.AddNameMappings(m, "npm_tracer") + + numCPUs, err := ebpf.PossibleCPU() + if err != nil { + return nil, fmt.Errorf("could not determine number of CPUs: %w", err) + } + extractor := newBatchExtractor(numCPUs) + batchMgr, err := newConnBatchManager(m, extractor) + if err != nil { + return nil, fmt.Errorf("could not create connection batch manager: %w", err) + } + + closeConsumer := newTCPCloseConsumer(connCloseEventHandler, batchMgr) + + var failedConnConsumer *failure.TCPFailedConnConsumer + // Failed connections are not supported on prebuilt + if tracerType == TracerTypeKProbePrebuilt { + config.TCPFailedConnectionsEnabled = false + } + if config.FailedConnectionsSupported() { + failedConnConsumer = failure.NewFailedConnConsumer(failedConnsHandler, m, config.MaxFailedConnectionsBuffered) + } + + tr := &ebpfTracer{ + m: m, + config: config, + closeConsumer: closeConsumer, + failedConnConsumer: failedConnConsumer, + removeTuple: &netebpf.ConnTuple{}, + closeTracer: closeTracerFn, + ebpfTracerType: tracerType, + exitTelemetry: make(chan struct{}), + ch: newCookieHasher(), + } + + tr.conns, err = maps.GetMap[netebpf.ConnTuple, netebpf.ConnStats](m, probes.ConnMap) + if err != nil { + tr.Stop() + return nil, fmt.Errorf("error retrieving the bpf %s map: %s", probes.ConnMap, err) + } + + tr.tcpStats, err = maps.GetMap[netebpf.ConnTuple, netebpf.TCPStats](m, probes.TCPStatsMap) + if err != nil { + tr.Stop() + return nil, fmt.Errorf("error retrieving the bpf %s map: %s", probes.TCPStatsMap, err) + } + + if tr.tcpRetransmits, err = maps.GetMap[netebpf.ConnTuple, uint32](m, probes.TCPRetransmitsMap); err != nil { + tr.Stop() + return nil, fmt.Errorf("error retrieving the bpf %s map: %s", probes.TCPRetransmitsMap, err) + } + + return tr, nil +} + +func boolConst(name string, value bool) manager.ConstantEditor { + c := manager.ConstantEditor{ + Name: name, + Value: uint64(1), + } + if !value { + c.Value = uint64(0) + } + + return c +} + +func (t *ebpfTracer) Start(callback func(*network.ConnectionStats)) (err error) { + defer func() { + if err != nil { + t.Stop() + } + }() + + err = t.initializePortBindingMaps() + if err != nil { + return fmt.Errorf("error initializing port binding maps: %s", err) + } + + if err := t.m.Start(); err != nil { + return fmt.Errorf("could not start ebpf manager: %s", err) + } + + t.closeConsumer.Start(callback) + t.failedConnConsumer.Start() + return nil +} + +func (t *ebpfTracer) Pause() error { + // add small delay for socket filters to properly detach + time.Sleep(1 * time.Millisecond) + return t.m.Pause() +} + +func (t *ebpfTracer) Resume() error { + err := t.m.Resume() + // add small delay for socket filters to properly attach + time.Sleep(1 * time.Millisecond) + return err +} + +func (t *ebpfTracer) FlushPending() { + t.closeConsumer.FlushPending() +} + +func (t *ebpfTracer) GetFailedConnections() *failure.FailedConns { + if t.failedConnConsumer == nil { + return nil + } + return t.failedConnConsumer.FailedConns +} + +func (t *ebpfTracer) Stop() { + t.stopOnce.Do(func() { + close(t.exitTelemetry) + ddebpf.RemoveNameMappings(t.m) + ebpftelemetry.UnregisterTelemetry(t.m) + _ = t.m.Stop(manager.CleanAll) + t.closeConsumer.Stop() + t.failedConnConsumer.Stop() + if t.closeTracer != nil { + t.closeTracer() + } + }) +} + +func (t *ebpfTracer) GetMap(name string) *ebpf.Map { + switch name { + case probes.ConnectionProtocolMap: + default: + return nil + } + m, _, _ := t.m.GetMap(name) + return m +} + +func (t *ebpfTracer) GetConnections(buffer *network.ConnectionBuffer, filter func(*network.ConnectionStats) bool) error { + // Iterate through all key-value pairs in map + key, stats := &netebpf.ConnTuple{}, &netebpf.ConnStats{} + seen := make(map[netebpf.ConnTuple]struct{}) + // connsByTuple is used to detect whether we are iterating over + // a connection we have previously seen. This can happen when + // ebpf maps are being iterated over and deleted at the same time. + // The iteration can reset when that happens. + // See https://justin.azoff.dev/blog/bpf_map_get_next_key-pitfalls/ + connsByTuple := make(map[netebpf.ConnTuple]uint32) + + // Cached objects + conn := new(network.ConnectionStats) + tcp := new(netebpf.TCPStats) + + var tcp4, tcp6, udp4, udp6 float64 + entries := t.conns.Iterate() + for entries.Next(key, stats) { + if cookie, exists := connsByTuple[*key]; exists && cookie == stats.Cookie { + // already seen the connection in current batch processing, + // due to race between the iterator and bpf_map_delete + EbpfTracerTelemetry.iterationDups.Inc() + continue + } + + populateConnStats(conn, key, stats, t.ch) + connsByTuple[*key] = stats.Cookie + + isTCP := conn.Type == network.TCP + switch conn.Family { + case network.AFINET6: + if isTCP { + tcp6++ + } else { + udp6++ + } + case network.AFINET: + if isTCP { + tcp4++ + } else { + udp4++ + } + } + + if filter != nil && !filter(conn) { + continue + } + + if t.getTCPStats(tcp, key) { + updateTCPStats(conn, tcp, 0) + } + if retrans, ok := t.getTCPRetransmits(key, seen); ok { + updateTCPStats(conn, nil, retrans) + } + + *buffer.Next() = *conn + } + + if err := entries.Err(); err != nil { + if !errors.Is(err, ebpf.ErrIterationAborted) { + return fmt.Errorf("unable to iterate connection map: %w", err) + } + + log.Warn("eBPF conn_stats map iteration aborted. Some connections may not be reported") + EbpfTracerTelemetry.iterationAborts.Inc() + } + + updateTelemetry(tcp4, tcp6, udp4, udp6) + + return nil +} + +func updateTelemetry(tcp4 float64, tcp6 float64, udp4 float64, udp6 float64) { + EbpfTracerTelemetry.connections.Set(tcp4, "tcp", "v4") + EbpfTracerTelemetry.connections.Set(tcp6, "tcp", "v6") + EbpfTracerTelemetry.connections.Set(udp4, "udp", "v4") + EbpfTracerTelemetry.connections.Set(udp6, "udp", "v6") +} + +func removeConnectionFromTelemetry(conn *network.ConnectionStats) { + isTCP := conn.Type == network.TCP + switch conn.Family { + case network.AFINET6: + if isTCP { + EbpfTracerTelemetry.connections.Dec("tcp", "v6") + } else { + EbpfTracerTelemetry.connections.Dec("udp", "v6") + } + case network.AFINET: + if isTCP { + EbpfTracerTelemetry.connections.Dec("tcp", "v4") + } else { + EbpfTracerTelemetry.connections.Dec("udp", "v4") + } + } +} + +func (t *ebpfTracer) Remove(conn *network.ConnectionStats) error { + util.ConnStatsToTuple(conn, t.removeTuple) + + err := t.conns.Delete(t.removeTuple) + if err != nil { + // If this entry no longer exists in the eBPF map it means `tcp_close` has executed + // during this function call. In that case state.StoreClosedConnection() was already called for this connection, + // and we can't delete the corresponding client state, or we'll likely over-report the metric values. + // By skipping to the next iteration and not calling state.RemoveConnections() we'll let + // this connection expire "naturally" when either next connection check runs or the client itself expires. + return err + } + + removeConnectionFromTelemetry(conn) + + if conn.Type == network.TCP { + // We can ignore the error for this map since it will not always contain the entry + _ = t.tcpStats.Delete(t.removeTuple) + // We remove the PID from the tuple as it is not used in the retransmits map + pid := t.removeTuple.Pid + t.removeTuple.Pid = 0 + _ = t.tcpRetransmits.Delete(t.removeTuple) + t.removeTuple.Pid = pid + } + return nil +} + +func (t *ebpfTracer) getEBPFTelemetry() *netebpf.Telemetry { + var zero uint32 + mp, err := maps.GetMap[uint32, netebpf.Telemetry](t.m, probes.TelemetryMap) + if err != nil { + log.Warnf("error retrieving telemetry map: %s", err) + return nil + } + + tm := &netebpf.Telemetry{} + if err := mp.Lookup(&zero, tm); err != nil { + // This can happen if we haven't initialized the telemetry object yet + // so let's just use a trace log + if log.ShouldLog(seelog.TraceLvl) { + log.Tracef("error retrieving the telemetry struct: %s", err) + } + return nil + } + return tm +} + +// Describe returns all descriptions of the collector +func (t *ebpfTracer) Describe(ch chan<- *prometheus.Desc) { + ch <- EbpfTracerTelemetry.tcpFailedConnects + ch <- EbpfTracerTelemetry.TcpSentMiscounts + ch <- EbpfTracerTelemetry.unbatchedTcpClose + ch <- EbpfTracerTelemetry.unbatchedUdpClose + ch <- EbpfTracerTelemetry.UdpSendsProcessed + ch <- EbpfTracerTelemetry.UdpSendsMissed + ch <- EbpfTracerTelemetry.UdpDroppedConns + ch <- EbpfTracerTelemetry.doubleFlushAttemptsClose + ch <- EbpfTracerTelemetry.doubleFlushAttemptsDone + ch <- EbpfTracerTelemetry.unsupportedTcpFailures + ch <- EbpfTracerTelemetry.tcpDonePidMismatch +} + +// Collect returns the current state of all metrics of the collector +func (t *ebpfTracer) Collect(ch chan<- prometheus.Metric) { + ebpfTelemetry := t.getEBPFTelemetry() + if ebpfTelemetry == nil { + return + } + delta := int64(ebpfTelemetry.Tcp_failed_connect) - EbpfTracerTelemetry.lastTcpFailedConnects.Load() + EbpfTracerTelemetry.lastTcpFailedConnects.Store(int64(ebpfTelemetry.Tcp_failed_connect)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.tcpFailedConnects, prometheus.CounterValue, float64(delta)) + + delta = int64(ebpfTelemetry.Tcp_sent_miscounts) - EbpfTracerTelemetry.LastTcpSentMiscounts.Load() + EbpfTracerTelemetry.LastTcpSentMiscounts.Store(int64(ebpfTelemetry.Tcp_sent_miscounts)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.TcpSentMiscounts, prometheus.CounterValue, float64(delta)) + + delta = int64(ebpfTelemetry.Unbatched_tcp_close) - EbpfTracerTelemetry.lastUnbatchedTcpClose.Load() + EbpfTracerTelemetry.lastUnbatchedTcpClose.Store(int64(ebpfTelemetry.Unbatched_tcp_close)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.unbatchedTcpClose, prometheus.CounterValue, float64(delta)) + + delta = int64(ebpfTelemetry.Unbatched_udp_close) - EbpfTracerTelemetry.lastUnbatchedUdpClose.Load() + EbpfTracerTelemetry.lastUnbatchedUdpClose.Store(int64(ebpfTelemetry.Unbatched_udp_close)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.unbatchedUdpClose, prometheus.CounterValue, float64(delta)) + + delta = int64(ebpfTelemetry.Udp_sends_processed) - EbpfTracerTelemetry.lastUdpSendsProcessed.Load() + EbpfTracerTelemetry.lastUdpSendsProcessed.Store(int64(ebpfTelemetry.Udp_sends_processed)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.UdpSendsProcessed, prometheus.CounterValue, float64(delta)) + + delta = int64(ebpfTelemetry.Udp_sends_missed) - EbpfTracerTelemetry.lastUdpSendsMissed.Load() + EbpfTracerTelemetry.lastUdpSendsMissed.Store(int64(ebpfTelemetry.Udp_sends_missed)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.UdpSendsMissed, prometheus.CounterValue, float64(delta)) + + delta = int64(ebpfTelemetry.Udp_dropped_conns) - EbpfTracerTelemetry.lastUdpDroppedConns.Load() + EbpfTracerTelemetry.lastUdpDroppedConns.Store(int64(ebpfTelemetry.Udp_dropped_conns)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.UdpDroppedConns, prometheus.CounterValue, float64(delta)) + + delta = int64(ebpfTelemetry.Double_flush_attempts_close) - EbpfTracerTelemetry.lastDoubleFlushAttemptsClose.Load() + EbpfTracerTelemetry.lastDoubleFlushAttemptsClose.Store(int64(ebpfTelemetry.Double_flush_attempts_close)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.doubleFlushAttemptsClose, prometheus.CounterValue, float64(delta)) + + delta = int64(ebpfTelemetry.Double_flush_attempts_done) - EbpfTracerTelemetry.lastDoubleFlushAttemptsDone.Load() + EbpfTracerTelemetry.lastDoubleFlushAttemptsDone.Store(int64(ebpfTelemetry.Double_flush_attempts_done)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.doubleFlushAttemptsDone, prometheus.CounterValue, float64(delta)) + + delta = int64(ebpfTelemetry.Unsupported_tcp_failures) - EbpfTracerTelemetry.lastUnsupportedTcpFailures.Load() + EbpfTracerTelemetry.lastUnsupportedTcpFailures.Store(int64(ebpfTelemetry.Unsupported_tcp_failures)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.unsupportedTcpFailures, prometheus.CounterValue, float64(delta)) + + delta = int64(ebpfTelemetry.Tcp_done_pid_mismatch) - EbpfTracerTelemetry.lastTcpDonePidMismatch.Load() + EbpfTracerTelemetry.lastTcpDonePidMismatch.Store(int64(ebpfTelemetry.Tcp_done_pid_mismatch)) + ch <- prometheus.MustNewConstMetric(EbpfTracerTelemetry.tcpDonePidMismatch, prometheus.CounterValue, float64(delta)) + +} + +// DumpMaps (for debugging purpose) returns all maps content by default or selected maps from maps parameter. +func (t *ebpfTracer) DumpMaps(w io.Writer, maps ...string) error { + return t.m.DumpMaps(w, maps...) +} + +// Type returns the type of the underlying ebpf tracer that is currently loaded +func (t *ebpfTracer) Type() TracerType { + return t.ebpfTracerType +} + +func (t *ebpfTracer) initializePortBindingMaps() error { + tcpPorts, err := network.ReadListeningPorts(t.config.ProcRoot, network.TCP, t.config.CollectTCPv6Conns) + if err != nil { + return fmt.Errorf("failed to read initial TCP pid->port mapping: %s", err) + } + + tcpPortMap, err := maps.GetMap[netebpf.PortBinding, uint32](t.m, probes.PortBindingsMap) + if err != nil { + return fmt.Errorf("failed to get TCP port binding map: %w", err) + } + for p, count := range tcpPorts { + log.Debugf("adding initial TCP port binding: netns: %d port: %d", p.Ino, p.Port) + pb := netebpf.PortBinding{Netns: p.Ino, Port: p.Port} + err = tcpPortMap.Update(&pb, &count, ebpf.UpdateNoExist) + if err != nil && !errors.Is(err, ebpf.ErrKeyExist) { + return fmt.Errorf("failed to update TCP port binding map: %w", err) + } + } + + udpPorts, err := network.ReadListeningPorts(t.config.ProcRoot, network.UDP, t.config.CollectUDPv6Conns) + if err != nil { + return fmt.Errorf("failed to read initial UDP pid->port mapping: %s", err) + } + + udpPortMap, err := maps.GetMap[netebpf.PortBinding, uint32](t.m, probes.UDPPortBindingsMap) + if err != nil { + return fmt.Errorf("failed to get UDP port binding map: %w", err) + } + for p, count := range udpPorts { + // ignore ephemeral port binds as they are more likely to be from + // clients calling bind with port 0 + if network.IsPortInEphemeralRange(network.AFINET, network.UDP, p.Port) == network.EphemeralTrue { + log.Debugf("ignoring initial ephemeral UDP port bind to %d", p) + continue + } + + log.Debugf("adding initial UDP port binding: netns: %d port: %d", p.Ino, p.Port) + pb := netebpf.PortBinding{Netns: p.Ino, Port: p.Port} + err = udpPortMap.Update(&pb, &count, ebpf.UpdateNoExist) + if err != nil && !errors.Is(err, ebpf.ErrKeyExist) { + return fmt.Errorf("failed to update UDP port binding map: %w", err) + } + } + return nil +} + +func (t *ebpfTracer) getTCPRetransmits(tuple *netebpf.ConnTuple, seen map[netebpf.ConnTuple]struct{}) (uint32, bool) { + if tuple.Type() != netebpf.TCP { + return 0, false + } + + // The PID isn't used as a key in the stats map, we will temporarily set it to 0 here and reset it when we're done + pid := tuple.Pid + tuple.Pid = 0 + + var retransmits uint32 + if err := t.tcpRetransmits.Lookup(tuple, &retransmits); err == nil { + // This is required to avoid (over)reporting retransmits for connections sharing the same socket. + if _, reported := seen[*tuple]; reported { + EbpfTracerTelemetry.PidCollisions.Inc() + retransmits = 0 + } else { + seen[*tuple] = struct{}{} + } + } + + tuple.Pid = pid + return retransmits, true +} + +// getTCPStats reads tcp related stats for the given ConnTuple +func (t *ebpfTracer) getTCPStats(stats *netebpf.TCPStats, tuple *netebpf.ConnTuple) bool { + if tuple.Type() != netebpf.TCP { + return false + } + + return t.tcpStats.Lookup(tuple, stats) == nil +} + +func populateConnStats(stats *network.ConnectionStats, t *netebpf.ConnTuple, s *netebpf.ConnStats, ch *cookieHasher) { + *stats = network.ConnectionStats{ + Pid: t.Pid, + NetNS: t.Netns, + Source: t.SourceAddress(), + Dest: t.DestAddress(), + SPort: t.Sport, + DPort: t.Dport, + Monotonic: network.StatCounters{ + SentBytes: s.Sent_bytes, + RecvBytes: s.Recv_bytes, + SentPackets: uint64(s.Sent_packets), + RecvPackets: uint64(s.Recv_packets), + }, + LastUpdateEpoch: s.Timestamp, + IsAssured: s.IsAssured(), + Cookie: network.StatCookie(s.Cookie), + } + + if s.Duration <= uint64(math.MaxInt64) { + stats.Duration = time.Duration(s.Duration) * time.Nanosecond + } + + stats.ProtocolStack = protocols.Stack{ + API: protocols.API(s.Protocol_stack.Api), + Application: protocols.Application(s.Protocol_stack.Application), + Encryption: protocols.Encryption(s.Protocol_stack.Encryption), + } + + if t.Type() == netebpf.TCP { + stats.Type = network.TCP + } else { + stats.Type = network.UDP + } + + switch t.Family() { + case netebpf.IPv4: + stats.Family = network.AFINET + case netebpf.IPv6: + stats.Family = network.AFINET6 + } + + stats.SPortIsEphemeral = network.IsPortInEphemeralRange(stats.Family, stats.Type, t.Sport) + + switch s.ConnectionDirection() { + case netebpf.Incoming: + stats.Direction = network.INCOMING + case netebpf.Outgoing: + stats.Direction = network.OUTGOING + default: + stats.Direction = network.OUTGOING + } + + if ch != nil { + ch.Hash(stats) + } +} + +func updateTCPStats(conn *network.ConnectionStats, tcpStats *netebpf.TCPStats, retransmits uint32) { + if conn.Type != network.TCP { + return + } + + conn.Monotonic.Retransmits = retransmits + if tcpStats != nil { + conn.Monotonic.TCPEstablished = uint32(tcpStats.State_transitions >> netebpf.Established & 1) + conn.Monotonic.TCPClosed = uint32(tcpStats.State_transitions >> netebpf.Close & 1) + conn.RTT = tcpStats.Rtt + conn.RTTVar = tcpStats.Rtt_var + } +} diff --git a/pkg/network/tracer/connection/ebpfless/payload.go b/pkg/network/tracer/connection/ebpfless/payload.go new file mode 100644 index 0000000000000..50d9e1d190b53 --- /dev/null +++ b/pkg/network/tracer/connection/ebpfless/payload.go @@ -0,0 +1,102 @@ +// 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 2024-present Datadog, Inc. + +//go:build linux + +// Package ebpfless contains supporting code for the ebpfless tracer +package ebpfless + +import ( + "errors" + "fmt" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + + "github.com/DataDog/datadog-agent/pkg/network" +) + +var errZeroLengthUDPPacket = errors.New("UDP packet with length 0") +var errZeroLengthIPPacket = errors.New("IP packet with length 0") + +// UDPPayloadLen returns the UDP payload length from a layers.UDP object +func UDPPayloadLen(udp *layers.UDP) (uint16, error) { + if udp.Length == 0 { + return 0, errZeroLengthUDPPacket + } + + // Length includes the header (8 bytes), + // so we need to exclude that here + return udp.Length - 8, nil +} + +// TCPPayloadLen returns the TCP payload length from a layers.TCP object +func TCPPayloadLen(family network.ConnectionFamily, ip4 *layers.IPv4, ip6 *layers.IPv6, tcp *layers.TCP) (uint16, error) { + var ipl uint16 + var err error + switch family { + case network.AFINET: + ipl, err = ipv4PayloadLen(ip4) + case network.AFINET6: + ipl, err = ipv6PayloadLen(ip6) + default: + return 0, fmt.Errorf("unknown family %s", family) + } + + if err != nil { + return 0, nil + } + + if ipl == 0 { + return 0, errZeroLengthIPPacket + } + + // the data offset field in the TCP header specifies + // the length of the TCP header in 32 bit words, so + // subtracting that here to get the payload size + // + // see https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure + return ipl - uint16(tcp.DataOffset)*4, nil +} + +func ipv4PayloadLen(ip4 *layers.IPv4) (uint16, error) { + // the IHL field specifies the the size of the IP + // header in 32 bit words, so subtracting that here + // to get the payload size + // + // see https://en.wikipedia.org/wiki/IPv4#Header + return ip4.Length - uint16(ip4.IHL)*4, nil +} + +func ipv6PayloadLen(ip6 *layers.IPv6) (uint16, error) { + if ip6.NextHeader == layers.IPProtocolUDP || ip6.NextHeader == layers.IPProtocolTCP { + return ip6.Length, nil + } + + var ipExt layers.IPv6ExtensionSkipper + parser := gopacket.NewDecodingLayerParser(gopacket.LayerTypePayload, &ipExt) + decoded := make([]gopacket.LayerType, 0, 1) + l := ip6.Length + payload := ip6.Payload + for len(payload) > 0 { + err := parser.DecodeLayers(payload, &decoded) + if err != nil { + return 0, fmt.Errorf("error decoding with ipv6 extension skipper: %w", err) + } + + if len(decoded) == 0 { + return l, nil + } + + l -= uint16(len(ipExt.Contents)) + if ipExt.NextHeader == layers.IPProtocolTCP || ipExt.NextHeader == layers.IPProtocolUDP { + break + } + + payload = ipExt.Payload + } + + return l, nil +} diff --git a/pkg/network/tracer/connection/ebpfless/ports.go b/pkg/network/tracer/connection/ebpfless/ports.go new file mode 100644 index 0000000000000..00ebebf273c64 --- /dev/null +++ b/pkg/network/tracer/connection/ebpfless/ports.go @@ -0,0 +1,130 @@ +// 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 2024-present Datadog, Inc. + +//go:build linux + +// Package ebpfless contains supporting code for the ebpfless tracer +package ebpfless + +import ( + "fmt" + "sync" + "time" + + "github.com/DataDog/datadog-agent/pkg/network" + "github.com/DataDog/datadog-agent/pkg/network/config" + "github.com/DataDog/datadog-agent/pkg/util/kernel" + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +type boundPortsKey struct { + proto network.ConnectionType + port uint16 +} + +// BoundPorts is a collection of bound ports on the host +// that is periodically updated from procfs +type BoundPorts struct { + mu sync.RWMutex + + config *config.Config + ports map[boundPortsKey]struct{} + + stop chan struct{} + ino uint32 +} + +// NewBoundPorts returns a new BoundPorts instance +func NewBoundPorts(cfg *config.Config) *BoundPorts { + ino, _ := kernel.GetCurrentIno() + return &BoundPorts{ + config: cfg, + ports: map[boundPortsKey]struct{}{}, + stop: make(chan struct{}), + ino: ino, + } +} + +// Start starts a BoundPorts instance +func (b *BoundPorts) Start() error { + if err := b.update(); err != nil { + return err + } + + go func() { + ticker := time.NewTicker(10 * time.Second) + defer ticker.Stop() + for { + select { + case <-b.stop: + return + case <-ticker.C: + if err := b.update(); err != nil { + log.Errorf("error updating bound ports, exiting loop: %s", err) + return + } + } + } + }() + + return nil +} + +// Stop stops a BoundPorts instance +func (b *BoundPorts) Stop() { + close(b.stop) +} + +func (b *BoundPorts) update() error { + b.mu.Lock() + defer b.mu.Unlock() + + tcpPorts, err := network.ReadListeningPorts(b.config.ProcRoot, network.TCP, b.config.CollectTCPv6Conns) + if err != nil { + return fmt.Errorf("failed to read initial TCP pid->port mapping: %s", err) + } + + for p := range tcpPorts { + if p.Ino != b.ino { + continue + } + log.Debugf("adding initial TCP port binding: netns: %d port: %d", p.Ino, p.Port) + b.ports[boundPortsKey{network.TCP, p.Port}] = struct{}{} + } + + udpPorts, err := network.ReadListeningPorts(b.config.ProcRoot, network.UDP, b.config.CollectUDPv6Conns) + if err != nil { + return fmt.Errorf("failed to read initial UDP pid->port mapping: %s", err) + } + + for p := range udpPorts { + // ignore ephemeral port binds as they are more likely to be from + // clients calling bind with port 0 + if network.IsPortInEphemeralRange(network.AFINET, network.UDP, p.Port) == network.EphemeralTrue { + log.Debugf("ignoring initial ephemeral UDP port bind to %d", p) + continue + } + + if p.Ino != b.ino { + continue + } + + log.Debugf("adding initial UDP port binding: netns: %d port: %d", p.Ino, p.Port) + b.ports[boundPortsKey{network.UDP, p.Port}] = struct{}{} + } + + return nil + +} + +// Find returns `true` if the given `(proto, port)` exists in +// the BoundPorts collection +func (b *BoundPorts) Find(proto network.ConnectionType, port uint16) bool { + b.mu.RLock() + defer b.mu.RUnlock() + + _, ok := b.ports[boundPortsKey{proto, port}] + return ok +} diff --git a/pkg/network/tracer/connection/ebpfless_tracer.go b/pkg/network/tracer/connection/ebpfless_tracer.go new file mode 100644 index 0000000000000..b2cd928ceddfb --- /dev/null +++ b/pkg/network/tracer/connection/ebpfless_tracer.go @@ -0,0 +1,417 @@ +// 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. + +//go:build linux_bpf + +package connection + +import ( + "fmt" + "io" + "sync" + "time" + + "github.com/cilium/ebpf" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/prometheus/client_golang/prometheus" + "github.com/vishvananda/netns" + "golang.org/x/sys/unix" + + "github.com/DataDog/datadog-agent/pkg/network" + "github.com/DataDog/datadog-agent/pkg/network/config" + "github.com/DataDog/datadog-agent/pkg/network/filter" + "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/ebpfless" + "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/failure" + "github.com/DataDog/datadog-agent/pkg/process/util" + "github.com/DataDog/datadog-agent/pkg/telemetry" + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +const ( + // the segment length to read + // mac header (with vlan) + ip header + tcp header + segmentLen = 18 + 60 + 60 + + ebpfLessTelemetryPrefix = "network_tracer__ebpfless" +) + +var ( + ebpfLessTracerTelemetry = struct { + skippedPackets telemetry.Counter + }{ + telemetry.NewCounter(ebpfLessTelemetryPrefix, "skipped_packets", []string{"reason"}, "Counter measuring skipped packets"), + } +) + +type ebpfLessTracer struct { + m sync.Mutex + + config *config.Config + + packetSrc *filter.AFPacketSource + exit chan struct{} + keyBuf []byte + scratchConn *network.ConnectionStats + + udp *udpProcessor + tcp *tcpProcessor + + // connection maps + conns map[string]*network.ConnectionStats + boundPorts *ebpfless.BoundPorts + cookieHasher *cookieHasher + + ns netns.NsHandle +} + +// newEbpfLessTracer creates a new ebpfLessTracer instance +func newEbpfLessTracer(cfg *config.Config) (*ebpfLessTracer, error) { + packetSrc, err := filter.NewAFPacketSource( + 8<<20, // 8 MB total space + filter.OptSnapLen(segmentLen)) + if err != nil { + return nil, fmt.Errorf("error creating packet source: %w", err) + } + + tr := &ebpfLessTracer{ + config: cfg, + packetSrc: packetSrc, + exit: make(chan struct{}), + keyBuf: make([]byte, network.ConnectionByteKeyMaxLen), + scratchConn: &network.ConnectionStats{}, + udp: &udpProcessor{}, + tcp: newTCPProcessor(), + conns: make(map[string]*network.ConnectionStats, cfg.MaxTrackedConnections), + boundPorts: ebpfless.NewBoundPorts(cfg), + cookieHasher: newCookieHasher(), + } + + tr.ns, err = netns.Get() + if err != nil { + return nil, fmt.Errorf("error getting current net ns: %w", err) + } + + return tr, nil +} + +// Start begins collecting network connection data. +func (t *ebpfLessTracer) Start(func(*network.ConnectionStats)) error { + if err := t.boundPorts.Start(); err != nil { + return fmt.Errorf("could not update bound ports: %w", err) + } + + go func() { + var eth layers.Ethernet + var ip4 layers.IPv4 + var ip6 layers.IPv6 + var tcp layers.TCP + var udp layers.UDP + decoded := make([]gopacket.LayerType, 0, 5) + parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, ð, &ip4, &ip6, &tcp, &udp) + parser.IgnoreUnsupported = true + for { + err := t.packetSrc.VisitPackets(t.exit, func(b []byte, info filter.PacketInfo, _ time.Time) error { + if err := parser.DecodeLayers(b, &decoded); err != nil { + return fmt.Errorf("error decoding packet layers: %w", err) + } + + pktType := info.(*filter.AFPacketInfo).PktType + // only process PACKET_HOST and PACK_OUTGOING packets + if pktType != unix.PACKET_HOST && pktType != unix.PACKET_OUTGOING { + ebpfLessTracerTelemetry.skippedPackets.Inc("unsupported_packet_type") + return nil + } + + if err := t.processConnection(pktType, &ip4, &ip6, &udp, &tcp, decoded); err != nil { + log.Warnf("could not process packet: %s", err) + } + + return nil + }) + + if err != nil { + log.Errorf("exiting packet loop: %s", err) + return + } + } + }() + + return nil +} + +func (t *ebpfLessTracer) processConnection( + pktType uint8, + ip4 *layers.IPv4, + ip6 *layers.IPv6, + udp *layers.UDP, + tcp *layers.TCP, + decoded []gopacket.LayerType, +) error { + t.scratchConn.Source, t.scratchConn.Dest = util.Address{}, util.Address{} + t.scratchConn.SPort, t.scratchConn.DPort = 0, 0 + var udpPresent, tcpPresent bool + for _, layerType := range decoded { + switch layerType { + case layers.LayerTypeIPv4: + t.scratchConn.Source = util.AddressFromNetIP(ip4.SrcIP) + t.scratchConn.Dest = util.AddressFromNetIP(ip4.DstIP) + t.scratchConn.Family = network.AFINET + case layers.LayerTypeIPv6: + t.scratchConn.Source = util.AddressFromNetIP(ip6.SrcIP) + t.scratchConn.Dest = util.AddressFromNetIP(ip6.DstIP) + t.scratchConn.Family = network.AFINET6 + case layers.LayerTypeTCP: + t.scratchConn.SPort = uint16(tcp.SrcPort) + t.scratchConn.DPort = uint16(tcp.DstPort) + t.scratchConn.Type = network.TCP + tcpPresent = true + case layers.LayerTypeUDP: + t.scratchConn.SPort = uint16(udp.SrcPort) + t.scratchConn.DPort = uint16(udp.DstPort) + t.scratchConn.Type = network.UDP + udpPresent = true + } + } + + // check if have all the basic pieces + if !udpPresent && !tcpPresent { + log.Debugf("ignoring packet since its not udp or tcp") + ebpfLessTracerTelemetry.skippedPackets.Inc("not_tcp_udp") + return nil + } + + flipSourceDest(t.scratchConn, pktType) + t.determineConnectionDirection(t.scratchConn, pktType) + + t.m.Lock() + defer t.m.Unlock() + + key := string(t.scratchConn.ByteKey(t.keyBuf)) + conn := t.conns[key] + if conn == nil { + conn = &network.ConnectionStats{} + *conn = *t.scratchConn + t.cookieHasher.Hash(conn) + conn.Duration = time.Duration(time.Now().UnixNano()) + } + + var err error + switch conn.Type { + case network.UDP: + err = t.udp.process(conn, pktType, udp) + case network.TCP: + err = t.tcp.process(conn, pktType, ip4, ip6, tcp) + default: + err = fmt.Errorf("unsupported connection type %d", conn.Type) + } + + if err != nil { + return fmt.Errorf("error processing connection: %w", err) + } + + if conn.Type == network.UDP || conn.Monotonic.TCPEstablished > 0 { + conn.LastUpdateEpoch = uint64(time.Now().UnixNano()) + t.conns[key] = conn + } + + log.TraceFunc(func() string { + return fmt.Sprintf("connection: %s", conn) + }) + return nil +} + +func flipSourceDest(conn *network.ConnectionStats, pktType uint8) { + if pktType == unix.PACKET_HOST { + conn.Dest, conn.Source = conn.Source, conn.Dest + conn.DPort, conn.SPort = conn.SPort, conn.DPort + } +} + +func (t *ebpfLessTracer) determineConnectionDirection(conn *network.ConnectionStats, pktType uint8) { + t.m.Lock() + defer t.m.Unlock() + + ok := t.boundPorts.Find(conn.Type, conn.SPort) + if ok { + // incoming connection + conn.Direction = network.INCOMING + return + } + + if conn.Type == network.TCP { + switch pktType { + case unix.PACKET_HOST: + conn.Direction = network.INCOMING + case unix.PACKET_OUTGOING: + conn.Direction = network.OUTGOING + } + } +} + +// Stop halts all network data collection. +func (t *ebpfLessTracer) Stop() { + if t == nil { + return + } + + close(t.exit) + t.ns.Close() + t.boundPorts.Stop() +} + +// GetConnections returns the list of currently active connections, using the buffer provided. +// The optional filter function is used to prevent unwanted connections from being returned and consuming resources. +func (t *ebpfLessTracer) GetConnections(buffer *network.ConnectionBuffer, filter func(*network.ConnectionStats) bool) error { + t.m.Lock() + defer t.m.Unlock() + + if len(t.conns) == 0 { + return nil + } + + log.Trace(t.conns) + conns := make([]network.ConnectionStats, 0, len(t.conns)) + for _, c := range t.conns { + if filter != nil && !filter(c) { + continue + } + + conns = append(conns, *c) + } + + buffer.Append(conns) + return nil +} + +// FlushPending forces any closed connections waiting for batching to be processed immediately. +func (t *ebpfLessTracer) FlushPending() {} + +// Remove deletes the connection from tracking state. +// It does not prevent the connection from re-appearing later, if additional traffic occurs. +func (t *ebpfLessTracer) Remove(conn *network.ConnectionStats) error { + t.m.Lock() + defer t.m.Unlock() + + delete(t.conns, string(conn.ByteKey(t.keyBuf))) + return nil +} + +// GetMap returns the underlying named map. This is useful if any maps are shared with other eBPF components. +// An individual ebpfLessTracer implementation may choose which maps to expose via this function. +func (t *ebpfLessTracer) GetMap(string) *ebpf.Map { return nil } + +// DumpMaps (for debugging purpose) returns all maps content by default or selected maps from maps parameter. +func (t *ebpfLessTracer) DumpMaps(_ io.Writer, _ ...string) error { + return fmt.Errorf("not implemented") +} + +// Type returns the type of the underlying ebpf ebpfLessTracer that is currently loaded +func (t *ebpfLessTracer) Type() TracerType { + return TracerTypeEbpfless +} + +func (t *ebpfLessTracer) Pause() error { + return fmt.Errorf("not implemented") +} + +func (t *ebpfLessTracer) Resume() error { + return fmt.Errorf("not implemented") +} + +// Describe returns all descriptions of the collector +func (t *ebpfLessTracer) Describe(_ chan<- *prometheus.Desc) {} + +// Collect returns the current state of all metrics of the collector +func (t *ebpfLessTracer) Collect(_ chan<- prometheus.Metric) {} + +// GetFailedConnections returns the underlying map used to store failed connections +func (t *ebpfLessTracer) GetFailedConnections() *failure.FailedConns { return nil } + +var _ Tracer = &ebpfLessTracer{} + +type udpProcessor struct { +} + +func (u *udpProcessor) process(conn *network.ConnectionStats, pktType uint8, udp *layers.UDP) error { + payloadLen, err := ebpfless.UDPPayloadLen(udp) + if err != nil { + return err + } + + switch pktType { + case unix.PACKET_OUTGOING: + conn.Monotonic.SentPackets++ + conn.Monotonic.SentBytes += uint64(payloadLen) + case unix.PACKET_HOST: + conn.Monotonic.RecvPackets++ + conn.Monotonic.RecvBytes += uint64(payloadLen) + } + + return nil +} + +type tcpProcessor struct { + buf []byte + conns map[string]struct { + established bool + closed bool + } +} + +func newTCPProcessor() *tcpProcessor { + return &tcpProcessor{ + buf: make([]byte, network.ConnectionByteKeyMaxLen), + conns: map[string]struct { + established bool + closed bool + }{}, + } +} + +func (t *tcpProcessor) process(conn *network.ConnectionStats, pktType uint8, ip4 *layers.IPv4, ip6 *layers.IPv6, tcp *layers.TCP) error { + payloadLen, err := ebpfless.TCPPayloadLen(conn.Family, ip4, ip6, tcp) + if err != nil { + return err + } + + log.TraceFunc(func() string { + return fmt.Sprintf("tcp processor: pktType=%+v seq=%+v ack=%+v fin=%+v rst=%+v syn=%+v ack=%+v", pktType, tcp.Seq, tcp.Ack, tcp.FIN, tcp.RST, tcp.SYN, tcp.ACK) + }) + key := string(conn.ByteKey(t.buf)) + c := t.conns[key] + log.TraceFunc(func() string { + return fmt.Sprintf("pre ack_seq=%+v", c) + }) + switch pktType { + case unix.PACKET_OUTGOING: + conn.Monotonic.SentPackets++ + conn.Monotonic.SentBytes += uint64(payloadLen) + case unix.PACKET_HOST: + conn.Monotonic.RecvPackets++ + conn.Monotonic.RecvBytes += uint64(payloadLen) + } + + if tcp.FIN || tcp.RST { + if !c.closed { + c.closed = true + conn.Monotonic.TCPClosed++ + conn.Duration = time.Duration(time.Now().UnixNano() - int64(conn.Duration)) + } + delete(t.conns, key) + return nil + } + + if !tcp.SYN && !c.established { + c.established = true + conn.Monotonic.TCPEstablished++ + } + + log.TraceFunc(func() string { + return fmt.Sprintf("ack_seq=%+v", c) + }) + t.conns[key] = c + return nil +} diff --git a/pkg/network/tracer/connection/tracer.go b/pkg/network/tracer/connection/tracer.go index 8c580e43339ad..3ab6dff49ca49 100644 --- a/pkg/network/tracer/connection/tracer.go +++ b/pkg/network/tracer/connection/tracer.go @@ -8,39 +8,15 @@ package connection import ( - "encoding/binary" - "errors" - "fmt" - "hash" "io" - "math" - "sync" - "time" - "github.com/cihub/seelog" "github.com/cilium/ebpf" "github.com/prometheus/client_golang/prometheus" - "github.com/twmb/murmur3" - "go.uber.org/atomic" - "golang.org/x/sys/unix" - manager "github.com/DataDog/ebpf-manager" - - telemetryComponent "github.com/DataDog/datadog-agent/comp/core/telemetry" - ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" - "github.com/DataDog/datadog-agent/pkg/ebpf/maps" - ebpftelemetry "github.com/DataDog/datadog-agent/pkg/ebpf/telemetry" + "github.com/DataDog/datadog-agent/comp/core/telemetry" "github.com/DataDog/datadog-agent/pkg/network" "github.com/DataDog/datadog-agent/pkg/network/config" - netebpf "github.com/DataDog/datadog-agent/pkg/network/ebpf" - "github.com/DataDog/datadog-agent/pkg/network/ebpf/probes" - "github.com/DataDog/datadog-agent/pkg/network/protocols" "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/failure" - "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/fentry" - "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/kprobe" - "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/util" - "github.com/DataDog/datadog-agent/pkg/telemetry" - "github.com/DataDog/datadog-agent/pkg/util/log" ) // TracerType is the type of the underlying tracer @@ -55,6 +31,8 @@ const ( TracerTypeKProbeCORE //nolint:revive // TODO(NET) Fix revive linter TracerTypeFentry + //nolint:revive // TODO(NET) Fix revive linter + TracerTypeEbpfless ) const ( @@ -96,716 +74,11 @@ type Tracer interface { Collect(metrics chan<- prometheus.Metric) } -const ( - defaultClosedChannelSize = 500 - defaultFailedChannelSize = 500 - connTracerModuleName = "network_tracer__ebpf" -) - -//nolint:revive // TODO(NET) Fix revive linter -var ConnTracerTelemetry = struct { - connections telemetry.Gauge - tcpFailedConnects *prometheus.Desc - //nolint:revive // TODO(NET) Fix revive linter - TcpSentMiscounts *prometheus.Desc - //nolint:revive // TODO(NET) Fix revive linter - unbatchedTcpClose *prometheus.Desc - //nolint:revive // TODO(NET) Fix revive linter - unbatchedUdpClose *prometheus.Desc - //nolint:revive // TODO(NET) Fix revive linter - UdpSendsProcessed *prometheus.Desc - //nolint:revive // TODO(NET) Fix revive linter - UdpSendsMissed *prometheus.Desc - //nolint:revive // TODO(NET) Fix revive linter - UdpDroppedConns *prometheus.Desc - // doubleFlushAttemptsClose is a counter measuring the number of attempts to flush a closed connection twice from tcp_close - doubleFlushAttemptsClose *prometheus.Desc - // doubleFlushAttemptsDone is a counter measuring the number of attempts to flush a closed connection twice from tcp_done - doubleFlushAttemptsDone *prometheus.Desc - // unsupportedTcpFailures is a counter measuring the number of attempts to flush a TCP failure that is not supported - unsupportedTcpFailures *prometheus.Desc - // tcpDonePidMismatch is a counter measuring the number of TCP connections with a PID mismatch between tcp_connect and tcp_done - tcpDonePidMismatch *prometheus.Desc - PidCollisions *telemetry.StatCounterWrapper - iterationDups telemetry.Counter - iterationAborts telemetry.Counter - - //nolint:revive // TODO(NET) Fix revive linter - lastTcpFailedConnects *atomic.Int64 - //nolint:revive // TODO(NET) Fix revive linter - LastTcpSentMiscounts *atomic.Int64 - //nolint:revive // TODO(NET) Fix revive linter - lastUnbatchedTcpClose *atomic.Int64 - //nolint:revive // TODO(NET) Fix revive linter - lastUnbatchedUdpClose *atomic.Int64 - //nolint:revive // TODO(NET) Fix revive linter - lastUdpSendsProcessed *atomic.Int64 - //nolint:revive // TODO(NET) Fix revive linter - lastUdpSendsMissed *atomic.Int64 - //nolint:revive // TODO(NET) Fix revive linter - lastUdpDroppedConns *atomic.Int64 - // lastDoubleFlushAttemptsClose is a counter measuring the diff between the last two values of doubleFlushAttemptsClose - lastDoubleFlushAttemptsClose *atomic.Int64 - // lastDoubleFlushAttemptsDone is a counter measuring the diff between the last two values of doubleFlushAttemptsDone - lastDoubleFlushAttemptsDone *atomic.Int64 - // lastUnsupportedTcpFailures is a counter measuring the diff between the last two values of unsupportedTcpFailures - lastUnsupportedTcpFailures *atomic.Int64 - // lastTcpDonePidMismatch is a counter measuring the diff between the last two values of tcpDonePidMismatch - lastTcpDonePidMismatch *atomic.Int64 -}{ - telemetry.NewGauge(connTracerModuleName, "connections", []string{"ip_proto", "family"}, "Gauge measuring the number of active connections in the EBPF map"), - prometheus.NewDesc(connTracerModuleName+"__tcp_failed_connects", "Counter measuring the number of failed TCP connections in the EBPF map", nil, nil), - prometheus.NewDesc(connTracerModuleName+"__tcp_sent_miscounts", "Counter measuring the number of miscounted tcp sends in the EBPF map", nil, nil), - prometheus.NewDesc(connTracerModuleName+"__unbatched_tcp_close", "Counter measuring the number of missed TCP close events in the EBPF map", nil, nil), - prometheus.NewDesc(connTracerModuleName+"__unbatched_udp_close", "Counter measuring the number of missed UDP close events in the EBPF map", nil, nil), - prometheus.NewDesc(connTracerModuleName+"__udp_sends_processed", "Counter measuring the number of processed UDP sends in EBPF", nil, nil), - prometheus.NewDesc(connTracerModuleName+"__udp_sends_missed", "Counter measuring failures to process UDP sends in EBPF", nil, nil), - prometheus.NewDesc(connTracerModuleName+"__udp_dropped_conns", "Counter measuring the number of dropped UDP connections in the EBPF map", nil, nil), - prometheus.NewDesc(connTracerModuleName+"__double_flush_attempts_close", "Counter measuring the number of attempts to flush a closed connection twice from tcp_close", nil, nil), - prometheus.NewDesc(connTracerModuleName+"__double_flush_attempts_done", "Counter measuring the number of attempts to flush a closed connection twice from tcp_done", nil, nil), - prometheus.NewDesc(connTracerModuleName+"__unsupported_tcp_failures", "Counter measuring the number of attempts to flush a TCP failure that is not supported", nil, nil), - prometheus.NewDesc(connTracerModuleName+"__tcp_done_pid_mismatch", "Counter measuring the number of TCP connections with a PID mismatch between tcp_connect and tcp_done", nil, nil), - telemetry.NewStatCounterWrapper(connTracerModuleName, "pid_collisions", []string{}, "Counter measuring number of process collisions"), - telemetry.NewCounter(connTracerModuleName, "iteration_dups", []string{}, "Counter measuring the number of connections iterated more than once"), - telemetry.NewCounter(connTracerModuleName, "iteration_aborts", []string{}, "Counter measuring how many times ebpf iteration of connection map was aborted"), - atomic.NewInt64(0), - atomic.NewInt64(0), - atomic.NewInt64(0), - atomic.NewInt64(0), - atomic.NewInt64(0), - atomic.NewInt64(0), - atomic.NewInt64(0), - atomic.NewInt64(0), - atomic.NewInt64(0), - atomic.NewInt64(0), - atomic.NewInt64(0), -} - -type tracer struct { - m *manager.Manager - - conns *maps.GenericMap[netebpf.ConnTuple, netebpf.ConnStats] - tcpStats *maps.GenericMap[netebpf.ConnTuple, netebpf.TCPStats] - tcpRetransmits *maps.GenericMap[netebpf.ConnTuple, uint32] - config *config.Config - - // tcp_close events - closeConsumer *tcpCloseConsumer - // tcp failure events - failedConnConsumer *failure.TCPFailedConnConsumer - - removeTuple *netebpf.ConnTuple - - closeTracer func() - stopOnce sync.Once - - ebpfTracerType TracerType - - exitTelemetry chan struct{} - - ch *cookieHasher -} - -// NewTracer creates a new tracer -func NewTracer(config *config.Config, _ telemetryComponent.Component) (Tracer, error) { - mgrOptions := manager.Options{ - // Extend RLIMIT_MEMLOCK (8) size - // On some systems, the default for RLIMIT_MEMLOCK may be as low as 64 bytes. - // This will result in an EPERM (Operation not permitted) error, when trying to create an eBPF map - // using bpf(2) with BPF_MAP_CREATE. - // - // We are setting the limit to infinity until we have a better handle on the true requirements. - RLimit: &unix.Rlimit{ - Cur: math.MaxUint64, - Max: math.MaxUint64, - }, - MapSpecEditors: map[string]manager.MapSpecEditor{ - probes.ConnMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, - probes.TCPStatsMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, - probes.TCPRetransmitsMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, - probes.PortBindingsMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, - probes.UDPPortBindingsMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, - probes.ConnectionProtocolMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, - probes.ConnectionTupleToSocketSKBConnMap: {MaxEntries: config.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries}, - }, - ConstantEditors: []manager.ConstantEditor{ - boolConst("tcpv6_enabled", config.CollectTCPv6Conns), - boolConst("udpv6_enabled", config.CollectUDPv6Conns), - }, - DefaultKProbeMaxActive: maxActive, - BypassEnabled: config.BypassEnabled, +// NewTracer returns a new Tracer +func NewTracer(cfg *config.Config, telemetryComp telemetry.Component) (Tracer, error) { + if cfg.EnableEbpfless { + return newEbpfLessTracer(cfg) } - begin, end := network.EphemeralRange() - mgrOptions.ConstantEditors = append(mgrOptions.ConstantEditors, - manager.ConstantEditor{Name: "ephemeral_range_begin", Value: uint64(begin)}, - manager.ConstantEditor{Name: "ephemeral_range_end", Value: uint64(end)}) - - closedChannelSize := defaultClosedChannelSize - if config.ClosedChannelSize > 0 { - closedChannelSize = config.ClosedChannelSize - } - var connCloseEventHandler ddebpf.EventHandler - var failedConnsHandler ddebpf.EventHandler - if config.RingBufferSupportedNPM() { - connCloseEventHandler = ddebpf.NewRingBufferHandler(closedChannelSize) - failedConnsHandler = ddebpf.NewRingBufferHandler(defaultFailedChannelSize) - } else { - connCloseEventHandler = ddebpf.NewPerfHandler(closedChannelSize) - failedConnsHandler = ddebpf.NewPerfHandler(defaultFailedChannelSize) - } - - var m *manager.Manager - //nolint:revive // TODO(NET) Fix revive linter - var tracerType TracerType = TracerTypeFentry - var closeTracerFn func() - m, closeTracerFn, err := fentry.LoadTracer(config, mgrOptions, connCloseEventHandler) - if err != nil && !errors.Is(err, fentry.ErrorNotSupported) { - // failed to load fentry tracer - return nil, err - } - - if err != nil { - // load the kprobe tracer - log.Info("fentry tracer not supported, falling back to kprobe tracer") - var kprobeTracerType kprobe.TracerType - m, closeTracerFn, kprobeTracerType, err = kprobe.LoadTracer(config, mgrOptions, connCloseEventHandler, failedConnsHandler) - if err != nil { - return nil, err - } - tracerType = TracerType(kprobeTracerType) - } - m.DumpHandler = dumpMapsHandler - ddebpf.AddNameMappings(m, "npm_tracer") - - numCPUs, err := ebpf.PossibleCPU() - if err != nil { - return nil, fmt.Errorf("could not determine number of CPUs: %w", err) - } - extractor := newBatchExtractor(numCPUs) - batchMgr, err := newConnBatchManager(m, extractor) - if err != nil { - return nil, fmt.Errorf("could not create connection batch manager: %w", err) - } - - closeConsumer := newTCPCloseConsumer(connCloseEventHandler, batchMgr) - - var failedConnConsumer *failure.TCPFailedConnConsumer - // Failed connections are not supported on prebuilt - if tracerType == TracerTypeKProbePrebuilt { - config.TCPFailedConnectionsEnabled = false - } - if config.FailedConnectionsSupported() { - failedConnConsumer = failure.NewFailedConnConsumer(failedConnsHandler, m, config.MaxFailedConnectionsBuffered) - } - - tr := &tracer{ - m: m, - config: config, - closeConsumer: closeConsumer, - failedConnConsumer: failedConnConsumer, - removeTuple: &netebpf.ConnTuple{}, - closeTracer: closeTracerFn, - ebpfTracerType: tracerType, - exitTelemetry: make(chan struct{}), - ch: newCookieHasher(), - } - - tr.conns, err = maps.GetMap[netebpf.ConnTuple, netebpf.ConnStats](m, probes.ConnMap) - if err != nil { - tr.Stop() - return nil, fmt.Errorf("error retrieving the bpf %s map: %s", probes.ConnMap, err) - } - - tr.tcpStats, err = maps.GetMap[netebpf.ConnTuple, netebpf.TCPStats](m, probes.TCPStatsMap) - if err != nil { - tr.Stop() - return nil, fmt.Errorf("error retrieving the bpf %s map: %s", probes.TCPStatsMap, err) - } - - if tr.tcpRetransmits, err = maps.GetMap[netebpf.ConnTuple, uint32](m, probes.TCPRetransmitsMap); err != nil { - tr.Stop() - return nil, fmt.Errorf("error retrieving the bpf %s map: %s", probes.TCPRetransmitsMap, err) - } - - return tr, nil -} - -func boolConst(name string, value bool) manager.ConstantEditor { - c := manager.ConstantEditor{ - Name: name, - Value: uint64(1), - } - if !value { - c.Value = uint64(0) - } - - return c -} - -func (t *tracer) Start(callback func(*network.ConnectionStats)) (err error) { - defer func() { - if err != nil { - t.Stop() - } - }() - - err = initializePortBindingMaps(t.config, t.m) - if err != nil { - return fmt.Errorf("error initializing port binding maps: %s", err) - } - - if err := t.m.Start(); err != nil { - return fmt.Errorf("could not start ebpf manager: %s", err) - } - - t.closeConsumer.Start(callback) - t.failedConnConsumer.Start() - return nil -} - -func (t *tracer) Pause() error { - // add small delay for socket filters to properly detach - time.Sleep(1 * time.Millisecond) - return t.m.Pause() -} - -func (t *tracer) Resume() error { - err := t.m.Resume() - // add small delay for socket filters to properly attach - time.Sleep(1 * time.Millisecond) - return err -} - -func (t *tracer) FlushPending() { - t.closeConsumer.FlushPending() -} - -func (t *tracer) GetFailedConnections() *failure.FailedConns { - if t.failedConnConsumer == nil { - return nil - } - return t.failedConnConsumer.FailedConns -} - -func (t *tracer) Stop() { - t.stopOnce.Do(func() { - close(t.exitTelemetry) - ddebpf.RemoveNameMappings(t.m) - ebpftelemetry.UnregisterTelemetry(t.m) - _ = t.m.Stop(manager.CleanAll) - t.closeConsumer.Stop() - t.failedConnConsumer.Stop() - if t.closeTracer != nil { - t.closeTracer() - } - }) -} - -func (t *tracer) GetMap(name string) *ebpf.Map { - switch name { - case probes.ConnectionProtocolMap: - default: - return nil - } - m, _, _ := t.m.GetMap(name) - return m -} - -func (t *tracer) GetConnections(buffer *network.ConnectionBuffer, filter func(*network.ConnectionStats) bool) error { - // Iterate through all key-value pairs in map - key, stats := &netebpf.ConnTuple{}, &netebpf.ConnStats{} - seen := make(map[netebpf.ConnTuple]struct{}) - // connsByTuple is used to detect whether we are iterating over - // a connection we have previously seen. This can happen when - // ebpf maps are being iterated over and deleted at the same time. - // The iteration can reset when that happens. - // See https://justin.azoff.dev/blog/bpf_map_get_next_key-pitfalls/ - connsByTuple := make(map[netebpf.ConnTuple]uint32) - - // Cached objects - conn := new(network.ConnectionStats) - tcp := new(netebpf.TCPStats) - - var tcp4, tcp6, udp4, udp6 float64 - entries := t.conns.Iterate() - for entries.Next(key, stats) { - if cookie, exists := connsByTuple[*key]; exists && cookie == stats.Cookie { - // already seen the connection in current batch processing, - // due to race between the iterator and bpf_map_delete - ConnTracerTelemetry.iterationDups.Inc() - continue - } - - populateConnStats(conn, key, stats, t.ch) - connsByTuple[*key] = stats.Cookie - - isTCP := conn.Type == network.TCP - switch conn.Family { - case network.AFINET6: - if isTCP { - tcp6++ - } else { - udp6++ - } - case network.AFINET: - if isTCP { - tcp4++ - } else { - udp4++ - } - } - - if filter != nil && !filter(conn) { - continue - } - - if t.getTCPStats(tcp, key) { - updateTCPStats(conn, tcp, 0) - } - if retrans, ok := t.getTCPRetransmits(key, seen); ok { - updateTCPStats(conn, nil, retrans) - } - - *buffer.Next() = *conn - } - - if err := entries.Err(); err != nil { - if !errors.Is(err, ebpf.ErrIterationAborted) { - return fmt.Errorf("unable to iterate connection map: %w", err) - } - - log.Warn("eBPF conn_stats map iteration aborted. Some connections may not be reported") - ConnTracerTelemetry.iterationAborts.Inc() - } - - updateTelemetry(tcp4, tcp6, udp4, udp6) - - return nil -} - -func updateTelemetry(tcp4 float64, tcp6 float64, udp4 float64, udp6 float64) { - ConnTracerTelemetry.connections.Set(tcp4, "tcp", "v4") - ConnTracerTelemetry.connections.Set(tcp6, "tcp", "v6") - ConnTracerTelemetry.connections.Set(udp4, "udp", "v4") - ConnTracerTelemetry.connections.Set(udp6, "udp", "v6") -} - -func removeConnectionFromTelemetry(conn *network.ConnectionStats) { - isTCP := conn.Type == network.TCP - switch conn.Family { - case network.AFINET6: - if isTCP { - ConnTracerTelemetry.connections.Dec("tcp", "v6") - } else { - ConnTracerTelemetry.connections.Dec("udp", "v6") - } - case network.AFINET: - if isTCP { - ConnTracerTelemetry.connections.Dec("tcp", "v4") - } else { - ConnTracerTelemetry.connections.Dec("udp", "v4") - } - } -} - -func (t *tracer) Remove(conn *network.ConnectionStats) error { - util.ConnStatsToTuple(conn, t.removeTuple) - - err := t.conns.Delete(t.removeTuple) - if err != nil { - // If this entry no longer exists in the eBPF map it means `tcp_close` has executed - // during this function call. In that case state.StoreClosedConnection() was already called for this connection, - // and we can't delete the corresponding client state, or we'll likely over-report the metric values. - // By skipping to the next iteration and not calling state.RemoveConnections() we'll let - // this connection expire "naturally" when either next connection check runs or the client itself expires. - return err - } - - removeConnectionFromTelemetry(conn) - - if conn.Type == network.TCP { - // We can ignore the error for this map since it will not always contain the entry - _ = t.tcpStats.Delete(t.removeTuple) - // We remove the PID from the tuple as it is not used in the retransmits map - pid := t.removeTuple.Pid - t.removeTuple.Pid = 0 - _ = t.tcpRetransmits.Delete(t.removeTuple) - t.removeTuple.Pid = pid - } - return nil -} - -func (t *tracer) getEBPFTelemetry() *netebpf.Telemetry { - var zero uint32 - mp, err := maps.GetMap[uint32, netebpf.Telemetry](t.m, probes.TelemetryMap) - if err != nil { - log.Warnf("error retrieving telemetry map: %s", err) - return nil - } - - tm := &netebpf.Telemetry{} - if err := mp.Lookup(&zero, tm); err != nil { - // This can happen if we haven't initialized the telemetry object yet - // so let's just use a trace log - if log.ShouldLog(seelog.TraceLvl) { - log.Tracef("error retrieving the telemetry struct: %s", err) - } - return nil - } - return tm -} - -// Describe returns all descriptions of the collector -func (t *tracer) Describe(ch chan<- *prometheus.Desc) { - ch <- ConnTracerTelemetry.tcpFailedConnects - ch <- ConnTracerTelemetry.TcpSentMiscounts - ch <- ConnTracerTelemetry.unbatchedTcpClose - ch <- ConnTracerTelemetry.unbatchedUdpClose - ch <- ConnTracerTelemetry.UdpSendsProcessed - ch <- ConnTracerTelemetry.UdpSendsMissed - ch <- ConnTracerTelemetry.UdpDroppedConns - ch <- ConnTracerTelemetry.doubleFlushAttemptsClose - ch <- ConnTracerTelemetry.doubleFlushAttemptsDone - ch <- ConnTracerTelemetry.unsupportedTcpFailures - ch <- ConnTracerTelemetry.tcpDonePidMismatch -} - -// Collect returns the current state of all metrics of the collector -func (t *tracer) Collect(ch chan<- prometheus.Metric) { - ebpfTelemetry := t.getEBPFTelemetry() - if ebpfTelemetry == nil { - return - } - delta := int64(ebpfTelemetry.Tcp_failed_connect) - ConnTracerTelemetry.lastTcpFailedConnects.Load() - ConnTracerTelemetry.lastTcpFailedConnects.Store(int64(ebpfTelemetry.Tcp_failed_connect)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.tcpFailedConnects, prometheus.CounterValue, float64(delta)) - - delta = int64(ebpfTelemetry.Tcp_sent_miscounts) - ConnTracerTelemetry.LastTcpSentMiscounts.Load() - ConnTracerTelemetry.LastTcpSentMiscounts.Store(int64(ebpfTelemetry.Tcp_sent_miscounts)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.TcpSentMiscounts, prometheus.CounterValue, float64(delta)) - - delta = int64(ebpfTelemetry.Unbatched_tcp_close) - ConnTracerTelemetry.lastUnbatchedTcpClose.Load() - ConnTracerTelemetry.lastUnbatchedTcpClose.Store(int64(ebpfTelemetry.Unbatched_tcp_close)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.unbatchedTcpClose, prometheus.CounterValue, float64(delta)) - - delta = int64(ebpfTelemetry.Unbatched_udp_close) - ConnTracerTelemetry.lastUnbatchedUdpClose.Load() - ConnTracerTelemetry.lastUnbatchedUdpClose.Store(int64(ebpfTelemetry.Unbatched_udp_close)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.unbatchedUdpClose, prometheus.CounterValue, float64(delta)) - - delta = int64(ebpfTelemetry.Udp_sends_processed) - ConnTracerTelemetry.lastUdpSendsProcessed.Load() - ConnTracerTelemetry.lastUdpSendsProcessed.Store(int64(ebpfTelemetry.Udp_sends_processed)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.UdpSendsProcessed, prometheus.CounterValue, float64(delta)) - - delta = int64(ebpfTelemetry.Udp_sends_missed) - ConnTracerTelemetry.lastUdpSendsMissed.Load() - ConnTracerTelemetry.lastUdpSendsMissed.Store(int64(ebpfTelemetry.Udp_sends_missed)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.UdpSendsMissed, prometheus.CounterValue, float64(delta)) - - delta = int64(ebpfTelemetry.Udp_dropped_conns) - ConnTracerTelemetry.lastUdpDroppedConns.Load() - ConnTracerTelemetry.lastUdpDroppedConns.Store(int64(ebpfTelemetry.Udp_dropped_conns)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.UdpDroppedConns, prometheus.CounterValue, float64(delta)) - - delta = int64(ebpfTelemetry.Double_flush_attempts_close) - ConnTracerTelemetry.lastDoubleFlushAttemptsClose.Load() - ConnTracerTelemetry.lastDoubleFlushAttemptsClose.Store(int64(ebpfTelemetry.Double_flush_attempts_close)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.doubleFlushAttemptsClose, prometheus.CounterValue, float64(delta)) - - delta = int64(ebpfTelemetry.Double_flush_attempts_done) - ConnTracerTelemetry.lastDoubleFlushAttemptsDone.Load() - ConnTracerTelemetry.lastDoubleFlushAttemptsDone.Store(int64(ebpfTelemetry.Double_flush_attempts_done)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.doubleFlushAttemptsDone, prometheus.CounterValue, float64(delta)) - - delta = int64(ebpfTelemetry.Unsupported_tcp_failures) - ConnTracerTelemetry.lastUnsupportedTcpFailures.Load() - ConnTracerTelemetry.lastUnsupportedTcpFailures.Store(int64(ebpfTelemetry.Unsupported_tcp_failures)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.unsupportedTcpFailures, prometheus.CounterValue, float64(delta)) - - delta = int64(ebpfTelemetry.Tcp_done_pid_mismatch) - ConnTracerTelemetry.lastTcpDonePidMismatch.Load() - ConnTracerTelemetry.lastTcpDonePidMismatch.Store(int64(ebpfTelemetry.Tcp_done_pid_mismatch)) - ch <- prometheus.MustNewConstMetric(ConnTracerTelemetry.tcpDonePidMismatch, prometheus.CounterValue, float64(delta)) - -} - -// DumpMaps (for debugging purpose) returns all maps content by default or selected maps from maps parameter. -func (t *tracer) DumpMaps(w io.Writer, maps ...string) error { - return t.m.DumpMaps(w, maps...) -} - -// Type returns the type of the underlying ebpf tracer that is currently loaded -func (t *tracer) Type() TracerType { - return t.ebpfTracerType -} - -func initializePortBindingMaps(config *config.Config, m *manager.Manager) error { - tcpPorts, err := network.ReadInitialState(config.ProcRoot, network.TCP, config.CollectTCPv6Conns) - if err != nil { - return fmt.Errorf("failed to read initial TCP pid->port mapping: %s", err) - } - - tcpPortMap, err := maps.GetMap[netebpf.PortBinding, uint32](m, probes.PortBindingsMap) - if err != nil { - return fmt.Errorf("failed to get TCP port binding map: %w", err) - } - for p, count := range tcpPorts { - log.Debugf("adding initial TCP port binding: netns: %d port: %d", p.Ino, p.Port) - pb := netebpf.PortBinding{Netns: p.Ino, Port: p.Port} - err = tcpPortMap.Update(&pb, &count, ebpf.UpdateNoExist) - if err != nil && !errors.Is(err, ebpf.ErrKeyExist) { - return fmt.Errorf("failed to update TCP port binding map: %w", err) - } - } - - udpPorts, err := network.ReadInitialState(config.ProcRoot, network.UDP, config.CollectUDPv6Conns) - if err != nil { - return fmt.Errorf("failed to read initial UDP pid->port mapping: %s", err) - } - - udpPortMap, err := maps.GetMap[netebpf.PortBinding, uint32](m, probes.UDPPortBindingsMap) - if err != nil { - return fmt.Errorf("failed to get UDP port binding map: %w", err) - } - for p, count := range udpPorts { - // ignore ephemeral port binds as they are more likely to be from - // clients calling bind with port 0 - if network.IsPortInEphemeralRange(network.AFINET, network.UDP, p.Port) == network.EphemeralTrue { - log.Debugf("ignoring initial ephemeral UDP port bind to %d", p) - continue - } - - log.Debugf("adding initial UDP port binding: netns: %d port: %d", p.Ino, p.Port) - pb := netebpf.PortBinding{Netns: p.Ino, Port: p.Port} - err = udpPortMap.Update(&pb, &count, ebpf.UpdateNoExist) - if err != nil && !errors.Is(err, ebpf.ErrKeyExist) { - return fmt.Errorf("failed to update UDP port binding map: %w", err) - } - } - return nil -} - -func (t *tracer) getTCPRetransmits(tuple *netebpf.ConnTuple, seen map[netebpf.ConnTuple]struct{}) (uint32, bool) { - if tuple.Type() != netebpf.TCP { - return 0, false - } - - // The PID isn't used as a key in the stats map, we will temporarily set it to 0 here and reset it when we're done - pid := tuple.Pid - tuple.Pid = 0 - - var retransmits uint32 - if err := t.tcpRetransmits.Lookup(tuple, &retransmits); err == nil { - // This is required to avoid (over)reporting retransmits for connections sharing the same socket. - if _, reported := seen[*tuple]; reported { - ConnTracerTelemetry.PidCollisions.Inc() - retransmits = 0 - } else { - seen[*tuple] = struct{}{} - } - } - - tuple.Pid = pid - return retransmits, true -} - -// getTCPStats reads tcp related stats for the given ConnTuple -func (t *tracer) getTCPStats(stats *netebpf.TCPStats, tuple *netebpf.ConnTuple) bool { - if tuple.Type() != netebpf.TCP { - return false - } - - return t.tcpStats.Lookup(tuple, stats) == nil -} - -func populateConnStats(stats *network.ConnectionStats, t *netebpf.ConnTuple, s *netebpf.ConnStats, ch *cookieHasher) { - *stats = network.ConnectionStats{ - Pid: t.Pid, - NetNS: t.Netns, - Source: t.SourceAddress(), - Dest: t.DestAddress(), - SPort: t.Sport, - DPort: t.Dport, - Monotonic: network.StatCounters{ - SentBytes: s.Sent_bytes, - RecvBytes: s.Recv_bytes, - SentPackets: uint64(s.Sent_packets), - RecvPackets: uint64(s.Recv_packets), - }, - LastUpdateEpoch: s.Timestamp, - IsAssured: s.IsAssured(), - Cookie: network.StatCookie(s.Cookie), - } - - if s.Duration <= uint64(math.MaxInt64) { - stats.Duration = time.Duration(s.Duration) * time.Nanosecond - } - - stats.ProtocolStack = protocols.Stack{ - API: protocols.API(s.Protocol_stack.Api), - Application: protocols.Application(s.Protocol_stack.Application), - Encryption: protocols.Encryption(s.Protocol_stack.Encryption), - } - - if t.Type() == netebpf.TCP { - stats.Type = network.TCP - } else { - stats.Type = network.UDP - } - - switch t.Family() { - case netebpf.IPv4: - stats.Family = network.AFINET - case netebpf.IPv6: - stats.Family = network.AFINET6 - } - - stats.SPortIsEphemeral = network.IsPortInEphemeralRange(stats.Family, stats.Type, t.Sport) - - switch s.ConnectionDirection() { - case netebpf.Incoming: - stats.Direction = network.INCOMING - case netebpf.Outgoing: - stats.Direction = network.OUTGOING - default: - stats.Direction = network.OUTGOING - } - - if ch != nil { - ch.Hash(stats) - } -} - -func updateTCPStats(conn *network.ConnectionStats, tcpStats *netebpf.TCPStats, retransmits uint32) { - if conn.Type != network.TCP { - return - } - - conn.Monotonic.Retransmits = retransmits - if tcpStats != nil { - conn.Monotonic.TCPEstablished = uint32(tcpStats.State_transitions >> netebpf.Established & 1) - conn.Monotonic.TCPClosed = uint32(tcpStats.State_transitions >> netebpf.Close & 1) - conn.RTT = tcpStats.Rtt - conn.RTTVar = tcpStats.Rtt_var - } -} - -type cookieHasher struct { - hash hash.Hash64 - buf []byte -} - -func newCookieHasher() *cookieHasher { - return &cookieHasher{ - hash: murmur3.New64(), - buf: make([]byte, network.ConnectionByteKeyMaxLen), - } -} - -func (h *cookieHasher) Hash(stats *network.ConnectionStats) { - h.hash.Reset() - if err := binary.Write(h.hash, binary.BigEndian, stats.Cookie); err != nil { - log.Errorf("error writing cookie to hash: %s", err) - return - } - key := stats.ByteKey(h.buf) - if _, err := h.hash.Write(key); err != nil { - log.Errorf("error writing byte key to hash: %s", err) - return - } - stats.Cookie = h.hash.Sum64() + return newEbpfTracer(cfg, telemetryComp) } diff --git a/pkg/network/tracer/ebpf_conntracker.go b/pkg/network/tracer/ebpf_conntracker.go index 3ddc765fff20a..5e712d600bdf8 100644 --- a/pkg/network/tracer/ebpf_conntracker.go +++ b/pkg/network/tracer/ebpf_conntracker.go @@ -14,14 +14,13 @@ import ( "io" "time" + manager "github.com/DataDog/ebpf-manager" "github.com/cihub/seelog" "github.com/cilium/ebpf" "github.com/cilium/ebpf/features" "github.com/prometheus/client_golang/prometheus" "golang.org/x/sys/unix" - manager "github.com/DataDog/ebpf-manager" - telemetryComp "github.com/DataDog/datadog-agent/comp/core/telemetry" ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" "github.com/DataDog/datadog-agent/pkg/ebpf/bytecode" @@ -238,13 +237,14 @@ func (e *ebpfConntracker) GetTranslationForConn(stats *network.ConnectionStats) log.Tracef("looking up in conntrack (stats): %s", stats) } - // Try the lookup in the root namespace first + // Try the lookup in the root namespace first, since usually + // NAT rules referencing conntrack are installed there instead + // of other network namespaces (for pods, for instance) src.Netns = e.rootNS if log.ShouldLog(seelog.TraceLvl) { log.Tracef("looking up in conntrack (tuple): %s", src) } dst := e.get(src) - if dst == nil && stats.NetNS != e.rootNS { // Perform another lookup, this time using the connection namespace src.Netns = stats.NetNS @@ -287,18 +287,35 @@ func (e *ebpfConntracker) get(src *netebpf.ConntrackTuple) *netebpf.ConntrackTup func (e *ebpfConntracker) delete(key *netebpf.ConntrackTuple) { start := time.Now() + defer func() { + conntrackerTelemetry.unregistersDuration.Observe(float64(time.Since(start).Nanoseconds())) + }() + if err := e.ctMap.Delete(key); err != nil { if errors.Is(err, ebpf.ErrKeyNotExist) { if log.ShouldLog(seelog.TraceLvl) { log.Tracef("connection does not exist in ebpf conntrack map: %s", key) } + return } + log.Warnf("unable to delete conntrack entry from eBPF map: %s", err) - } else { - conntrackerTelemetry.unregistersTotal.Inc() - conntrackerTelemetry.unregistersDuration.Observe(float64(time.Since(start).Nanoseconds())) + return } + + conntrackerTelemetry.unregistersTotal.Inc() +} + +func (e *ebpfConntracker) deleteTranslationNs(key *netebpf.ConntrackTuple, ns uint32) *netebpf.ConntrackTuple { + key.Netns = ns + dst := e.get(key) + e.delete(key) + if dst != nil { + e.delete(dst) + } + + return dst } func (e *ebpfConntracker) DeleteTranslation(stats *network.ConnectionStats) { @@ -307,10 +324,12 @@ func (e *ebpfConntracker) DeleteTranslation(stats *network.ConnectionStats) { toConntrackTupleFromStats(key, stats) - dst := e.get(key) - e.delete(key) - if dst != nil { - e.delete(dst) + // attempt a delete from both root and connection's network namespace + if dst := e.deleteTranslationNs(key, e.rootNS); dst != nil { + tuplePool.Put(dst) + } + + if dst := e.deleteTranslationNs(key, stats.NetNS); dst != nil { tuplePool.Put(dst) } } diff --git a/pkg/network/tracer/process_cache.go b/pkg/network/tracer/process_cache.go index 32fb1fd57e171..b44eb56f044cc 100644 --- a/pkg/network/tracer/process_cache.go +++ b/pkg/network/tracer/process_cache.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build linux_bpf +//go:build linux_bpf || (windows && npm) package tracer @@ -178,7 +178,6 @@ func (pc *processCache) add(p *events.Process) { if log.ShouldLog(seelog.TraceLvl) { log.Tracef("adding process %+v to process cache", p) } - p.Expiry = time.Now().Add(defaultExpiry).Unix() if evicted := pc.cache.Add(processCacheKey{pid: p.Pid, startTime: p.StartTime}, p); evicted { processCacheTelemetry.cacheEvicts.Inc() @@ -196,7 +195,7 @@ func (pc *processCache) Get(pid uint32, ts int64) (*events.Process, bool) { pc.mu.Lock() defer pc.mu.Unlock() - log.TraceFunc(func() string { return fmt.Sprintf("looking up pid %d", pid) }) + log.TraceFunc(func() string { return fmt.Sprintf("looking up pid %d %v", pid, ts) }) pl := pc.cacheByPid[pid] if closest := pl.closest(ts); closest != nil { diff --git a/pkg/network/tracer/testutil/config_linux.go b/pkg/network/tracer/testutil/config_linux.go index fba26b51c94a7..b0efe630beb10 100644 --- a/pkg/network/tracer/testutil/config_linux.go +++ b/pkg/network/tracer/testutil/config_linux.go @@ -8,7 +8,7 @@ package testutil import ( - ddconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/network/config" "github.com/DataDog/datadog-agent/pkg/util/kernel" ) @@ -18,7 +18,7 @@ var kv = kernel.MustHostVersion() // Config returns a network.Config setup for test purposes func Config() *config.Config { cfg := config.New() - if ddconfig.IsECSFargate() { + if env.IsECSFargate() { // protocol classification not yet supported on fargate cfg.ProtocolClassificationEnabled = false } diff --git a/pkg/network/tracer/tracer.go b/pkg/network/tracer/tracer.go index db5f0bc95a1a9..55faac7817df1 100644 --- a/pkg/network/tracer/tracer.go +++ b/pkg/network/tracer/tracer.go @@ -15,7 +15,6 @@ import ( "sync" "time" - "github.com/DataDog/ebpf-manager/tracefs" "github.com/cihub/seelog" "github.com/cilium/ebpf" "go.uber.org/atomic" @@ -121,10 +120,6 @@ func NewTracer(config *config.Config, telemetryComponent telemetryComponent.Comp // newTracer is an internal function used by tests primarily // (and NewTracer above) func newTracer(cfg *config.Config, telemetryComponent telemetryComponent.Component) (_ *Tracer, reterr error) { - if _, err := tracefs.Root(); err != nil { - return nil, fmt.Errorf("system-probe unsupported: %s", err) - } - // check if current platform is using old kernel API because it affects what kprobe are we going to enable currKernelVersion, err := kernel.HostVersion() if err != nil { @@ -139,12 +134,16 @@ func newTracer(cfg *config.Config, telemetryComponent telemetryComponent.Compone } if cfg.ServiceMonitoringEnabled { - if !usmconfig.IsUSMSupported() { - errStr := fmt.Sprintf("Universal Service Monitoring (USM) requires a Linux kernel version of %s or higher. We detected %s", usmconfig.MinimumKernelVersion, currKernelVersion) + if err := usmconfig.CheckUSMSupported(cfg); err != nil { + // this is the case where USM is enabled and NPM is not enabled + // in config; we implicitly enable the network tracer module + // in system-probe if USM is enabled if !cfg.NPMEnabled { - return nil, fmt.Errorf(errStr) + return nil, err } - log.Warnf("%s. NPM is explicitly enabled, so system-probe will continue with only NPM features enabled.", errStr) + + log.Warn(err) + log.Warnf("NPM is explicitly enabled, so system-probe will continue with only NPM features enabled") } } @@ -244,30 +243,33 @@ func newConntracker(cfg *config.Config, telemetryComponent telemetryComponent.Co var c netlink.Conntracker var err error - ns, err := cfg.GetRootNetNs() - if err != nil { - log.Warnf("error fetching root net namespace, will not attempt to load nf_conntrack_netlink module: %s", err) - } else { - defer ns.Close() - if err = netlink.LoadNfConntrackKernelModule(ns); err != nil { - log.Warnf("failed to load conntrack kernel module, though it may already be loaded: %s", err) + if !cfg.EnableEbpfless { + ns, err := cfg.GetRootNetNs() + if err != nil { + log.Warnf("error fetching root net namespace, will not attempt to load nf_conntrack_netlink module: %s", err) + } else { + defer ns.Close() + if err = netlink.LoadNfConntrackKernelModule(ns); err != nil { + log.Warnf("failed to load conntrack kernel module, though it may already be loaded: %s", err) + } } - } - if cfg.EnableEbpfConntracker { - if c, err = NewEBPFConntracker(cfg, telemetryComponent); err == nil { - return c, nil + if cfg.EnableEbpfConntracker { + if c, err = NewEBPFConntracker(cfg, telemetryComponent); err == nil { + return c, nil + } + log.Warnf("error initializing ebpf conntracker: %s", err) + } else { + log.Info("ebpf conntracker disabled") } - log.Warnf("error initializing ebpf conntracker: %s", err) - } else { - log.Info("ebpf conntracker disabled") + + log.Info("falling back to netlink conntracker") } - log.Info("falling back to netlink conntracker") if c, err = netlink.NewConntracker(cfg, telemetryComponent); err == nil { return c, nil } - if cfg.IgnoreConntrackInitFailure { + if errors.Is(err, netlink.ErrNotPermitted) || cfg.IgnoreConntrackInitFailure { log.Warnf("could not initialize conntrack, tracer will continue without NAT tracking: %s", err) return netlink.NewNoOpConntracker(), nil } diff --git a/pkg/network/tracer/tracer_linux_test.go b/pkg/network/tracer/tracer_linux_test.go index f86ccbb749ff8..f541f252cf8bf 100644 --- a/pkg/network/tracer/tracer_linux_test.go +++ b/pkg/network/tracer/tracer_linux_test.go @@ -41,6 +41,7 @@ import ( "golang.org/x/sys/unix" ddconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" "github.com/DataDog/datadog-agent/pkg/ebpf/ebpftest" ebpftelemetry "github.com/DataDog/datadog-agent/pkg/ebpf/telemetry" @@ -241,7 +242,7 @@ func (s *TracerSuite) TestTCPRetransmitSharedSocket() { // Test if telemetry measuring PID collisions is correct // >= because there can be other connections going on during CI that increase pidCollisions - assert.GreaterOrEqual(t, connection.ConnTracerTelemetry.PidCollisions.Load(), int64(numProcesses-1)) + assert.GreaterOrEqual(t, connection.EbpfTracerTelemetry.PidCollisions.Load(), int64(numProcesses-1)) } func (s *TracerSuite) TestTCPRTT() { @@ -333,7 +334,7 @@ func (s *TracerSuite) TestTCPMiscount() { assert.False(t, uint64(len(x)) == conn.Monotonic.SentBytes) } - assert.NotZero(t, connection.ConnTracerTelemetry.LastTcpSentMiscounts.Load()) + assert.NotZero(t, connection.EbpfTracerTelemetry.LastTcpSentMiscounts.Load()) } func (s *TracerSuite) TestConnectionExpirationRegression() { @@ -387,6 +388,9 @@ func (s *TracerSuite) TestConnectionExpirationRegression() { func (s *TracerSuite) TestConntrackExpiration() { t := s.T() ebpftest.LogLevel(t, "trace") + + cfg := testConfig() + skipOnEbpflessNotSupported(t, cfg) netlinktestutil.SetupDNAT(t) tr := setupTracer(t, testConfig()) @@ -861,6 +865,7 @@ func (s *TracerSuite) TestGatewayLookupCrossNamespace() { }) t.Run("client in other namespace", func(t *testing.T) { + skipOnEbpflessNotSupported(t, cfg) // try connecting to server in test1 namespace test2Ns, err := vnetns.GetFromName(ns2) require.NoError(t, err) @@ -925,6 +930,8 @@ func (s *TracerSuite) TestGatewayLookupCrossNamespace() { func (s *TracerSuite) TestConnectionAssured() { t := s.T() cfg := testConfig() + skipOnEbpflessNotSupported(t, cfg) + tr := setupTracer(t, cfg) server := &UDPServer{ network: "udp4", @@ -1012,9 +1019,11 @@ func (s *TracerSuite) TestUDPConnExpiryTimeout() { func (s *TracerSuite) TestDNATIntraHostIntegration() { t := s.T() + cfg := testConfig() + skipEbpflessTodo(t, cfg) netlinktestutil.SetupDNAT(t) - tr := setupTracer(t, testConfig()) + tr := setupTracer(t, cfg) var serverAddr struct { local, remote net.Addr @@ -1385,12 +1394,13 @@ func testUDPReusePort(t *testing.T, udpnet string, ip string) { func (s *TracerSuite) TestDNSStatsWithNAT() { t := s.T() + cfg := testConfig() + skipEbpflessTodo(t, cfg) testutil.IptablesSave(t) // Setup a NAT rule to translate 2.2.2.2 to 8.8.8.8 and issue a DNS request to 2.2.2.2 cmds := []string{"iptables -t nat -A OUTPUT -d 2.2.2.2 -j DNAT --to-destination 8.8.8.8"} testutil.RunCommands(t, cmds, false) - cfg := testConfig() cfg.CollectDNSStats = true cfg.DNSTimeout = 1 * time.Second tr := setupTracer(t, cfg) @@ -1713,6 +1723,7 @@ func (s *TracerSuite) TestShortWrite() { func (s *TracerSuite) TestKprobeAttachWithKprobeEvents() { t := s.T() cfg := config.New() + skipOnEbpflessNotSupported(t, cfg) cfg.AttachKprobesWithKprobeEventsABI = true tr := setupTracer(t, cfg) @@ -1851,7 +1862,9 @@ func (s *TracerSuite) TestPreexistingConnectionDirection() { m := outgoing.Monotonic assert.Equal(t, clientMessageSize, int(m.SentBytes)) assert.Equal(t, serverMessageSize, int(m.RecvBytes)) - assert.Equal(t, os.Getpid(), int(outgoing.Pid)) + if !tr.config.EnableEbpfless { + assert.Equal(t, os.Getpid(), int(outgoing.Pid)) + } assert.Equal(t, addrPort(server.Address()), int(outgoing.DPort)) assert.Equal(t, c.LocalAddr().(*net.TCPAddr).Port, int(outgoing.SPort)) assert.Equal(t, network.OUTGOING, outgoing.Direction) @@ -1859,7 +1872,9 @@ func (s *TracerSuite) TestPreexistingConnectionDirection() { m = incoming.Monotonic assert.Equal(t, clientMessageSize, int(m.RecvBytes)) assert.Equal(t, serverMessageSize, int(m.SentBytes)) - assert.Equal(t, os.Getpid(), int(incoming.Pid)) + if !tr.config.EnableEbpfless { + assert.Equal(t, os.Getpid(), int(incoming.Pid)) + } assert.Equal(t, addrPort(server.Address()), int(incoming.SPort)) assert.Equal(t, c.LocalAddr().(*net.TCPAddr).Port, int(incoming.DPort)) assert.Equal(t, network.INCOMING, incoming.Direction) @@ -1872,6 +1887,7 @@ func (s *TracerSuite) TestPreexistingEmptyIncomingConnectionDirection() { t.Skip("skipping test as ringbuffers are not supported on this kernel") } c := testConfig() + skipOnEbpflessNotSupported(t, c) c.NPMRingbuffersEnabled = true testPreexistingEmptyIncomingConnectionDirection(t, c) }) @@ -1890,6 +1906,7 @@ func testPreexistingEmptyIncomingConnectionDirection(t *testing.T, config *confi server := tracertestutil.NewTCPServer(func(c net.Conn) { <-ch c.Close() + close(ch) }) require.NoError(t, server.Run()) t.Cleanup(server.Shutdown) @@ -1901,7 +1918,8 @@ func testPreexistingEmptyIncomingConnectionDirection(t *testing.T, config *confi tr := setupTracer(t, config) // close the server connection so the tracer picks it up - close(ch) + ch <- struct{}{} + <-ch var conn *network.ConnectionStats require.Eventually(t, func() bool { @@ -2121,7 +2139,7 @@ func TestConntrackerFallback(t *testing.T) { func testConfig() *config.Config { cfg := config.New() - if ddconfig.IsECSFargate() { + if env.IsECSFargate() { // protocol classification not yet supported on fargate cfg.ProtocolClassificationEnabled = false } @@ -2337,3 +2355,15 @@ func setupDropTrafficRule(tb testing.TB) (ns string) { testutil.RunCommands(tb, cmds, false) return } + +func skipOnEbpflessNotSupported(t *testing.T, cfg *config.Config) { + if cfg.EnableEbpfless { + t.Skip("not supported on ebpf-less") + } +} + +func skipEbpflessTodo(t *testing.T, cfg *config.Config) { + if cfg.EnableEbpfless { + t.Skip("TODO: ebpf-less") + } +} diff --git a/pkg/network/tracer/tracer_test.go b/pkg/network/tracer/tracer_test.go index 7011923c9329d..1e001d5b5ed98 100644 --- a/pkg/network/tracer/tracer_test.go +++ b/pkg/network/tracer/tracer_test.go @@ -34,6 +34,7 @@ import ( "golang.org/x/sync/errgroup" ddconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/ebpf/ebpftest" "github.com/DataDog/datadog-agent/pkg/network" "github.com/DataDog/datadog-agent/pkg/network/config" @@ -76,7 +77,7 @@ func isFentry() bool { func setupTracer(t testing.TB, cfg *config.Config) *Tracer { if isFentry() { - ddconfig.SetFeatures(t, ddconfig.ECSFargate) + ddconfig.SetFeatures(t, env.ECSFargate) // protocol classification not yet supported on fargate cfg.ProtocolClassificationEnabled = false } @@ -156,7 +157,8 @@ func (s *TracerSuite) TestGetStats() { func (s *TracerSuite) TestTCPSendAndReceive() { t := s.T() - tr := setupTracer(t, testConfig()) + cfg := testConfig() + tr := setupTracer(t, cfg) // Create TCP Server which, for every line, sends back a message with size=serverMessageSize server := testutil.NewTCPServer(func(c net.Conn) { @@ -208,10 +210,11 @@ func (s *TracerSuite) TestTCPSendAndReceive() { m := conn.Monotonic assert.Equal(t, 10*clientMessageSize, int(m.SentBytes)) assert.Equal(t, 10*serverMessageSize, int(m.RecvBytes)) - assert.Equal(t, os.Getpid(), int(conn.Pid)) + if !cfg.EnableEbpfless { + assert.Equal(t, os.Getpid(), int(conn.Pid)) + } assert.Equal(t, addrPort(server.Address()), int(conn.DPort)) assert.Equal(t, network.OUTGOING, conn.Direction) - assert.True(t, conn.IntraHost) } func (s *TracerSuite) TestTCPShortLived() { @@ -557,14 +560,16 @@ func (s *TracerSuite) TestLocalDNSCollectionEnabled() { _, err = cn.Write([]byte("test")) assert.NoError(t, err) - found := false - // Iterate through active connections making sure theres at least one connection - for _, c := range getConnections(t, tr).Conns { - found = found || isLocalDNS(c) - } + require.Eventually(t, func() bool { + for _, c := range getConnections(t, tr).Conns { + if isLocalDNS(c) { + return true + } + } - assert.True(t, found) + return false + }, 3*time.Second, 100*time.Millisecond, "could not find connection") } func isLocalDNS(c network.ConnectionStats) bool { @@ -993,8 +998,10 @@ func testDNSStats(t *testing.T, tr *Tracer, domain string, success, failure, tim if !assert.Equal(c, queryMsg.Len(), int(conn.Monotonic.SentBytes)) { return } - if !assert.Equal(c, os.Getpid(), int(conn.Pid)) { - return + if !tr.config.EnableEbpfless { + if !assert.Equal(c, os.Getpid(), int(conn.Pid)) { + return + } } if !assert.Equal(c, dnsServerAddr.Port, int(conn.DPort)) { return @@ -1161,10 +1168,15 @@ func (s *TracerSuite) TestConnectedUDPSendIPv6() { bytesSent, err := conn.Write(message) require.NoError(t, err) - connections := getConnections(t, tr) - outgoing := network.FilterConnections(connections, func(cs network.ConnectionStats) bool { - return cs.DPort == uint16(remotePort) - }) + var outgoing []network.ConnectionStats + require.Eventually(t, func() bool { + connections := getConnections(t, tr) + outgoing = network.FilterConnections(connections, func(cs network.ConnectionStats) bool { + return cs.DPort == uint16(remotePort) + }) + + return len(outgoing) == 1 + }, 3*time.Second, 100*time.Millisecond, "failed to find connection") require.Len(t, outgoing, 1) assert.Equal(t, remoteAddr.IP.String(), outgoing[0].Dest.String()) diff --git a/pkg/network/tracer/tracer_windows.go b/pkg/network/tracer/tracer_windows.go index 4e39b66739f8e..a4677a19c501a 100644 --- a/pkg/network/tracer/tracer_windows.go +++ b/pkg/network/tracer/tracer_windows.go @@ -17,6 +17,8 @@ import ( "syscall" "time" + "go4.org/intern" + "golang.org/x/sys/windows" "github.com/DataDog/datadog-agent/comp/core/telemetry" @@ -25,6 +27,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/network/config" "github.com/DataDog/datadog-agent/pkg/network/dns" driver "github.com/DataDog/datadog-agent/pkg/network/driver" + "github.com/DataDog/datadog-agent/pkg/network/events" "github.com/DataDog/datadog-agent/pkg/network/usm" "github.com/DataDog/datadog-agent/pkg/process/util" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -59,6 +62,8 @@ type Tracer struct { // windows event handle for stopping the closed connection event loop hStopClosedLoopEvent windows.Handle + + processCache *processCache } // NewTracer returns an initialized tracer struct @@ -114,6 +119,22 @@ func NewTracer(config *config.Config, telemetry telemetry.Component) (*Tracer, e destExcludes: network.ParseConnectionFilters(config.ExcludedDestinationConnections), hStopClosedLoopEvent: stopEvent, } + if config.EnableProcessEventMonitoring { + if tr.processCache, err = newProcessCache(config.MaxProcessesTracked); err != nil { + return nil, fmt.Errorf("could not create process cache; %w", err) + } + if telemetry != nil { + // the tests don't have a telemetry component + telemetry.RegisterCollector(tr.processCache) + } + + if err = events.Init(); err != nil { + return nil, fmt.Errorf("could not initialize event monitoring: %w", err) + } + + events.RegisterHandler(tr.processCache) + } + tr.closedEventLoop.Add(1) go func() { defer tr.closedEventLoop.Done() @@ -137,6 +158,7 @@ func NewTracer(config *config.Config, telemetry telemetry.Component) (*Tracer, e closedConnStats := tr.closedBuffer.Connections() for i := range closedConnStats { + tr.addProcessInfo(&closedConnStats[i]) tr.state.StoreClosedConnection(&closedConnStats[i]) } @@ -200,7 +222,11 @@ func (t *Tracer) GetActiveConnections(clientID string) (*network.Connections, er // check for expired clients in the state t.state.RemoveExpiredClients(time.Now()) + for i := range activeConnStats { + t.addProcessInfo(&activeConnStats[i]) + } for i := range closedConnStats { + t.addProcessInfo(&closedConnStats[i]) t.state.StoreClosedConnection(&closedConnStats[i]) } @@ -301,3 +327,28 @@ func newUSMMonitor(c *config.Config, dh driver.Handle) usm.Monitor { monitor.Start() return monitor } + +func (t *Tracer) addProcessInfo(c *network.ConnectionStats) { + if t.processCache == nil { + return + } + + c.ContainerID.Source, c.ContainerID.Dest = nil, nil + + // on windows, cLastUpdateEpoch is already set as + // ns since unix epoch. + ts := c.LastUpdateEpoch + p, ok := t.processCache.Get(c.Pid, int64(ts)) + if !ok { + return + } + + if len(p.Tags) > 0 { + c.Tags = make([]*intern.Value, len(p.Tags)) + copy(c.Tags, p.Tags) + } + + if p.ContainerID != nil { + c.ContainerID.Source = p.ContainerID + } +} diff --git a/pkg/network/tracer/utils_linux.go b/pkg/network/tracer/utils_linux.go index 2477b60ea38a1..d072906eec687 100644 --- a/pkg/network/tracer/utils_linux.go +++ b/pkg/network/tracer/utils_linux.go @@ -3,8 +3,6 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build linux_bpf - package tracer import ( @@ -16,10 +14,16 @@ import ( "github.com/cilium/ebpf/asm" "github.com/cilium/ebpf/features" + coreconfig "github.com/DataDog/datadog-agent/pkg/config" "github.com/DataDog/datadog-agent/pkg/util/kernel" "github.com/DataDog/datadog-agent/pkg/util/log" ) +// NeedsEBPF returns `true` if the network-tracer requires eBPF +func NeedsEBPF() bool { + return !coreconfig.SystemProbe().GetBool("network_config.enable_ebpfless") +} + // IsTracerSupportedByOS returns whether the current kernel version supports tracer functionality // along with some context on why it's not supported func IsTracerSupportedByOS(exclusionList []string) (bool, error) { @@ -59,6 +63,10 @@ func verifyOSVersion(kernelCode kernel.Version, platform string, exclusionList [ return false, fmt.Errorf("Known bug for kernel %s on platform %s, see: \n- https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1763454", kernelCode, platform) } + if !NeedsEBPF() { + return true, nil + } + var requiredFuncs = []asm.BuiltinFunc{ asm.FnMapLookupElem, asm.FnMapUpdateElem, @@ -81,5 +89,5 @@ func verifyOSVersion(kernelCode kernel.Version, platform string, exclusionList [ } errMsg := fmt.Sprintf("Kernel unsupported (%s) - ", kernelCode) errMsg += fmt.Sprintf("required functions missing: %s", strings.Join(missingFuncs, ", ")) - return false, fmt.Errorf(errMsg) + return false, errors.New(errMsg) } diff --git a/pkg/network/tracer/utils_unsupported.go b/pkg/network/tracer/utils_unsupported.go index cf8f70835e1a8..5678e22e579e1 100644 --- a/pkg/network/tracer/utils_unsupported.go +++ b/pkg/network/tracer/utils_unsupported.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build !linux_bpf && !windows +//go:build !windows && !linux package tracer diff --git a/pkg/network/usm/config/config.go b/pkg/network/usm/config/config.go index 915e68b15098b..00a4cc9764c5b 100644 --- a/pkg/network/usm/config/config.go +++ b/pkg/network/usm/config/config.go @@ -9,6 +9,8 @@ package config import ( + "errors" + "fmt" "runtime" "strings" @@ -20,6 +22,9 @@ import ( // MinimumKernelVersion indicates the minimum kernel version required for HTTP monitoring var MinimumKernelVersion kernel.Version +// ErrNotSupported is the error returned if USM is not supported on this platform +var ErrNotSupported = errors.New("Universal Service Monitoring (USM) is not supported") + func init() { MinimumKernelVersion = kernel.VersionCode(4, 14, 0) } @@ -44,21 +49,31 @@ func TLSSupported(c *config.Config) bool { return kversion >= MinimumKernelVersion } -// IsUSMSupported We only support http with kernel >= 4.14.0. -func IsUSMSupported() bool { +// CheckUSMSupported returns an error if USM is not supported +// on this platform. Callers can check `errors.Is(err, ErrNotSupported)` +// to verify if USM is supported +func CheckUSMSupported(cfg *config.Config) error { + // TODO: remove this once USM is supported on ebpf-less + if cfg.EnableEbpfless { + return fmt.Errorf("%w: eBPF-less is not supported", ErrNotSupported) + } + kversion, err := kernel.HostVersion() if err != nil { - log.Warn("could not determine the current kernel version. USM disabled.") - return false + return fmt.Errorf("%w: could not determine the current kernel version: %w", ErrNotSupported, err) } - return kversion >= MinimumKernelVersion + if kversion < MinimumKernelVersion { + return fmt.Errorf("%w: a Linux kernel version of %s or higher is required; we detected %s", ErrNotSupported, MinimumKernelVersion, kversion) + } + + return nil } // IsUSMSupportedAndEnabled returns true if USM is supported and enabled func IsUSMSupportedAndEnabled(config *config.Config) bool { // http.Supported is misleading, it should be named usm.Supported. - return config.ServiceMonitoringEnabled && IsUSMSupported() + return config.ServiceMonitoringEnabled && CheckUSMSupported(config) == nil } // NeedProcessMonitor returns true if the process monitor is needed for the given configuration diff --git a/pkg/network/usm/ebpf_gotls.go b/pkg/network/usm/ebpf_gotls.go index 0eb4a1613cec3..e0090e3ba889c 100644 --- a/pkg/network/usm/ebpf_gotls.go +++ b/pkg/network/usm/ebpf_gotls.go @@ -119,6 +119,9 @@ type goTLSProgram struct { // analysis binAnalysisMetric *libtelemetry.Counter + // binNoSymbolsMetric counts Golang binaries without symbols. + binNoSymbolsMetric *libtelemetry.Counter + registry *utils.FileRegistry } @@ -176,12 +179,13 @@ func newGoTLSProgramProtocolFactory(m *manager.Manager) protocols.ProtocolFactor } return &goTLSProgram{ - done: make(chan struct{}), - cfg: c, - manager: m, - procRoot: c.ProcRoot, - binAnalysisMetric: libtelemetry.NewCounter("usm.go_tls.analysis_time", libtelemetry.OptPrometheus), - registry: utils.NewFileRegistry("go-tls"), + done: make(chan struct{}), + cfg: c, + manager: m, + procRoot: c.ProcRoot, + binAnalysisMetric: libtelemetry.NewCounter("usm.go_tls.analysis_time", libtelemetry.OptPrometheus), + binNoSymbolsMetric: libtelemetry.NewCounter("usm.go_tls.missing_symbols", libtelemetry.OptPrometheus), + registry: utils.NewFileRegistry("go-tls"), }, nil } } @@ -334,10 +338,12 @@ func (p *goTLSProgram) AttachPID(pid uint32) error { // Check go process probeList := make([]manager.ProbeIdentificationPair, 0) - return p.registry.Register(binPath, pid, registerCBCreator(p.manager, p.offsetsDataMap, &probeList, p.binAnalysisMetric), unregisterCBCreator(p.manager, &probeList, p.offsetsDataMap)) + return p.registry.Register(binPath, pid, registerCBCreator(p.manager, p.offsetsDataMap, &probeList, p.binAnalysisMetric, p.binNoSymbolsMetric), + unregisterCBCreator(p.manager, &probeList, p.offsetsDataMap), + utils.IgnoreCB) } -func registerCBCreator(mgr *manager.Manager, offsetsDataMap *ebpf.Map, probeIDs *[]manager.ProbeIdentificationPair, binAnalysisMetric *libtelemetry.Counter) func(path utils.FilePath) error { +func registerCBCreator(mgr *manager.Manager, offsetsDataMap *ebpf.Map, probeIDs *[]manager.ProbeIdentificationPair, binAnalysisMetric, binNoSymbolsMetric *libtelemetry.Counter) func(path utils.FilePath) error { return func(filePath utils.FilePath) error { start := time.Now() @@ -354,6 +360,9 @@ func registerCBCreator(mgr *manager.Manager, offsetsDataMap *ebpf.Map, probeIDs inspectionResult, err := bininspect.InspectNewProcessBinary(elfFile, functionsConfig, structFieldsLookupFunctions) if err != nil { + if errors.Is(err, elf.ErrNoSymbols) { + binNoSymbolsMetric.Add(1) + } return fmt.Errorf("error extracting inspectoin data from %s: %w", filePath.HostPath, err) } diff --git a/pkg/network/usm/ebpf_ssl_test.go b/pkg/network/usm/ebpf_ssl_test.go index 617dd25912ecb..99d8dcf37fdfb 100644 --- a/pkg/network/usm/ebpf_ssl_test.go +++ b/pkg/network/usm/ebpf_ssl_test.go @@ -32,7 +32,8 @@ func testArch(t *testing.T, arch string) { curDir, err := testutil.CurDir() require.NoError(t, err) - libmmap := filepath.Join(curDir, "testdata", "libmmap") + // Named site-packages/ddtrace since it is used from servicediscovery tests too. + libmmap := filepath.Join(curDir, "testdata", "site-packages", "ddtrace") lib := filepath.Join(libmmap, fmt.Sprintf("libssl.so.%s", arch)) monitor := setupUSMTLSMonitor(t, cfg) diff --git a/pkg/network/usm/istio.go b/pkg/network/usm/istio.go index e5f291b647f87..12bcc0df94046 100644 --- a/pkg/network/usm/istio.go +++ b/pkg/network/usm/istio.go @@ -136,6 +136,7 @@ func (m *istioMonitor) AttachPID(pid uint32) error { pid, m.registerCB, m.unregisterCB, + utils.IgnoreCB, ) } diff --git a/pkg/network/usm/kafka_monitor_test.go b/pkg/network/usm/kafka_monitor_test.go index d42ba08aab0b3..2862a8600c89b 100644 --- a/pkg/network/usm/kafka_monitor_test.go +++ b/pkg/network/usm/kafka_monitor_test.go @@ -1513,7 +1513,15 @@ func validateProduceFetchCount(t *assert.CollectT, kafkaStats map[kafka.Key]*kaf numberOfProduceRequests := 0 numberOfFetchRequests := 0 for kafkaKey, kafkaStat := range kafkaStats { - hasTLSTag := kafkaStat.ErrorCodeToStat[errorCode].StaticTags&network.ConnTagGo != 0 + requestStats, exists := kafkaStat.ErrorCodeToStat[errorCode] + assert.True(t, exists, "Expected error code %d not found in stats", errorCode) + // assert does not halt the execution, we need to do it manually. + // Thus, if the error code is not found, we should not continue, as we expect it to be found for all stats. + // So, we marked this iteration as failed (by calling assert.True), and we should return here. + if !exists { + return + } + hasTLSTag := requestStats.StaticTags&network.ConnTagGo != 0 if hasTLSTag != validation.tlsEnabled { continue } @@ -1521,11 +1529,11 @@ func validateProduceFetchCount(t *assert.CollectT, kafkaStats map[kafka.Key]*kaf switch kafkaKey.RequestAPIKey { case kafka.ProduceAPIKey: assert.Equal(t, uint16(validation.expectedAPIVersionProduce), kafkaKey.RequestVersion) - numberOfProduceRequests += kafkaStat.ErrorCodeToStat[errorCode].Count + numberOfProduceRequests += requestStats.Count case kafka.FetchAPIKey: assert.Equal(t, uint16(validation.expectedAPIVersionFetch), kafkaKey.RequestVersion) - assert.Greater(t, kafkaStat.ErrorCodeToStat[errorCode].FirstLatencySample, float64(1)) - numberOfFetchRequests += kafkaStat.ErrorCodeToStat[errorCode].Count + assert.Greater(t, requestStats.FirstLatencySample, float64(1)) + numberOfFetchRequests += requestStats.Count default: assert.FailNow(t, "Expecting only produce or fetch kafka requests") } diff --git a/pkg/network/usm/monitor.go b/pkg/network/usm/monitor.go index 54180ccea27a1..f1f73ab50d858 100644 --- a/pkg/network/usm/monitor.go +++ b/pkg/network/usm/monitor.go @@ -25,21 +25,13 @@ import ( "github.com/DataDog/datadog-agent/pkg/network/protocols" "github.com/DataDog/datadog-agent/pkg/network/protocols/telemetry" usmconfig "github.com/DataDog/datadog-agent/pkg/network/usm/config" + usmstate "github.com/DataDog/datadog-agent/pkg/network/usm/state" "github.com/DataDog/datadog-agent/pkg/network/usm/utils" "github.com/DataDog/datadog-agent/pkg/process/monitor" "github.com/DataDog/datadog-agent/pkg/util/log" ) -type monitorState = string - -const ( - disabled monitorState = "disabled" - running monitorState = "running" - notRunning monitorState = "Not running" -) - var ( - state = disabled startupError error ) @@ -65,7 +57,7 @@ func NewMonitor(c *config.Config, connectionProtocolMap *ebpf.Map) (m *Monitor, defer func() { // capture error and wrap it if err != nil { - state = notRunning + usmstate.Set(usmstate.NotRunning) err = fmt.Errorf("could not initialize USM: %w", err) startupError = err } @@ -77,7 +69,7 @@ func NewMonitor(c *config.Config, connectionProtocolMap *ebpf.Map) (m *Monitor, } if len(mgr.enabledProtocols) == 0 { - state = disabled + usmstate.Set(usmstate.Disabled) log.Debug("not enabling USM as no protocols monitoring were enabled.") return nil, nil } @@ -99,7 +91,7 @@ func NewMonitor(c *config.Config, connectionProtocolMap *ebpf.Map) (m *Monitor, processMonitor := monitor.GetProcessMonitor() - state = running + usmstate.Set(usmstate.Running) usmMonitor := &Monitor{ cfg: c, @@ -169,7 +161,7 @@ func (m *Monitor) Resume() error { // GetUSMStats returns the current state of the USM monitor func (m *Monitor) GetUSMStats() map[string]interface{} { response := map[string]interface{}{ - "state": state, + "state": usmstate.Get(), } if startupError != nil { @@ -215,6 +207,7 @@ func (m *Monitor) Stop() { m.ebpfProgram.Close() m.closeFilterFn() + usmstate.Set(usmstate.Stopped) } // DumpMaps dumps the maps associated with the monitor diff --git a/pkg/network/usm/nodejs.go b/pkg/network/usm/nodejs.go index bd4f3821454b7..387e22918aa52 100644 --- a/pkg/network/usm/nodejs.go +++ b/pkg/network/usm/nodejs.go @@ -228,6 +228,7 @@ func (m *nodeJSMonitor) AttachPID(pid uint32) error { pid, m.registerCB, m.unregisterCB, + utils.IgnoreCB, ) } diff --git a/pkg/network/usm/postgres_monitor_test.go b/pkg/network/usm/postgres_monitor_test.go index 5e16cd3117472..a74ef203f3721 100644 --- a/pkg/network/usm/postgres_monitor_test.go +++ b/pkg/network/usm/postgres_monitor_test.go @@ -34,15 +34,17 @@ import ( ) const ( - postgresPort = "5432" - repeatCount = ebpf.BufferSize / len("table_") - createTableQuery = "CREATE TABLE dummy (id SERIAL PRIMARY KEY, foo TEXT)" - updateSingleValueQuery = "UPDATE dummy SET foo = 'updated' WHERE id = 1" - selectAllQuery = "SELECT * FROM dummy" - dropTableQuery = "DROP TABLE IF EXISTS dummy" - deleteTableQuery = "DELETE FROM dummy WHERE id = 1" - alterTableQuery = "ALTER TABLE dummy ADD test VARCHAR(255);" - truncateTableQuery = "TRUNCATE TABLE dummy" + postgresPort = "5432" + repeatCount = ebpf.BufferSize / len("table_") + createTableQuery = "CREATE TABLE dummy (id SERIAL PRIMARY KEY, foo TEXT)" + updateSingleValueQuery = "UPDATE dummy SET foo = 'updated' WHERE id = 1" + selectAllQuery = "SELECT * FROM dummy" + selectParameterizedQuery = "SELECT * FROM dummy WHERE id = $1" + dropTableQuery = "DROP TABLE IF EXISTS dummy" + deleteTableQuery = "DELETE FROM dummy WHERE id = 1" + alterTableQuery = "ALTER TABLE dummy ADD test VARCHAR(255);" + truncateTableQuery = "TRUNCATE TABLE dummy" + showQuery = "SHOW search_path" ) var ( @@ -476,6 +478,115 @@ func testDecoding(t *testing.T, isTLS bool) { }, isTLS) }, }, + // This test validates that the SHOW command is currently not supported. + { + name: "show command", + preMonitorSetup: func(t *testing.T, ctx pgTestContext) { + pg, err := postgres.NewPGXClient(postgres.ConnectionOptions{ + ServerAddress: ctx.serverAddress, + EnableTLS: isTLS, + }) + require.NoError(t, err) + require.NoError(t, pg.Ping()) + ctx.extras["pg"] = pg + require.NoError(t, pg.RunQuery(createTableQuery)) + }, + postMonitorSetup: func(t *testing.T, ctx pgTestContext) { + pg := ctx.extras["pg"].(*postgres.PGXClient) + require.NoError(t, pg.RunQuery(showQuery)) + }, + validation: func(t *testing.T, _ pgTestContext, monitor *Monitor) { + validatePostgres(t, monitor, map[string]map[postgres.Operation]int{ + "UNKNOWN": { + postgres.UnknownOP: adjustCount(1), + }, + }, isTLS) + }, + }, + // This test validates that the sql transaction is not supported. + { + name: "transaction", + preMonitorSetup: func(t *testing.T, ctx pgTestContext) { + pg, err := postgres.NewPGXClient(postgres.ConnectionOptions{ + ServerAddress: ctx.serverAddress, + EnableTLS: isTLS, + }) + require.NoError(t, err) + require.NoError(t, pg.Ping()) + ctx.extras["pg"] = pg + + tx, err := pg.Begin() + require.NoError(t, err) + require.NoError(t, pg.RunQuery(createTableQuery)) + require.NoError(t, pg.Commit(tx)) + }, + postMonitorSetup: func(t *testing.T, ctx pgTestContext) { + pg := ctx.extras["pg"].(*postgres.PGXClient) + + tx, err := pg.Begin() + require.NoError(t, err) + require.NoError(t, pg.RunQueryTX(tx, selectAllQuery)) + require.NoError(t, pg.Commit(tx)) + }, + validation: func(t *testing.T, _ pgTestContext, monitor *Monitor) { + validatePostgres(t, monitor, map[string]map[postgres.Operation]int{ + "UNKNOWN": { + postgres.UnknownOP: adjustCount(2), + }, + "dummy": { + postgres.SelectOP: adjustCount(1), + }, + }, isTLS) + }, + }, + { + name: "batched queries", + preMonitorSetup: func(t *testing.T, ctx pgTestContext) { + pg, err := postgres.NewPGXClient(postgres.ConnectionOptions{ + ServerAddress: ctx.serverAddress, + EnableTLS: isTLS, + }) + require.NoError(t, err) + require.NoError(t, pg.Ping()) + ctx.extras["pg"] = pg + require.NoError(t, pg.RunQuery(createTableQuery)) + + }, + postMonitorSetup: func(t *testing.T, ctx pgTestContext) { + pg := ctx.extras["pg"].(*postgres.PGXClient) + + require.NoError(t, pg.SendBatch(createInsertQuery("value-1"), selectAllQuery)) + }, + validation: func(t *testing.T, _ pgTestContext, monitor *Monitor) { + validatePostgres(t, monitor, map[string]map[postgres.Operation]int{ + "dummy": { + postgres.InsertOP: adjustCount(1), + }, + }, isTLS) + }, + }, + // This test validates that parameterized queries are currently not supported. + { + name: "parameterized select", + preMonitorSetup: func(t *testing.T, ctx pgTestContext) { + pg, err := postgres.NewPGXClient(postgres.ConnectionOptions{ + ServerAddress: ctx.serverAddress, + EnableTLS: isTLS, + }) + require.NoError(t, err) + require.NoError(t, pg.Ping()) + ctx.extras["pg"] = pg + require.NoError(t, pg.RunQuery(createTableQuery)) + require.NoError(t, pg.RunQuery(createInsertQuery("value-1"))) + }, + postMonitorSetup: func(t *testing.T, ctx pgTestContext) { + pg := ctx.extras["pg"].(*postgres.PGXClient) + require.NoError(t, pg.RunQuery(selectParameterizedQuery, "value-1")) + }, + validation: func(t *testing.T, _ pgTestContext, monitor *Monitor) { + validatePostgres(t, monitor, map[string]map[postgres.Operation]int{}, isTLS) + }, + }, } for _, tt := range tests { diff --git a/pkg/network/usm/sharedlibraries/testutil/testutil.go b/pkg/network/usm/sharedlibraries/testutil/testutil.go index a8123133ba614..1cf1bcee23e3a 100644 --- a/pkg/network/usm/sharedlibraries/testutil/testutil.go +++ b/pkg/network/usm/sharedlibraries/testutil/testutil.go @@ -26,10 +26,9 @@ import ( // mutex protecting build process var mux sync.Mutex -// OpenFromAnotherProcess launches an external file that holds active handler to the given paths. -func OpenFromAnotherProcess(t *testing.T, paths ...string) (*exec.Cmd, error) { - programExecutable := build(t) - +// OpenFromProcess launches the specified external program which holds an active +// handle to the given paths. +func OpenFromProcess(t *testing.T, programExecutable string, paths ...string) (*exec.Cmd, error) { cmd := exec.Command(programExecutable, paths...) patternScanner := protocolstestutil.NewScanner(regexp.MustCompile("awaiting signal"), make(chan struct{}, 1)) cmd.Stdout = patternScanner @@ -56,8 +55,16 @@ func OpenFromAnotherProcess(t *testing.T, paths ...string) (*exec.Cmd, error) { } } -// build only gets executed when running tests locally -func build(t *testing.T) string { +// OpenFromAnotherProcess launches an external program that holds an active +// handle to the given paths. +func OpenFromAnotherProcess(t *testing.T, paths ...string) (*exec.Cmd, error) { + programExecutable := BuildFmapper(t) + return OpenFromProcess(t, programExecutable, paths...) +} + +// BuildFmapper builds the external program which is used to hold references to +// shared libraries for testing. +func BuildFmapper(t *testing.T) string { mux.Lock() defer mux.Unlock() diff --git a/pkg/network/usm/sharedlibraries/watcher.go b/pkg/network/usm/sharedlibraries/watcher.go index 9f926a1eba5a7..1342e2c8fd50b 100644 --- a/pkg/network/usm/sharedlibraries/watcher.go +++ b/pkg/network/usm/sharedlibraries/watcher.go @@ -156,7 +156,7 @@ func (w *Watcher) AttachPID(pid uint32) error { // Iterate over the rule, and look for a match. for _, r := range w.rules { if r.Re.MatchString(path) { - if err := w.registry.Register(path, pid, r.RegisterCB, r.UnregisterCB); err != nil { + if err := w.registry.Register(path, pid, r.RegisterCB, r.UnregisterCB, utils.IgnoreCB); err != nil { registerErrors = append(registerErrors, err) } else { successfulMatches = append(successfulMatches, path) @@ -210,7 +210,7 @@ func (w *Watcher) Start() { // Iterate over the rule, and look for a match. for _, r := range w.rules { if r.Re.MatchString(path) { - _ = w.registry.Register(path, uint32(pid), r.RegisterCB, r.UnregisterCB) + _ = w.registry.Register(path, uint32(pid), r.RegisterCB, r.UnregisterCB, utils.IgnoreCB) break } } @@ -267,7 +267,7 @@ func (w *Watcher) Start() { for _, r := range w.rules { if r.Re.Match(path) { w.libMatches.Add(1) - _ = w.registry.Register(string(path), lib.Pid, r.RegisterCB, r.UnregisterCB) + _ = w.registry.Register(string(path), lib.Pid, r.RegisterCB, r.UnregisterCB, utils.IgnoreCB) break } } diff --git a/pkg/network/usm/state/state.go b/pkg/network/usm/state/state.go new file mode 100644 index 0000000000000..f2c2bc1b85d25 --- /dev/null +++ b/pkg/network/usm/state/state.go @@ -0,0 +1,43 @@ +// 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 2024-present Datadog, Inc. + +// Package state provides the state of the USM monitor. +package state + +import ( + "go.uber.org/atomic" +) + +// MonitorState represents the state of the USM monitor. +type MonitorState = string + +const ( + // Disabled represents the state of the USM monitor when it is disabled. + Disabled MonitorState = "Disabled" + // Running represents the state of the USM monitor when it is running. + Running MonitorState = "Running" + // NotRunning represents the state of the USM monitor when it is not running. + NotRunning MonitorState = "Not running" + // Stopped represents the state of the USM monitor when it is stopped. + Stopped MonitorState = "Stopped" +) + +var ( + globalState = &atomic.Value{} +) + +func init() { + Set(Disabled) +} + +// Set sets the current state of the USM monitor. +func Set(state MonitorState) { + globalState.Store(state) +} + +// Get returns the current state of the USM monitor. +func Get() MonitorState { + return globalState.Load().(MonitorState) +} diff --git a/pkg/network/usm/testdata/libmmap/build.sh b/pkg/network/usm/testdata/site-packages/ddtrace/build.sh similarity index 100% rename from pkg/network/usm/testdata/libmmap/build.sh rename to pkg/network/usm/testdata/site-packages/ddtrace/build.sh diff --git a/pkg/network/usm/testdata/libmmap/fakessl.c b/pkg/network/usm/testdata/site-packages/ddtrace/fakessl.c similarity index 100% rename from pkg/network/usm/testdata/libmmap/fakessl.c rename to pkg/network/usm/testdata/site-packages/ddtrace/fakessl.c diff --git a/pkg/network/usm/testdata/libmmap/libssl.so.amd64 b/pkg/network/usm/testdata/site-packages/ddtrace/libssl.so.amd64 similarity index 100% rename from pkg/network/usm/testdata/libmmap/libssl.so.amd64 rename to pkg/network/usm/testdata/site-packages/ddtrace/libssl.so.amd64 diff --git a/pkg/network/usm/testdata/libmmap/libssl.so.arm64 b/pkg/network/usm/testdata/site-packages/ddtrace/libssl.so.arm64 similarity index 100% rename from pkg/network/usm/testdata/libmmap/libssl.so.arm64 rename to pkg/network/usm/testdata/site-packages/ddtrace/libssl.so.arm64 diff --git a/pkg/network/usm/tests/tracer_classification_test.go b/pkg/network/usm/tests/tracer_classification_test.go index 0accac7d6029a..582425dc6c360 100644 --- a/pkg/network/usm/tests/tracer_classification_test.go +++ b/pkg/network/usm/tests/tracer_classification_test.go @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/require" ddconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/ebpf/ebpftest" "github.com/DataDog/datadog-agent/pkg/network" "github.com/DataDog/datadog-agent/pkg/network/config" @@ -51,7 +52,7 @@ func TestMain(m *testing.M) { func setupTracer(t testing.TB, cfg *config.Config) *tracer.Tracer { if ebpftest.GetBuildMode() == ebpftest.Fentry { - ddconfig.SetFeatures(t, ddconfig.ECSFargate) + ddconfig.SetFeatures(t, env.ECSFargate) // protocol classification not yet supported on fargate cfg.ProtocolClassificationEnabled = false } diff --git a/pkg/network/usm/tests/tracer_usm_linux_test.go b/pkg/network/usm/tests/tracer_usm_linux_test.go index 11e42fc5a9ddc..2da79eadbf80a 100644 --- a/pkg/network/usm/tests/tracer_usm_linux_test.go +++ b/pkg/network/usm/tests/tracer_usm_linux_test.go @@ -308,10 +308,7 @@ func (s *USMSuite) TestIgnoreTLSClassificationIfApplicationProtocolWasDetected() t.Skip("TLS classification platform not supported") } - const srvPort = 9111 - srvAddress := fmt.Sprintf("localhost:%d", srvPort) - - srv := testutil.NewTLSServerWithSpecificVersion(srvAddress, func(conn net.Conn) { + srv := testutil.NewTLSServerWithSpecificVersion("localhost:0", func(conn net.Conn) { defer conn.Close() // Echo back whatever is received _, err := io.Copy(conn, conn) @@ -323,6 +320,11 @@ func (s *USMSuite) TestIgnoreTLSClassificationIfApplicationProtocolWasDetected() done := make(chan struct{}) require.NoError(t, srv.Run(done)) t.Cleanup(func() { close(done) }) + _, srvPortStr, err := net.SplitHostPort(srv.Address()) + require.NoError(t, err) + srvPort, err := strconv.Atoi(srvPortStr) + require.NoError(t, err) + srvPortU16 := uint16(srvPort) tlsConfig := &tls.Config{ MinVersion: tls.VersionTLS12, @@ -397,7 +399,7 @@ func (s *USMSuite) TestIgnoreTLSClassificationIfApplicationProtocolWasDetected() Port: int(clientPort), }, } - conn, err := dialer.Dial("tcp", srvAddress) + conn, err := dialer.Dial("tcp", srv.Address()) require.NoError(t, err) defer conn.Close() tlsConn := tls.Client(conn, tlsConfig) @@ -408,7 +410,7 @@ func (s *USMSuite) TestIgnoreTLSClassificationIfApplicationProtocolWasDetected() Daddr_h: addrHigh, Daddr_l: addrLow, Sport: clientPort, - Dport: srvPort, + Dport: srvPortU16, Metadata: uint32(netebpf.TCP), } protocolValue := netebpf.ProtocolStackWrapper{ @@ -426,7 +428,7 @@ func (s *USMSuite) TestIgnoreTLSClassificationIfApplicationProtocolWasDetected() require.Eventually(t, func() bool { payload := getConnections(t, tr) for _, c := range payload.Conns { - if c.DPort == srvPort || c.SPort == srvPort { + if c.DPort == srvPortU16 || c.SPort == srvPortU16 { return c.ProtocolStack.Contains(protocols.TLS) == tt.shouldBeTLS } } diff --git a/pkg/network/usm/utils/file_registry.go b/pkg/network/usm/utils/file_registry.go index 8666364df427c..5ea71e3838603 100644 --- a/pkg/network/usm/utils/file_registry.go +++ b/pkg/network/usm/utils/file_registry.go @@ -80,6 +80,10 @@ func NewFilePath(procRoot, namespacedPath string, pid uint32) (FilePath, error) type callback func(FilePath) error +// IgnoreCB is just a dummy callback that doesn't do anything +// Meant for testing purposes +var IgnoreCB = func(FilePath) error { return nil } + // NewFileRegistry creates a new `FileRegistry` instance func NewFileRegistry(programName string) *FileRegistry { blocklistByID, err := simplelru.NewLRU[PathIdentifier, string](2000, nil) @@ -118,7 +122,7 @@ var ( // If no current registration exists for the given `PathIdentifier`, we execute // its *activation* callback. Otherwise, we increment the reference counter for // the existing registration if and only if `pid` is new; -func (r *FileRegistry) Register(namespacedPath string, pid uint32, activationCB, deactivationCB callback) error { +func (r *FileRegistry) Register(namespacedPath string, pid uint32, activationCB, deactivationCB, alreadyRegistered callback) error { if activationCB == nil || deactivationCB == nil { return errCallbackIsMissing } @@ -152,6 +156,9 @@ func (r *FileRegistry) Register(namespacedPath string, pid uint32, activationCB, r.byPID[pid][pathID] = struct{}{} } r.telemetry.fileAlreadyRegistered.Add(1) + if alreadyRegistered != nil { + _ = alreadyRegistered(path) + } return ErrPathIsAlreadyRegistered } @@ -210,7 +217,7 @@ func (r *FileRegistry) Unregister(pid uint32) error { r.telemetry.fileUnregisterPathIDNotFound.Add(1) continue } - if reg.unregisterPath(pathID) { + if reg.unregisterPath(FilePath{ID: pathID, PID: pid}) { // we need to clean up our entries as there are no more processes using this ELF delete(r.byID, pathID) } @@ -248,9 +255,29 @@ func (r *FileRegistry) Clear() { return } - for pathID, reg := range r.byID { - reg.unregisterPath(pathID) + for pid, pathIDs := range r.byPID { + for pathID := range pathIDs { + reg, found := r.byID[pathID] + if !found { + continue + } + if reg.unregisterPath(FilePath{ID: pathID, PID: pid}) { + delete(r.byID, pathID) + } + } + } + // reset the registry + r.byPID = make(map[uint32]pathIdentifierSet) + + if len(r.byID) > 0 { + log.Warnf("file_registry: %d files are still registered", len(r.byID)) + for pathID, reg := range r.byID { + // We don't have associated PID here, so we can't provide it + reg.unregisterPath(FilePath{ID: pathID}) + } + r.byID = make(map[PathIdentifier]*registration) } + r.stopped = true } @@ -279,23 +306,23 @@ type registration struct { sampleFilePath string } -// unregister return true if there are no more reference to this registration -func (r *registration) unregisterPath(pathID PathIdentifier) bool { +// unregisterPath return true if there are no more reference to this registration +func (r *registration) unregisterPath(filePath FilePath) bool { currentUniqueProcessesCount := r.uniqueProcessesCount.Dec() if currentUniqueProcessesCount > 0 { return false } if currentUniqueProcessesCount < 0 { - log.Errorf("unregistered %+v too much (current counter %v)", pathID, currentUniqueProcessesCount) + log.Errorf("unregistered %+v too much (current counter %v)", filePath.ID, currentUniqueProcessesCount) r.telemetry.fileUnregisterErrors.Add(1) return true } // currentUniqueProcessesCount is 0, thus we should unregister. - if err := r.deactivationCB(FilePath{ID: pathID}); err != nil { + if err := r.deactivationCB(filePath); err != nil { // Even if we fail here, we have to return true, as best effort methodology. // We cannot handle the failure, and thus we should continue. - log.Errorf("error while unregistering %s : %s", pathID.String(), err) + log.Errorf("error while unregistering %s : %s", filePath.ID.String(), err) r.telemetry.fileUnregisterFailedCB.Add(1) } r.telemetry.fileUnregistered.Add(1) diff --git a/pkg/network/usm/utils/file_registry_test.go b/pkg/network/usm/utils/file_registry_test.go index 9f75ed3168e17..6c8e6cac22a07 100644 --- a/pkg/network/usm/utils/file_registry_test.go +++ b/pkg/network/usm/utils/file_registry_test.go @@ -21,6 +21,96 @@ import ( "github.com/DataDog/datadog-agent/pkg/network/usm/sharedlibraries/testutil" ) +func verifyPIDInFilePath(t *testing.T) func(FilePath) error { + return func(f FilePath) error { + require.NotZerof(t, f.PID, "PID should not be zero") + return nil + } +} + +// TestClearSanity tests the behavior and cleanup of Clear method. +func TestClearSanity(t *testing.T) { + r := newFileRegistry() + + path1, pathID1 := createTempTestFile(t, "foobar") + path2, pathID2 := createTempTestFile(t, "foobar2") + + path1Pids := make([]uint32, 0) + for i := 0; i < 3; i++ { + target := fmt.Sprintf("%s-%d", path1, i) + createSymlink(t, path1, target) + cmd, err := testutil.OpenFromAnotherProcess(t, target) + require.NoError(t, err) + path1Pids = append(path1Pids, uint32(cmd.Process.Pid)) + _ = r.Register(target, uint32(cmd.Process.Pid), verifyPIDInFilePath(t), verifyPIDInFilePath(t), IgnoreCB) + } + path2Pids := make([]uint32, 0) + for i := 0; i < 2; i++ { + target := fmt.Sprintf("%s-%d", path2, i) + createSymlink(t, path2, target) + cmd, err := testutil.OpenFromAnotherProcess(t, target) + require.NoError(t, err) + path2Pids = append(path2Pids, uint32(cmd.Process.Pid)) + _ = r.Register(target, uint32(cmd.Process.Pid), verifyPIDInFilePath(t), verifyPIDInFilePath(t), IgnoreCB) + } + + assert.Len(t, r.byPID, len(path1Pids)+len(path2Pids)) + for _, pid := range path1Pids { + assert.Contains(t, r.byPID, pid) + } + for _, pid := range path2Pids { + assert.Contains(t, r.byPID, pid) + } + assert.Len(t, r.byID, 2) + assert.Contains(t, r.byID, pathID1) + assert.Contains(t, r.byID, pathID2) + + r.Clear() + + // Verify empty registry + assert.Empty(t, r.byPID) + assert.Empty(t, r.byID) + assert.True(t, r.stopped) +} + +// TestClearLeakedPathID tests that the registry can handle a leaked pathID, that does not have a corresponding PID. +func TestClearLeakedPathID(t *testing.T) { + r := newFileRegistry() + + path1, pathID1 := createTempTestFile(t, "foobar") + path2, pathID2 := createTempTestFile(t, "foobar2") + + path1Pids := make([]uint32, 0) + for i := 0; i < 3; i++ { + target := fmt.Sprintf("%s-%d", path1, i) + createSymlink(t, path1, target) + cmd, err := testutil.OpenFromAnotherProcess(t, target) + require.NoError(t, err) + path1Pids = append(path1Pids, uint32(cmd.Process.Pid)) + _ = r.Register(target, uint32(cmd.Process.Pid), verifyPIDInFilePath(t), verifyPIDInFilePath(t), IgnoreCB) + } + + assert.Len(t, r.byPID, len(path1Pids)) + for _, pid := range path1Pids { + assert.Contains(t, r.byPID, pid) + } + assert.Len(t, r.byID, 1) + assert.Contains(t, r.byID, pathID1) + + r.byID[pathID2] = r.newRegistration(path2, func(f FilePath) error { + require.Zerof(t, f.PID, "PID should be zero, as there was no PID associated with this pathID") + return nil + }) + assert.Contains(t, r.byID, pathID2) + + r.Clear() + + // Verify empty registry + assert.Empty(t, r.byPID) + assert.Empty(t, r.byID) + assert.True(t, r.stopped) +} + func TestRegister(t *testing.T) { registerRecorder := new(CallbackRecorder) @@ -30,7 +120,7 @@ func TestRegister(t *testing.T) { pid := uint32(cmd.Process.Pid) r := newFileRegistry() - require.NoError(t, r.Register(path, pid, registerRecorder.Callback(), IgnoreCB)) + require.NoError(t, r.Register(path, pid, registerRecorder.Callback(), IgnoreCB, IgnoreCB)) assert.Equal(t, 1, registerRecorder.CallsForPathID(pathID)) assert.Contains(t, r.GetRegisteredProcesses(), pid) @@ -44,6 +134,9 @@ func TestMultiplePIDsSharingSameFile(t *testing.T) { unregisterRecorder := new(CallbackRecorder) unregisterCallback := unregisterRecorder.Callback() + alreadyRegisteredRecorder := new(CallbackRecorder) + alreadyRegisteredCallback := alreadyRegisteredRecorder.Callback() + r := newFileRegistry() path, pathID := createTempTestFile(t, "foobar") @@ -56,8 +149,8 @@ func TestMultiplePIDsSharingSameFile(t *testing.T) { pid2 := uint32(cmd2.Process.Pid) // Trying to register the same file twice from different PIDs - require.NoError(t, r.Register(path, pid1, registerCallback, unregisterCallback)) - require.Equal(t, ErrPathIsAlreadyRegistered, r.Register(path, pid2, registerCallback, unregisterCallback)) + require.NoError(t, r.Register(path, pid1, registerCallback, unregisterCallback, alreadyRegisteredCallback)) + require.Equal(t, ErrPathIsAlreadyRegistered, r.Register(path, pid2, registerCallback, unregisterCallback, alreadyRegisteredCallback)) // Assert that the callback should execute only *once* assert.Equal(t, 1, registerRecorder.CallsForPathID(pathID)) @@ -66,6 +159,9 @@ func TestMultiplePIDsSharingSameFile(t *testing.T) { assert.Contains(t, r.GetRegisteredProcesses(), pid1) assert.Contains(t, r.GetRegisteredProcesses(), pid2) + // Assert that the callback should execute only *once* + assert.Equal(t, 1, alreadyRegisteredRecorder.CallsForPathID(pathID)) + // Assert that the first call to `Unregister` (from pid1) doesn't trigger // the callback but removes pid1 from the list require.NoError(t, r.Unregister(pid1)) @@ -99,8 +195,8 @@ func TestRepeatedRegistrationsFromSamePID(t *testing.T) { require.NoError(t, err) pid := uint32(cmd.Process.Pid) - require.NoError(t, r.Register(path, pid, registerCallback, unregisterCallback)) - require.Equal(t, ErrPathIsAlreadyRegistered, r.Register(path, pid, registerCallback, unregisterCallback)) + require.NoError(t, r.Register(path, pid, registerCallback, unregisterCallback, IgnoreCB)) + require.Equal(t, ErrPathIsAlreadyRegistered, r.Register(path, pid, registerCallback, unregisterCallback, IgnoreCB)) require.NoError(t, r.Unregister(pid)) // Assert that despite multiple calls to `Register` from the same PID we @@ -122,7 +218,7 @@ func TestFailedRegistration(t *testing.T) { require.NoError(t, err) pid := uint32(cmd.Process.Pid) - require.NoError(t, r.Register(path, pid, registerCallback, IgnoreCB)) + require.NoError(t, r.Register(path, pid, registerCallback, IgnoreCB, IgnoreCB)) // First let's assert that the callback was executed once, but there are no // registered processes because the registration should have failed @@ -130,7 +226,7 @@ func TestFailedRegistration(t *testing.T) { assert.Empty(t, r.GetRegisteredProcesses()) // Now let's try to register the same process again - require.Equal(t, errPathIsBlocked, r.Register(path, pid, registerCallback, IgnoreCB)) + require.Equal(t, errPathIsBlocked, r.Register(path, pid, registerCallback, IgnoreCB, IgnoreCB)) // Assert that the number of callback executions hasn't changed for this pathID // This is because we have block-listed this file @@ -150,7 +246,7 @@ func TestFilePathInCallbackArgument(t *testing.T) { pid := cmd.Process.Pid r := newFileRegistry() - require.NoError(t, r.Register(path, uint32(pid), callback, callback)) + require.NoError(t, r.Register(path, uint32(pid), callback, callback, IgnoreCB)) // Assert that the callback paths match the pattern //root/ expectedPath := filepath.Join(r.procRoot, strconv.Itoa(pid), "root", path) @@ -182,7 +278,7 @@ func TestRelativeFilePathInCallbackArgument(t *testing.T) { pid := cmd.Process.Pid r := newFileRegistry() - require.NoError(t, r.Register(relpath, uint32(pid), callback, callback)) + require.NoError(t, r.Register(relpath, uint32(pid), callback, callback, IgnoreCB)) // Assert that the callback paths match the pattern //cwd/. // We need to avoid `filepath.Join` for the last component since using @@ -204,6 +300,11 @@ func createTempTestFile(t *testing.T, name string) (string, PathIdentifier) { return path, pathID } +func createSymlink(t *testing.T, old, new string) { + require.NoError(t, os.Symlink(old, new)) + t.Cleanup(func() { require.NoError(t, os.Remove(new)) }) +} + func newFileRegistry() *FileRegistry { // Ensure that tests relying on telemetry data will always have a clean slate telemetry.Clear() diff --git a/pkg/network/usm/utils/testutils.go b/pkg/network/usm/utils/testutils.go index e1b57527ca952..9622c0486a999 100644 --- a/pkg/network/usm/utils/testutils.go +++ b/pkg/network/usm/utils/testutils.go @@ -9,10 +9,6 @@ package utils import "sync" -// IgnoreCB is just a dummy callback that doesn't do anything -// Meant for testing purposes -var IgnoreCB = func(FilePath) error { return nil } - // CallbackRecorder is meant to assist with *testing* the `FileRegistry` code // as well as code interacting with it such as `sharedlibraries.Watcher`. // A callback "mock" can be generated by calling `Callback()`, which essentially diff --git a/pkg/networkpath/payload/pathevent.go b/pkg/networkpath/payload/pathevent.go index 6246b0eb8a46f..25fa9f748cffc 100644 --- a/pkg/networkpath/payload/pathevent.go +++ b/pkg/networkpath/payload/pathevent.go @@ -20,6 +20,16 @@ const ( ProtocolUDP Protocol = "UDP" ) +// PathOrigin origin of the path e.g. network_traffic, network_path_integration +type PathOrigin string + +const ( + // PathOriginNetworkTraffic correspond to traffic from network traffic (NPM). + PathOriginNetworkTraffic PathOrigin = "network_traffic" + // PathOriginNetworkPathIntegration correspond to traffic from network_path integration. + PathOriginNetworkPathIntegration PathOrigin = "network_path_integration" +) + // NetworkPathHop encapsulates the data for a single // hop within a path type NetworkPathHop struct { @@ -54,7 +64,8 @@ type NetworkPathDestination struct { type NetworkPath struct { Timestamp int64 `json:"timestamp"` Namespace string `json:"namespace"` // namespace used to resolve NDM resources - PathID string `json:"path_id"` + PathtraceID string `json:"pathtrace_id"` + Origin PathOrigin `json:"origin"` Protocol Protocol `json:"protocol"` Source NetworkPathSource `json:"source"` Destination NetworkPathDestination `json:"destination"` diff --git a/pkg/networkpath/payload/utils.go b/pkg/networkpath/payload/utils.go new file mode 100644 index 0000000000000..2b576e5b80edd --- /dev/null +++ b/pkg/networkpath/payload/utils.go @@ -0,0 +1,13 @@ +// 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 2024-present Datadog, Inc. + +package payload + +import "github.com/google/uuid" + +// NewPathtraceID creates a new pathtrace id +func NewPathtraceID() string { + return uuid.New().String() +} diff --git a/pkg/networkpath/telemetry/telemetry.go b/pkg/networkpath/telemetry/telemetry.go index 1066bcfc14cc6..3c47773b9bc50 100644 --- a/pkg/networkpath/telemetry/telemetry.go +++ b/pkg/networkpath/telemetry/telemetry.go @@ -17,6 +17,7 @@ import ( ) // NetworkPathCollectorType represent the source of the network path data e.g. network_path_integration +// TODO: DEPRECATED in favour of Path.Origin type NetworkPathCollectorType string // CollectorTypeNetworkPathIntegration correspond to the Network Path Integration source type @@ -26,14 +27,22 @@ const CollectorTypeNetworkPathIntegration NetworkPathCollectorType = "network_pa const CollectorTypeNetworkPathCollector NetworkPathCollectorType = "network_path_collector" // SubmitNetworkPathTelemetry submits Network Path related telemetry -func SubmitNetworkPathTelemetry(sender metricsender.MetricSender, path payload.NetworkPath, pathSource NetworkPathCollectorType, checkDuration time.Duration, checkInterval time.Duration, tags []string) { +func SubmitNetworkPathTelemetry(sender metricsender.MetricSender, path payload.NetworkPath, checkDuration time.Duration, checkInterval time.Duration, tags []string) { destPortTag := "unspecified" if path.Destination.Port > 0 { destPortTag = strconv.Itoa(int(path.Destination.Port)) } + var pathSource NetworkPathCollectorType + if path.Origin == payload.PathOriginNetworkTraffic { + pathSource = CollectorTypeNetworkPathCollector + } else { + pathSource = CollectorTypeNetworkPathIntegration + } newTags := append(utils.CopyStrings(tags), []string{ "collector:" + string(pathSource), + "origin:" + string(path.Origin), "protocol:" + string(path.Protocol), + "destination_ip:" + path.Destination.IPAddress, "destination_hostname:" + path.Destination.Hostname, "destination_port:" + destPortTag, }...) diff --git a/pkg/networkpath/telemetry/telemetry_test.go b/pkg/networkpath/telemetry/telemetry_test.go index 0a6ac97f25446..ce765c6046bb2 100644 --- a/pkg/networkpath/telemetry/telemetry_test.go +++ b/pkg/networkpath/telemetry/telemetry_test.go @@ -20,8 +20,10 @@ func TestSubmitNetworkPathTelemetry(t *testing.T) { expectedTags := []string{ "collector:network_path_integration", "destination_hostname:abc", + "destination_ip:10.0.0.1", "destination_port:unspecified", "foo:bar", + "origin:network_path_integration", "protocol:UDP", "tag2:val2", } @@ -36,7 +38,8 @@ func TestSubmitNetworkPathTelemetry(t *testing.T) { { name: "with hops and interval", path: payload.NetworkPath{ - Destination: payload.NetworkPathDestination{Hostname: "abc"}, + Origin: payload.PathOriginNetworkPathIntegration, + Destination: payload.NetworkPathDestination{Hostname: "abc", IPAddress: "10.0.0.1"}, Protocol: payload.ProtocolUDP, Hops: []payload.NetworkPathHop{ {Hostname: "hop_1", IPAddress: "1.1.1.1"}, @@ -82,7 +85,8 @@ func TestSubmitNetworkPathTelemetry(t *testing.T) { { name: "with last hop successful", path: payload.NetworkPath{ - Destination: payload.NetworkPathDestination{Hostname: "abc"}, + Origin: payload.PathOriginNetworkPathIntegration, + Destination: payload.NetworkPathDestination{Hostname: "abc", IPAddress: "10.0.0.1"}, Protocol: payload.ProtocolUDP, Hops: []payload.NetworkPathHop{ {Hostname: "hop_1", IPAddress: "1.1.1.1"}, @@ -128,7 +132,8 @@ func TestSubmitNetworkPathTelemetry(t *testing.T) { { name: "no hops and no interval", path: payload.NetworkPath{ - Destination: payload.NetworkPathDestination{Hostname: "abc"}, + Origin: payload.PathOriginNetworkPathIntegration, + Destination: payload.NetworkPathDestination{Hostname: "abc", IPAddress: "10.0.0.1"}, Protocol: payload.ProtocolUDP, Hops: []payload.NetworkPathHop{}, }, @@ -154,7 +159,7 @@ func TestSubmitNetworkPathTelemetry(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { sender := &metricsender.MockMetricSender{} - SubmitNetworkPathTelemetry(sender, tt.path, CollectorTypeNetworkPathIntegration, tt.checkDuration, tt.checkInterval, tt.tags) + SubmitNetworkPathTelemetry(sender, tt.path, tt.checkDuration, tt.checkInterval, tt.tags) assert.Equal(t, tt.expectedMetrics, sender.Metrics) }) } diff --git a/pkg/networkpath/traceroute/runner.go b/pkg/networkpath/traceroute/runner.go index fc7ef3b9af585..940ea9a7344e7 100644 --- a/pkg/networkpath/traceroute/runner.go +++ b/pkg/networkpath/traceroute/runner.go @@ -30,8 +30,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/util/hostname" "github.com/DataDog/datadog-agent/pkg/util/kernel" "github.com/DataDog/datadog-agent/pkg/util/log" - - "github.com/google/uuid" ) // TODO: are these good defaults? @@ -222,11 +220,10 @@ func (r *Runner) runTCP(cfg Config, hname string, target net.IP, maxTTL uint8, t } func (r *Runner) processTCPResults(res *tcp.Results, hname string, destinationHost string, destinationPort uint16, destinationIP net.IP) (payload.NetworkPath, error) { - pathID := uuid.New().String() traceroutePath := payload.NetworkPath{ - PathID: pathID, - Protocol: payload.ProtocolTCP, - Timestamp: time.Now().UnixMilli(), + PathtraceID: payload.NewPathtraceID(), + Protocol: payload.ProtocolTCP, + Timestamp: time.Now().UnixMilli(), Source: payload.NetworkPathSource{ Hostname: hname, NetworkID: r.networkID, @@ -285,12 +282,10 @@ func (r *Runner) processUDPResults(res *results.Results, hname string, destinati probe *results.Probe } - pathID := uuid.New().String() - traceroutePath := payload.NetworkPath{ - PathID: pathID, - Protocol: payload.ProtocolUDP, - Timestamp: time.Now().UnixMilli(), + PathtraceID: payload.NewPathtraceID(), + Protocol: payload.ProtocolUDP, + Timestamp: time.Now().UnixMilli(), Source: payload.NetworkPathSource{ Hostname: hname, NetworkID: r.networkID, diff --git a/pkg/obfuscate/go.mod b/pkg/obfuscate/go.mod index 7396829b2dd4f..80da0db8971b4 100644 --- a/pkg/obfuscate/go.mod +++ b/pkg/obfuscate/go.mod @@ -17,7 +17,7 @@ require ( github.com/dustin/go-humanize v1.0.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sys v0.24.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/obfuscate/go.sum b/pkg/obfuscate/go.sum index 151afb1a0c5a3..b0abab16649ad 100644 --- a/pkg/obfuscate/go.sum +++ b/pkg/obfuscate/go.sum @@ -45,8 +45,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -57,8 +57,8 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= diff --git a/pkg/obfuscate/ip_address.go b/pkg/obfuscate/ip_address.go index 3c80294b5578e..7639453bd958b 100644 --- a/pkg/obfuscate/ip_address.go +++ b/pkg/obfuscate/ip_address.go @@ -57,8 +57,8 @@ func splitPrefix(raw string) (prefix, after string) { // quantizeIP quantizes the ip address in the provided string, only if it exactly matches an ip with an optional port // if the string is not an ip then empty string is returned func quantizeIP(raw string) string { - prefix, raw := splitPrefix(raw) - host, port, suffix := parseIPAndPort(raw) + prefix, rawNoPrefix := splitPrefix(raw) + host, port, suffix := parseIPAndPort(rawNoPrefix) if host == "" { // not an ip address return raw @@ -153,7 +153,7 @@ func parseIPv4(s string, sep byte) (parsed bool, lastIndex int) { val = 0 digLen = 0 } else { - if pos == 3 { + if pos == 3 && digLen > 0 { fields[3] = uint8(val) return true, i } diff --git a/pkg/obfuscate/ip_address_test.go b/pkg/obfuscate/ip_address_test.go index fcec7dcf917e5..b037f9c37183d 100644 --- a/pkg/obfuscate/ip_address_test.go +++ b/pkg/obfuscate/ip_address_test.go @@ -39,15 +39,24 @@ func TestQuantizePeerIpAddresses(t *testing.T) { {"[fe80::1ff:fe23:4567:890a]:8080", "blocked-ip-address:8080"}, {"192.168.1.1:1234", "blocked-ip-address:1234"}, {"dnspoll:///10.21.120.145:6400", "dnspoll:///blocked-ip-address:6400"}, + {"dnspoll:///abc.cluster.local:50051", "dnspoll:///abc.cluster.local:50051"}, {"http://10.21.120.145:6400", "http://blocked-ip-address:6400"}, {"https://10.21.120.145:6400", "https://blocked-ip-address:6400"}, {"192.168.1.1:1234,10.23.1.1:53,10.23.1.1,fe80::1ff:fe23:4567:890a,foo.dog", "blocked-ip-address:1234,blocked-ip-address:53,blocked-ip-address,foo.dog"}, {"http://172.24.160.151:8091,172.24.163.33:8091,172.24.164.111:8091,172.24.165.203:8091,172.24.168.235:8091,172.24.170.130:8091", "http://blocked-ip-address:8091,blocked-ip-address:8091"}, {"10-60-160-172.my-service.namespace.svc.abc.cluster.local", "blocked-ip-address.my-service.namespace.svc.abc.cluster.local"}, {"ip-10-152-4-129.ec2.internal", "ip-blocked-ip-address.ec2.internal"}, + {"1-foo", "1-foo"}, + {"1-2-foo", "1-2-foo"}, + {"1-2-3-foo", "1-2-3-foo"}, + {"1-2-3-999", "1-2-3-999"}, + {"1-2-999-foo", "1-2-999-foo"}, + {"1-2-3-999-foo", "1-2-3-999-foo"}, + {"1-2-3-4-foo", "blocked-ip-address-foo"}, + {"7-55-2-app.agent.datadoghq.com", "7-55-2-app.agent.datadoghq.com"}, } for _, tc := range testCases { - t.Run("", func(t *testing.T) { + t.Run(tc.original, func(t *testing.T) { assert.Equal(t, tc.quantized, QuantizePeerIPAddresses(tc.original)) }) } diff --git a/pkg/orchestrator/config/config.go b/pkg/orchestrator/config/config.go index c1dca518ac1c0..870b6e0e5ebf3 100644 --- a/pkg/orchestrator/config/config.go +++ b/pkg/orchestrator/config/config.go @@ -14,6 +14,7 @@ import ( "time" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/config/utils" "github.com/DataDog/datadog-agent/pkg/orchestrator/redact" apicfg "github.com/DataDog/datadog-agent/pkg/process/util/api/config" @@ -207,7 +208,7 @@ func IsOrchestratorECSExplorerEnabled() bool { return false } - if config.IsECS() || config.IsECSFargate() { + if env.IsECS() || env.IsECSFargate() { return true } diff --git a/pkg/process/checks/checks.go b/pkg/process/checks/checks.go index de19ee22f0e09..139abb92720dd 100644 --- a/pkg/process/checks/checks.go +++ b/pkg/process/checks/checks.go @@ -13,6 +13,7 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/comp/networkpath/npcollector" ddconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/log" ) @@ -132,7 +133,7 @@ func canEnableContainerChecks(config ddconfig.Reader, displayFeatureWarning bool if config.GetBool("process_config.process_collection.enabled") { return false } - if !ddconfig.IsAnyContainerFeaturePresent() { + if !env.IsAnyContainerFeaturePresent() { if displayFeatureWarning { _ = log.Warn("Disabled container checks because no container environment detected (see list of detected features in `agent status`)") } diff --git a/pkg/process/checks/enable_checks_containerized_test.go b/pkg/process/checks/enable_checks_containerized_test.go index ee9b26c4bde8b..aad1d013d9500 100644 --- a/pkg/process/checks/enable_checks_containerized_test.go +++ b/pkg/process/checks/enable_checks_containerized_test.go @@ -19,6 +19,7 @@ import ( "github.com/DataDog/datadog-agent/comp/networkpath/npcollector" "github.com/DataDog/datadog-agent/comp/networkpath/npcollector/npcollectorimpl" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" configmock "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/util/flavor" "github.com/DataDog/datadog-agent/pkg/util/fxutil" @@ -38,9 +39,9 @@ func TestContainerCheck(t *testing.T) { cfg.SetWithoutSource("process_config.process_collection.enabled", false) cfg.SetWithoutSource("process_config.container_collection.enabled", true) cfg.SetWithoutSource("process_config.disable_realtime_checks", false) - config.SetFeatures(t, config.Docker) + config.SetFeatures(t, env.Docker) - enabledChecks := getEnabledChecks(t, cfg, config.MockSystemProbe(t), deps.WMeta, deps.NpCollector) + enabledChecks := getEnabledChecks(t, cfg, configmock.NewSystemProbe(t), deps.WMeta, deps.NpCollector) assertContainsCheck(t, enabledChecks, ContainerCheckName) assertContainsCheck(t, enabledChecks, RTContainerCheckName) assertNotContainsCheck(t, enabledChecks, ProcessCheckName) @@ -53,9 +54,9 @@ func TestContainerCheck(t *testing.T) { cfg.SetWithoutSource("process_config.process_collection.enabled", false) cfg.SetWithoutSource("process_config.container_collection.enabled", true) cfg.SetWithoutSource("process_config.disable_realtime_checks", true) - config.SetFeatures(t, config.Docker) + config.SetFeatures(t, env.Docker) - enabledChecks := getEnabledChecks(t, cfg, config.MockSystemProbe(t), deps.WMeta, deps.NpCollector) + enabledChecks := getEnabledChecks(t, cfg, configmock.NewSystemProbe(t), deps.WMeta, deps.NpCollector) assertContainsCheck(t, enabledChecks, ContainerCheckName) assertNotContainsCheck(t, enabledChecks, RTContainerCheckName) }) @@ -67,7 +68,7 @@ func TestContainerCheck(t *testing.T) { cfg.SetWithoutSource("process_config.process_collection.enabled", false) cfg.SetWithoutSource("process_config.container_collection.enabled", true) - enabledChecks := getEnabledChecks(t, cfg, config.MockSystemProbe(t), deps.WMeta, deps.NpCollector) + enabledChecks := getEnabledChecks(t, cfg, configmock.NewSystemProbe(t), deps.WMeta, deps.NpCollector) assertNotContainsCheck(t, enabledChecks, ContainerCheckName) assertNotContainsCheck(t, enabledChecks, RTContainerCheckName) @@ -79,9 +80,9 @@ func TestContainerCheck(t *testing.T) { cfg := configmock.New(t) cfg.SetWithoutSource("process_config.process_collection.enabled", true) cfg.SetWithoutSource("process_config.container_collection.enabled", true) - config.SetFeatures(t, config.Docker) + config.SetFeatures(t, env.Docker) - enabledChecks := getEnabledChecks(t, cfg, config.MockSystemProbe(t), deps.WMeta, deps.NpCollector) + enabledChecks := getEnabledChecks(t, cfg, configmock.NewSystemProbe(t), deps.WMeta, deps.NpCollector) assertContainsCheck(t, enabledChecks, ProcessCheckName) assertNotContainsCheck(t, enabledChecks, ContainerCheckName) assertNotContainsCheck(t, enabledChecks, RTContainerCheckName) @@ -91,11 +92,11 @@ func TestContainerCheck(t *testing.T) { // when run in core agent mode is enabled t.Run("run in core agent", func(t *testing.T) { deps := createDeps(t) - cfg, scfg := configmock.New(t), config.MockSystemProbe(t) + cfg, scfg := configmock.New(t), configmock.NewSystemProbe(t) cfg.SetWithoutSource("process_config.process_collection.enabled", false) cfg.SetWithoutSource("process_config.container_collection.enabled", true) cfg.SetWithoutSource("process_config.run_in_core_agent.enabled", true) - config.SetFeatures(t, config.Docker) + config.SetFeatures(t, env.Docker) flavor.SetFlavor("process_agent") enabledChecks := getEnabledChecks(t, cfg, scfg, deps.WMeta, deps.NpCollector) @@ -134,9 +135,9 @@ func TestDisableRealTime(t *testing.T) { mockConfig := configmock.New(t) mockConfig.SetWithoutSource("process_config.disable_realtime_checks", tc.disableRealtime) mockConfig.SetWithoutSource("process_config.process_discovery.enabled", false) // Not an RT check so we don't care - config.SetFeatures(t, config.Docker) + config.SetFeatures(t, env.Docker) - enabledChecks := getEnabledChecks(t, mockConfig, config.MockSystemProbe(t), deps.WMeta, deps.NpCollector) + enabledChecks := getEnabledChecks(t, mockConfig, configmock.NewSystemProbe(t), deps.WMeta, deps.NpCollector) assert.EqualValues(tc.expectedChecks, enabledChecks) }) } @@ -151,8 +152,7 @@ type deps struct { func createDeps(t *testing.T) deps { return fxutil.Test[deps](t, core.MockBundle(), - workloadmetafxmock.MockModule(), - fx.Supply(workloadmeta.NewParams()), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), npcollectorimpl.MockModule(), ) } diff --git a/pkg/process/checks/enabled_checks_linux_test.go b/pkg/process/checks/enabled_checks_linux_test.go index 8201f2203d314..f1e6396a14816 100644 --- a/pkg/process/checks/enabled_checks_linux_test.go +++ b/pkg/process/checks/enabled_checks_linux_test.go @@ -10,7 +10,6 @@ package checks import ( "testing" - "github.com/DataDog/datadog-agent/pkg/config" configmock "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/util/flavor" ) @@ -20,7 +19,7 @@ func TestProcessEventsCheckEnabled(t *testing.T) { t.Run("default", func(t *testing.T) { cfg := configmock.New(t) - enabledChecks := getEnabledChecks(t, cfg, config.MockSystemProbe(t), deps.WMeta, deps.NpCollector) + enabledChecks := getEnabledChecks(t, cfg, configmock.NewSystemProbe(t), deps.WMeta, deps.NpCollector) assertNotContainsCheck(t, enabledChecks, ProcessEventsCheckName) }) @@ -28,7 +27,7 @@ func TestProcessEventsCheckEnabled(t *testing.T) { cfg := configmock.New(t) cfg.SetWithoutSource("process_config.event_collection.enabled", true) - enabledChecks := getEnabledChecks(t, cfg, config.MockSystemProbe(t), deps.WMeta, deps.NpCollector) + enabledChecks := getEnabledChecks(t, cfg, configmock.NewSystemProbe(t), deps.WMeta, deps.NpCollector) assertContainsCheck(t, enabledChecks, ProcessEventsCheckName) }) @@ -36,7 +35,7 @@ func TestProcessEventsCheckEnabled(t *testing.T) { cfg := configmock.New(t) cfg.SetWithoutSource("process_config.event_collection.enabled", false) - enabledChecks := getEnabledChecks(t, cfg, config.MockSystemProbe(t), deps.WMeta, deps.NpCollector) + enabledChecks := getEnabledChecks(t, cfg, configmock.NewSystemProbe(t), deps.WMeta, deps.NpCollector) assertNotContainsCheck(t, enabledChecks, ProcessEventsCheckName) }) } @@ -49,7 +48,7 @@ func TestConnectionsCheckLinux(t *testing.T) { // Make sure the connections check is disabled on the core agent // and enabled in the process agent when process checks run in core agent t.Run("run in core agent", func(t *testing.T) { - cfg, scfg := configmock.New(t), config.MockSystemProbe(t) + cfg, scfg := configmock.New(t), configmock.NewSystemProbe(t) cfg.SetWithoutSource("process_config.process_collection.enabled", true) cfg.SetWithoutSource("process_config.run_in_core_agent.enabled", true) scfg.SetWithoutSource("network_config.enabled", true) @@ -73,7 +72,7 @@ func TestProcessCheckLinux(t *testing.T) { // Make sure process checks run on the core agent only // when run in core agent mode is enabled t.Run("run in core agent", func(t *testing.T) { - cfg, scfg := configmock.New(t), config.MockSystemProbe(t) + cfg, scfg := configmock.New(t), configmock.NewSystemProbe(t) cfg.SetWithoutSource("process_config.process_collection.enabled", true) cfg.SetWithoutSource("process_config.run_in_core_agent.enabled", true) @@ -95,7 +94,7 @@ func TestProcessDiscoveryLinux(t *testing.T) { // Make sure process discovery checks run on the core agent only // when run in core agent mode is enabled t.Run("run in core agent", func(t *testing.T) { - cfg, scfg := configmock.New(t), config.MockSystemProbe(t) + cfg, scfg := configmock.New(t), configmock.NewSystemProbe(t) cfg.SetWithoutSource("process_config.process_collection.enabled", false) cfg.SetWithoutSource("process_config.process_discovery.enabled", true) cfg.SetWithoutSource("process_config.run_in_core_agent.enabled", true) diff --git a/pkg/process/checks/enabled_checks_test.go b/pkg/process/checks/enabled_checks_test.go index 6cf5805f96916..7b4aaea81c38f 100644 --- a/pkg/process/checks/enabled_checks_test.go +++ b/pkg/process/checks/enabled_checks_test.go @@ -53,7 +53,7 @@ func TestProcessDiscovery(t *testing.T) { // Make sure the process_discovery check can be enabled t.Run("enabled", func(t *testing.T) { - cfg, sysprobeCfg := configmock.New(t), config.MockSystemProbe(t) + cfg, sysprobeCfg := configmock.New(t), configmock.NewSystemProbe(t) cfg.SetWithoutSource("process_config.process_discovery.enabled", true) enabledChecks := getEnabledChecks(t, cfg, sysprobeCfg, deps.WMeta, deps.NpCollector) assertContainsCheck(t, enabledChecks, DiscoveryCheckName) @@ -61,7 +61,7 @@ func TestProcessDiscovery(t *testing.T) { // Make sure the process_discovery check can be disabled t.Run("disabled", func(t *testing.T) { - cfg, scfg := configmock.New(t), config.MockSystemProbe(t) + cfg, scfg := configmock.New(t), configmock.NewSystemProbe(t) cfg.SetWithoutSource("process_config.process_discovery.enabled", false) enabledChecks := getEnabledChecks(t, cfg, scfg, deps.WMeta, deps.NpCollector) assertNotContainsCheck(t, enabledChecks, DiscoveryCheckName) @@ -69,7 +69,7 @@ func TestProcessDiscovery(t *testing.T) { // Make sure the process and process_discovery checks are mutually exclusive t.Run("mutual exclusion", func(t *testing.T) { - cfg, scfg := configmock.New(t), config.MockSystemProbe(t) + cfg, scfg := configmock.New(t), configmock.NewSystemProbe(t) cfg.SetWithoutSource("process_config.process_discovery.enabled", true) cfg.SetWithoutSource("process_config.process_collection.enabled", true) enabledChecks := getEnabledChecks(t, cfg, scfg, deps.WMeta, deps.NpCollector) @@ -80,7 +80,7 @@ func TestProcessDiscovery(t *testing.T) { func TestProcessCheck(t *testing.T) { deps := createProcessCheckDeps(t) t.Run("disabled", func(t *testing.T) { - cfg, scfg := configmock.New(t), config.MockSystemProbe(t) + cfg, scfg := configmock.New(t), configmock.NewSystemProbe(t) cfg.SetWithoutSource("process_config.process_collection.enabled", false) enabledChecks := getEnabledChecks(t, cfg, scfg, deps.WMeta, deps.NpCollector) assertNotContainsCheck(t, enabledChecks, ProcessCheckName) @@ -88,7 +88,7 @@ func TestProcessCheck(t *testing.T) { // Make sure the process check can be enabled t.Run("enabled", func(t *testing.T) { - cfg, scfg := configmock.New(t), config.MockSystemProbe(t) + cfg, scfg := configmock.New(t), configmock.NewSystemProbe(t) cfg.SetWithoutSource("process_config.process_collection.enabled", true) enabledChecks := getEnabledChecks(t, cfg, scfg, deps.WMeta, deps.NpCollector) assertContainsCheck(t, enabledChecks, ProcessCheckName) @@ -101,7 +101,7 @@ func TestConnectionsCheck(t *testing.T) { defer flavor.SetFlavor(originalFlavor) t.Run("enabled", func(t *testing.T) { - cfg, scfg := configmock.New(t), config.MockSystemProbe(t) + cfg, scfg := configmock.New(t), configmock.NewSystemProbe(t) scfg.SetWithoutSource("network_config.enabled", true) scfg.SetWithoutSource("system_probe_config.enabled", true) flavor.SetFlavor("process_agent") @@ -115,7 +115,7 @@ func TestConnectionsCheck(t *testing.T) { }) t.Run("disabled", func(t *testing.T) { - cfg, scfg := configmock.New(t), config.MockSystemProbe(t) + cfg, scfg := configmock.New(t), configmock.NewSystemProbe(t) scfg.SetWithoutSource("network_config.enabled", false) enabledChecks := getEnabledChecks(t, cfg, scfg, deps.WMeta, deps.NpCollector) @@ -131,9 +131,8 @@ type ProcessCheckDeps struct { func createProcessCheckDeps(t *testing.T) ProcessCheckDeps { return fxutil.Test[ProcessCheckDeps](t, - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), npcollectorimpl.MockModule(), ) } diff --git a/pkg/process/checks/host_info_test.go b/pkg/process/checks/host_info_test.go index 28b70d499abf2..ad19147d649b8 100644 --- a/pkg/process/checks/host_info_test.go +++ b/pkg/process/checks/host_info_test.go @@ -11,6 +11,7 @@ import ( "fmt" "os" "os/exec" + "runtime" "testing" "time" @@ -27,6 +28,9 @@ import ( ) func TestGetHostname(t *testing.T) { + if os.Getenv("CI") == "true" && runtime.GOOS == "darwin" { + t.Skip("TestGetHostname is known to fail on the macOS Gitlab runners because of the already running Agent") + } cfg := configmock.New(t) ctx := context.Background() h, err := getHostname(ctx, cfg.GetString("process_config.dd_agent_bin"), 0) @@ -84,6 +88,9 @@ func TestGetHostnameFromCmd(t *testing.T) { } func TestResolveHostname(t *testing.T) { + if os.Getenv("CI") == "true" && runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" { + t.Skip("TestResolveHostname is known to fail on the macOS Gitlab runners because of the already running Agent") + } osHostname, err := os.Hostname() require.NoError(t, err, "failed to get hostname from OS") diff --git a/pkg/process/checks/net_test.go b/pkg/process/checks/net_test.go index 18aab4ef443c3..b15fa65f1d34b 100644 --- a/pkg/process/checks/net_test.go +++ b/pkg/process/checks/net_test.go @@ -14,7 +14,7 @@ import ( model "github.com/DataDog/agent-payload/v5/process" - ddconfig "github.com/DataDog/datadog-agent/pkg/config" + configmock "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/network/dns" "github.com/DataDog/datadog-agent/pkg/process/metadata/parser" "github.com/DataDog/datadog-agent/pkg/process/procutil" @@ -637,7 +637,7 @@ func TestNetworkConnectionTagsWithService(t *testing.T) { Cmdline: []string{"./my-server.sh"}, }, } - mockConfig := ddconfig.MockSystemProbe(t) + mockConfig := configmock.NewSystemProbe(t) mockConfig.SetWithoutSource("system_probe_config.process_service_inference.enabled", true) maxConnsPerMessage := 1 diff --git a/pkg/process/checks/process_discovery_check.go b/pkg/process/checks/process_discovery_check.go index 8ba3b049d2b89..c5a3b65069b70 100644 --- a/pkg/process/checks/process_discovery_check.go +++ b/pkg/process/checks/process_discovery_check.go @@ -10,6 +10,7 @@ import ( "time" ddconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/flavor" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -64,7 +65,7 @@ func (d *ProcessDiscoveryCheck) IsEnabled() bool { return false } - if ddconfig.IsECSFargate() { + if env.IsECSFargate() { log.Debug("Process discovery is not supported on ECS Fargate") return false } diff --git a/pkg/process/checks/process_test.go b/pkg/process/checks/process_test.go index 78589003e37b4..4512db04f03de 100644 --- a/pkg/process/checks/process_test.go +++ b/pkg/process/checks/process_test.go @@ -83,8 +83,7 @@ func mockContainerProvider(t *testing.T) proccontainers.ContainerProvider { metadataProvider := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) fakeTagger := taggerimpl.SetupFakeTagger(t) diff --git a/pkg/process/metadata/parser/service_windows_test.go b/pkg/process/metadata/parser/service_windows_test.go index 89f6feb51d089..fa49194059515 100644 --- a/pkg/process/metadata/parser/service_windows_test.go +++ b/pkg/process/metadata/parser/service_windows_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/mock" ddconfig "github.com/DataDog/datadog-agent/pkg/config" + configmock "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/process/procutil" "github.com/DataDog/datadog-agent/pkg/util/winutil" ) @@ -105,7 +106,7 @@ func TestWindowsExtractServiceWithSCMReader(t *testing.T) { } t.Run("disabled", func(t *testing.T) { - cfg := ddconfig.MockSystemProbe(t) + cfg := configmock.NewSystemProbe(t) cfg.SetWithoutSource("system_probe_config.process_service_inference.enabled", true) cfg.SetWithoutSource("system_probe_config.process_service_inference.use_windows_service_name", false) @@ -117,7 +118,7 @@ func TestWindowsExtractServiceWithSCMReader(t *testing.T) { }) t.Run("enabled", func(t *testing.T) { - cfg := ddconfig.MockSystemProbe(t) + cfg := configmock.NewSystemProbe(t) cfg.SetWithoutSource("system_probe_config.process_service_inference.use_windows_service_name", true) cfg.SetWithoutSource("system_probe_config.process_service_inference.enabled", true) @@ -131,7 +132,7 @@ func TestWindowsExtractServiceWithSCMReader(t *testing.T) { }) t.Run("enabled, multiple results", func(t *testing.T) { - cfg := ddconfig.MockSystemProbe(t) + cfg := configmock.NewSystemProbe(t) cfg.SetWithoutSource("system_probe_config.process_service_inference.use_windows_service_name", true) cfg.SetWithoutSource("system_probe_config.process_service_inference.enabled", true) @@ -145,7 +146,7 @@ func TestWindowsExtractServiceWithSCMReader(t *testing.T) { }) t.Run("fallback_to_parsing", func(t *testing.T) { - cfg := ddconfig.MockSystemProbe(t) + cfg := configmock.NewSystemProbe(t) cfg.SetWithoutSource("system_probe_config.process_service_inference.use_windows_service_name", true) cfg.SetWithoutSource("system_probe_config.process_service_inference.enabled", true) diff --git a/pkg/process/metadata/workloadmeta/collector/process_test.go b/pkg/process/metadata/workloadmeta/collector/process_test.go index 5670fe0e22945..37824842f6cd3 100644 --- a/pkg/process/metadata/workloadmeta/collector/process_test.go +++ b/pkg/process/metadata/workloadmeta/collector/process_test.go @@ -90,8 +90,7 @@ func setUpCollectorTest(t *testing.T) *collectorTest { core.MockBundle(), fx.Replace(compcfg.MockParams{Overrides: overrides}), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) // pass actual config component diff --git a/pkg/process/procutil/data_scrubber.go b/pkg/process/procutil/data_scrubber.go index 826cadfb51207..18c3faf62bad1 100644 --- a/pkg/process/procutil/data_scrubber.go +++ b/pkg/process/procutil/data_scrubber.go @@ -186,16 +186,6 @@ func (ds *DataScrubber) ScrubCommand(cmdline []string) ([]string, bool) { return newCmdline, changed } -// Strip away all arguments from the command line -func (ds *DataScrubber) stripArguments(cmdline []string) []string { - // We will sometimes see the entire command line come in via the first element -- splitting guarantees removal - // of arguments in these cases. - if len(cmdline) > 0 { - return []string{strings.Split(cmdline[0], " ")[0]} - } - return cmdline -} - // AddCustomSensitiveWords adds custom sensitive words on the DataScrubber object func (ds *DataScrubber) AddCustomSensitiveWords(words []string) { newPatterns := CompileStringsToRegex(words) diff --git a/pkg/process/procutil/data_scrubber_notwin.go b/pkg/process/procutil/data_scrubber_fallback.go similarity index 56% rename from pkg/process/procutil/data_scrubber_notwin.go rename to pkg/process/procutil/data_scrubber_fallback.go index 015b87d105cc4..1968ea732eb55 100644 --- a/pkg/process/procutil/data_scrubber_notwin.go +++ b/pkg/process/procutil/data_scrubber_fallback.go @@ -5,9 +5,12 @@ //go:build !windows -//nolint:revive // TODO(PROC) Fix revive linter package procutil +import ( + "strings" +) + var ( defaultSensitiveWords = []string{ "*password*", "*passwd*", "*mysql_pwd*", @@ -18,3 +21,13 @@ var ( forbiddenSymbolsRegex = "[^a-zA-Z0-9_*]" ) + +// stripArguments removes all arguments given a command line. +func (ds *DataScrubber) stripArguments(cmdline []string) []string { + // We will sometimes see the entire command line come in via the first element -- splitting guarantees removal + // of arguments in these cases. + if len(cmdline) > 0 { + return []string{strings.SplitN(cmdline[0], " ", 2)[0]} + } + return cmdline +} diff --git a/pkg/process/procutil/data_scrubber_fallback_test.go b/pkg/process/procutil/data_scrubber_fallback_test.go new file mode 100644 index 0000000000000..430b02c2af94d --- /dev/null +++ b/pkg/process/procutil/data_scrubber_fallback_test.go @@ -0,0 +1,61 @@ +// 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. + +//go:build !windows + +package procutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStripArguments(t *testing.T) { + for _, tc := range []struct { + name string + cmdline []string + expected string + }{ + { + name: "OS parse", + cmdline: []string{"agent", "-password", "1234"}, + expected: "agent", + }, + { + name: "No OS parse", + cmdline: []string{"python ~/test/run.py -open_password=admin -consul_token 2345 -blocked_from_yamt=1234 &"}, + expected: "python", + }, + { + name: "No OS parse + whitespace", + cmdline: []string{"java -password 1234"}, + expected: "java", + }, + { + name: "Optional dash args", + cmdline: []string{"agent password:1234"}, + expected: "agent", + }, + { + name: "Single dash args", + cmdline: []string{"agent -password:1234"}, + expected: "agent", + }, + { + name: "Double dash args", + cmdline: []string{"agent --password:1234"}, + expected: "agent", + }, + } { + scrubber := setupDataScrubber(t) + scrubber.StripAllArguments = true + + t.Run(tc.name, func(t *testing.T) { + actual := scrubber.stripArguments(tc.cmdline) + assert.Equal(t, actual[0], tc.expected) + }) + } +} diff --git a/pkg/process/procutil/data_scrubber_windows.go b/pkg/process/procutil/data_scrubber_windows.go index b0de24eeb7ec6..6242060a1aadf 100644 --- a/pkg/process/procutil/data_scrubber_windows.go +++ b/pkg/process/procutil/data_scrubber_windows.go @@ -3,9 +3,14 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//nolint:revive // TODO(PROC) Fix revive linter +//go:build windows + package procutil +import ( + "strings" +) + var ( defaultSensitiveWords = []string{ "*password*", "*passwd*", "*mysql_pwd*", @@ -20,3 +25,62 @@ var ( // it's for handling parameters like `/p` and `/rp` in windows forbiddenSymbolsRegex = "[^/a-zA-Z0-9_*]" ) + +var executableExtensions = []string{".com", ".exe", ".bat", ".cmd", ".vbs", ".vbe", ".js", ".jse", ".wsf", ".wsh", ".psc1", ".ps1"} + +// stripArguments identifies windows extension and extracts command. Otherwise, returns the first element of the cmdline before first space. +// If cmdline is empty, stripArguments will return an empty string. +func (ds *DataScrubber) stripArguments(cmdline []string) []string { + if len(cmdline) < 1 { + return cmdline + } + + strCmdline := cmdline[0] + + // Case 1: OS has already completed splitting as there is one token per element, we return first token. + if len(cmdline) > 1 { + return []string{strCmdline} + } + + // Case 2: One string for cmdline, use extensionParser() to find first token. + if !strings.HasPrefix(strCmdline, "\"") { + strippedCmdline := extensionParser(strCmdline, executableExtensions) + + if strippedCmdline != "" { + return []string{strippedCmdline} + } + + // If no extension is found, return first token of cmdline. + return []string{strings.SplitN(strCmdline, " ", 2)[0]} + } + + // Case 2b: One string for cmdline and first token wrapped in quotes, use findEmbeddedQuotes() to find content between quotes. + strippedCmdline := findEmbeddedQuotes(strCmdline) + return []string{strippedCmdline} +} + +// extensionParser returns substring of cmdline up to the first extension (inclusive). +// If no extension is found, returns empty string. +// Example: Input="C:\\Program Files\\Datadog\\agent.vbe check process" Output="C:\\Program Files\\Datadog\\agent.vbe" +func extensionParser(cmdline string, executableExtensions []string) string { + for _, c := range executableExtensions { + // If extension is found before a word break (space or end of line). + if i := strings.Index(cmdline, c); i != -1 && (i+len(c) == len(cmdline) || cmdline[i+len(c)] == ' ') { + processedCmdline := cmdline[:i+len(c)] + return processedCmdline + } + } + return "" +} + +// findEmbeddedQuotes returns the content between the first pair of double quotes in cmdline. +// If there is no pair of double quotes found, function returns original cmdline. +// Example: Input="\"C:\\Program Files\\Datadog\\agent.vbe\" check process" Output="C:\\Program Files\\Datadog\\agent.vbe" +func findEmbeddedQuotes(cmdline string) string { + strippedCmdline := strings.SplitN(cmdline, "\"", 3) + if len(strippedCmdline) < 3 { + return cmdline + } + + return strippedCmdline[1] +} diff --git a/pkg/process/procutil/data_scrubber_windows_test.go b/pkg/process/procutil/data_scrubber_windows_test.go new file mode 100644 index 0000000000000..f7483e23472a3 --- /dev/null +++ b/pkg/process/procutil/data_scrubber_windows_test.go @@ -0,0 +1,192 @@ +// 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. + +//go:build windows + +package procutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStripArguments(t *testing.T) { + for _, tc := range []struct { + name string + cmdline []string + expected string + }{ + { + name: "Empty string", + cmdline: []string{""}, + expected: "", + }, + { + name: "OS parse", + cmdline: []string{"agent", "-password", "1234"}, + expected: "agent", + }, + { + name: "Windows exec + OS parse", + cmdline: []string{"C:\\Program Files\\Datadog\\agent.bat", "check", "process"}, + expected: "C:\\Program Files\\Datadog\\agent.bat", + }, + { + name: "No OS parse", + cmdline: []string{"python ~/test/run.py --password=1234 -password 1234 -open_password=admin -consul_token 2345 -blocked_from_yaml=1234 &"}, + expected: "python", + }, + { + name: "No OS parse + whitespace", + cmdline: []string{"java -password 1234"}, + expected: "java", + }, + { + name: "No OS parse + Optional dash args", + cmdline: []string{"agent password:1234"}, + expected: "agent", + }, + { + name: "Windows exec", + cmdline: []string{"C:\\Program Files\\Datadog\\agent.com"}, + expected: "C:\\Program Files\\Datadog\\agent.com", + }, + { + name: "Windows exec + args", + cmdline: []string{"C:\\Program Files\\Datadog\\agent.exe check process"}, + expected: "C:\\Program Files\\Datadog\\agent.exe", + }, + { + name: "Windows exec + paired quotes", + cmdline: []string{"\"C:\\Program Files\\Datadog\\agent.cmd\" check process"}, + expected: "C:\\Program Files\\Datadog\\agent.cmd", + }, + { + name: "Paired quotes", + cmdline: []string{"\"C:\\Program Files\\agent\" check process"}, + expected: "C:\\Program Files\\agent", + }, + } { + + scrubber := setupDataScrubber(t) + scrubber.StripAllArguments = true + + t.Run(tc.name, func(t *testing.T) { + cmdline := scrubber.stripArguments(tc.cmdline) + assert.Equal(t, cmdline[0], tc.expected) + }) + } +} + +func TestFindEmbeddedQuotes(t *testing.T) { + for _, tc := range []struct { + name string + cmdline string + expected string + }{ + { + name: "Paired quotes", + cmdline: "\"C:\\Program Files\\Datadog\\agent.cmd\" check process ", + expected: "C:\\Program Files\\Datadog\\agent.cmd", + }, + { + name: "One quote", + cmdline: "\"C:\\Program Files\\Datadog\\agent.cmd check process ", + expected: "\"C:\\Program Files\\Datadog\\agent.cmd check process ", + }, + { + name: "Empty string", + cmdline: "", + expected: "", + }, + } { + + t.Run(tc.name, func(t *testing.T) { + actual := findEmbeddedQuotes(tc.cmdline) + assert.Equal(t, actual, tc.expected) + }) + } +} + +func TestExtensionParser(t *testing.T) { + for _, tc := range []struct { + name string + cmdline string + expected string + }{ + { + name: "Extension not found", + cmdline: "python ~/test/run.py --password=1234 -password 1234 -open_password=admin -consul_token 2345 -blocked_from_yaml=1234 & ", + expected: "", + }, + { + name: "Extension at end of line", + cmdline: "C:\\Program Files\\Datadog\\agent.com", + expected: "C:\\Program Files\\Datadog\\agent.com", + }, + { + name: "Extension in first token", + cmdline: "C:\\Program Files\\Datadog\\agent.cmd check process", + expected: "C:\\Program Files\\Datadog\\agent.cmd", + }, + { + name: "Multiple extensions", + cmdline: "C:\\Program Files\\Datadog\\agent.exec.process.cmd check process", + expected: "C:\\Program Files\\Datadog\\agent.exec.process.cmd", + }, + { + name: "Misformed extension", + cmdline: "C:\\Program File\\Datexedog\\agent.exe check process", + expected: "C:\\Program File\\Datexedog\\agent.exe", + }, + { + name: "vbs extension", + cmdline: "C:\\Program Files\\agent.vbs check process", + expected: "C:\\Program Files\\agent.vbs", + }, + { + name: "jse extension", + cmdline: "C:\\Program Files\\Datadog\\agent.jse check process", + expected: "C:\\Program Files\\Datadog\\agent.jse", + }, + { + name: "wsf extension", + cmdline: "C:\\Program Files\\Datadog\\agent.wsf check process", + expected: "C:\\Program Files\\Datadog\\agent.wsf", + }, + { + name: "wsh extension", + cmdline: "C:\\Program Files\\Datadog\\agent.wsh check process", + expected: "C:\\Program Files\\Datadog\\agent.wsh", + }, + { + name: "psc1 extension", + cmdline: "C:\\Program Files\\Datadog\\agent.psc1 check process", + expected: "C:\\Program Files\\Datadog\\agent.psc1", + }, + { + name: "bat extension", + cmdline: "C:\\Program Files\\Datadog\\agent.bat check process", + expected: "C:\\Program Files\\Datadog\\agent.bat", + }, + { + name: "js extension", + cmdline: "C:\\Program Files\\Datadog\\agent.js check process", + expected: "C:\\Program Files\\Datadog\\agent.js", + }, + { + name: "com extension", + cmdline: "C:\\Program Files\\Datadog\\agent.com check process", + expected: "C:\\Program Files\\Datadog\\agent.com", + }, + } { + + t.Run(tc.name, func(t *testing.T) { + actual := extensionParser(tc.cmdline, executableExtensions) + assert.Equal(t, tc.expected, actual) + }) + } +} diff --git a/pkg/process/runner/runner.go b/pkg/process/runner/runner.go index ef4e9269088a0..c1dd778c270d8 100644 --- a/pkg/process/runner/runner.go +++ b/pkg/process/runner/runner.go @@ -378,6 +378,7 @@ func (l *CheckRunner) basicRunner(c checks.Check) func() { } ticker := time.NewTicker(checks.GetInterval(l.config, c.Name())) + defer ticker.Stop() for { select { case <-ticker.C: @@ -497,7 +498,7 @@ func readResponseStatuses(checkName string, responses <-chan defaultforwarder.Re } if response.StatusCode >= 300 { - log.Errorf("[%s] Invalid response from %s: %d -> %s", checkName, response.Domain, response.StatusCode, response.Err) + log.Errorf("[%s] Invalid response from %s: %d -> %v", checkName, response.Domain, response.StatusCode, response.Err) continue } diff --git a/pkg/process/runner/runner_test.go b/pkg/process/runner/runner_test.go index 8f7a074ae7ba4..1a69dfc2c1944 100644 --- a/pkg/process/runner/runner_test.go +++ b/pkg/process/runner/runner_test.go @@ -12,7 +12,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "go.uber.org/fx" model "github.com/DataDog/agent-payload/v5/process" @@ -31,7 +30,7 @@ func TestUpdateRTStatus(t *testing.T) { cfg := configmock.New(t) assert := assert.New(t) - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) c, err := NewRunner(cfg, nil, &checks.HostInfo{}, []checks.Check{checks.NewProcessCheck(cfg, cfg, wmeta)}, nil) assert.NoError(err) // XXX: Give the collector a big channel so it never blocks. @@ -68,7 +67,7 @@ func TestUpdateRTStatus(t *testing.T) { func TestUpdateRTInterval(t *testing.T) { cfg := configmock.New(t) assert := assert.New(t) - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) c, err := NewRunner(configmock.New(t), nil, &checks.HostInfo{}, []checks.Check{checks.NewProcessCheck(cfg, cfg, wmeta)}, nil) assert.NoError(err) // XXX: Give the collector a big channel so it never blocks. @@ -128,7 +127,7 @@ func TestDisableRealTimeProcessCheck(t *testing.T) { disableRealtime: false, }, } - wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(), fx.Supply(workloadmeta.NewParams())) + wmeta := fxutil.Test[workloadmeta.Component](t, core.MockBundle(), workloadmetafxmock.MockModule(workloadmeta.NewParams())) for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { mockConfig := configmock.New(t) diff --git a/pkg/process/util/api/go.mod b/pkg/process/util/api/go.mod index c0d02484bbc1a..00c0df586a102 100644 --- a/pkg/process/util/api/go.mod +++ b/pkg/process/util/api/go.mod @@ -47,11 +47,11 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.7.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.23.0 // indirect - golang.org/x/sys v0.23.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/sys v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/process/util/api/go.sum b/pkg/process/util/api/go.sum index e2f7be0870aec..8f97c7bc2a209 100644 --- a/pkg/process/util/api/go.sum +++ b/pkg/process/util/api/go.sum @@ -6,8 +6,6 @@ github.com/DataDog/zstd v1.4.8 h1:Rpmta4xZ/MgZnriKNd24iZMhGpP5dvUcs/uqfBapKZY= github.com/DataDog/zstd v1.4.8/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f/go.mod h1:oXfOhM/Kr8OvqS6tVqJwxPBornV0yrx3bc+l0BDr7PQ= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -40,8 +38,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= @@ -79,16 +75,16 @@ go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5 go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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= @@ -105,8 +101,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ 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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/pkg/process/util/containers/containers_test.go b/pkg/process/util/containers/containers_test.go index 2ed9dca0824d9..316b237a4858f 100644 --- a/pkg/process/util/containers/containers_test.go +++ b/pkg/process/util/containers/containers_test.go @@ -42,8 +42,7 @@ func TestGetContainers(t *testing.T) { metadataProvider := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) fakeTagger := taggerimpl.SetupFakeTagger(t) diff --git a/pkg/proto/go.mod b/pkg/proto/go.mod index fe7562271b18a..7550cc9d9b4e5 100644 --- a/pkg/proto/go.mod +++ b/pkg/proto/go.mod @@ -23,9 +23,9 @@ require ( github.com/philhofer/fwd v1.1.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // 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 google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/pkg/proto/go.sum b/pkg/proto/go.sum index 2ccd52479982d..c917a8d729190 100644 --- a/pkg/proto/go.sum +++ b/pkg/proto/go.sum @@ -78,8 +78,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -100,8 +100,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -110,8 +110,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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= diff --git a/pkg/proto/pbgo/mocks/core/api_mockgen.pb.go b/pkg/proto/pbgo/mocks/core/api_mockgen.pb.go index 68d71091db1f5..b3ecb4fc4529a 100644 --- a/pkg/proto/pbgo/mocks/core/api_mockgen.pb.go +++ b/pkg/proto/pbgo/mocks/core/api_mockgen.pb.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: /workspaces/datadog-agent/pkg/proto/pbgo/core/api.pb.go +// Source: pkg/proto/pbgo/core/api.pb.go // Package mock_core is a generated GoMock package. package mock_core diff --git a/pkg/remoteconfig/state/go.mod b/pkg/remoteconfig/state/go.mod index 0f16899c1a20f..934e1b30e6476 100644 --- a/pkg/remoteconfig/state/go.mod +++ b/pkg/remoteconfig/state/go.mod @@ -12,7 +12,7 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/sys v0.24.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/remoteconfig/state/go.sum b/pkg/remoteconfig/state/go.sum index 8eb5a769a1544..56c393ee2c599 100644 --- a/pkg/remoteconfig/state/go.sum +++ b/pkg/remoteconfig/state/go.sum @@ -16,10 +16,10 @@ github.com/secure-systems-lab/go-securesystemslib v0.7.0 h1:OwvJ5jQf9LnIAS83waAj github.com/secure-systems-lab/go-securesystemslib v0.7.0/go.mod h1:/2gYnlnHVQ6xeGtfIqFy7Do03K4cdCY0A/GlJLDKLHI= 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= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +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= 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= diff --git a/pkg/sbom/scanner/scanner_test.go b/pkg/sbom/scanner/scanner_test.go index 3a877e5a3f4a4..ba522b63cbefc 100644 --- a/pkg/sbom/scanner/scanner_test.go +++ b/pkg/sbom/scanner/scanner_test.go @@ -80,8 +80,7 @@ func TestRetryLogic_Error(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), compConfig.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) // Store the image @@ -162,8 +161,7 @@ func TestRetryLogic_ImageDeleted(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), compConfig.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) // Store the image @@ -229,8 +227,7 @@ func TestRetryChannelFull(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), compConfig.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) // Store the image diff --git a/pkg/security/agent/agent.go b/pkg/security/agent/agent.go index 338be6922ed67..afd53efc39b81 100644 --- a/pkg/security/agent/agent.go +++ b/pkg/security/agent/agent.go @@ -66,11 +66,12 @@ func (rsa *RuntimeSecurityAgent) Start(reporter common.RawReporter, endpoints *c if runtime.GOOS == "linux" { // Start activity dumps listener go rsa.StartActivityDumpListener() + go rsa.startActivityDumpStorageTelemetry(ctx) } if rsa.telemetry != nil { // Send Runtime Security Agent telemetry - go rsa.telemetry.run(ctx, rsa) + go rsa.telemetry.run(ctx) } } @@ -80,7 +81,6 @@ func (rsa *RuntimeSecurityAgent) Stop() { rsa.running.Store(false) rsa.client.Close() rsa.wg.Wait() - } // StartEventListener starts listening for new events from system-probe @@ -208,3 +208,19 @@ func newLogBackoffTicker() *backoff.Ticker { expBackoff.Reset() return backoff.NewTicker(expBackoff) } + +func (rsa *RuntimeSecurityAgent) startActivityDumpStorageTelemetry(ctx context.Context) { + metricsTicker := time.NewTicker(1 * time.Minute) + defer metricsTicker.Stop() + + for { + select { + case <-ctx.Done(): + return + case <-metricsTicker.C: + if rsa.storage != nil { + rsa.storage.SendTelemetry() + } + } + } +} diff --git a/pkg/security/agent/telemetry_linux.go b/pkg/security/agent/telemetry_linux.go index ec3e30825886c..ed00085994a08 100644 --- a/pkg/security/agent/telemetry_linux.go +++ b/pkg/security/agent/telemetry_linux.go @@ -61,7 +61,7 @@ func (t *telemetry) registerProfiledContainer(name, tag string) { } } -func (t *telemetry) run(ctx context.Context, rsa *RuntimeSecurityAgent) { +func (t *telemetry) run(ctx context.Context) { log.Info("started collecting Runtime Security Agent telemetry") defer log.Info("stopping Runtime Security Agent telemetry") @@ -78,9 +78,6 @@ func (t *telemetry) run(ctx context.Context, rsa *RuntimeSecurityAgent) { if err := t.reportContainers(); err != nil { log.Debugf("couldn't report containers: %v", err) } - if rsa.storage != nil { - rsa.storage.SendTelemetry() - } case <-profileCounterTicker.C: if err := t.reportProfiledContainers(); err != nil { log.Debugf("couldn't report profiled containers: %v", err) diff --git a/pkg/security/agent/telemetry_others.go b/pkg/security/agent/telemetry_others.go index f88976b538b42..aeb59d282624e 100644 --- a/pkg/security/agent/telemetry_others.go +++ b/pkg/security/agent/telemetry_others.go @@ -14,4 +14,4 @@ type telemetry struct{} func (t *telemetry) registerProfiledContainer(_, _ string) {} -func (t *telemetry) run(_ context.Context, _ *RuntimeSecurityAgent) {} +func (t *telemetry) run(_ context.Context) {} diff --git a/pkg/security/ebpf/kernel/kernel.go b/pkg/security/ebpf/kernel/kernel.go index cda74e0937dab..f6e6060a5be42 100644 --- a/pkg/security/ebpf/kernel/kernel.go +++ b/pkg/security/ebpf/kernel/kernel.go @@ -22,7 +22,7 @@ import ( "github.com/cilium/ebpf/features" "github.com/cilium/ebpf/link" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/filesystem" "github.com/DataDog/datadog-agent/pkg/util/kernel" ) @@ -156,7 +156,7 @@ func newKernelVersion() (*Version, error) { // Then look if `/host` is mounted in the container // since this can be done without the env variable being set - if config.IsContainerized() && filesystem.FileExists("/host") { + if env.IsContainerized() && filesystem.FileExists("/host") { osReleasePaths = append( osReleasePaths, filepath.Join("/host", osrelease.UsrLibOsRelease), diff --git a/pkg/security/module/server_linux.go b/pkg/security/module/server_linux.go index e7cea21a88a07..c4d1d9556cd11 100644 --- a/pkg/security/module/server_linux.go +++ b/pkg/security/module/server_linux.go @@ -56,7 +56,7 @@ func (a *APIServer) ListActivityDumps(_ context.Context, params *api.ActivityDum if managers := p.GetProfileManagers(); managers != nil { msg, err := managers.ListActivityDumps(params) if err != nil { - seclog.Errorf(err.Error()) + seclog.Errorf("%s", err.Error()) } return msg, nil } @@ -74,7 +74,7 @@ func (a *APIServer) StopActivityDump(_ context.Context, params *api.ActivityDump if managers := p.GetProfileManagers(); managers != nil { msg, err := managers.StopActivityDump(params) if err != nil { - seclog.Errorf(err.Error()) + seclog.Errorf("%s", err.Error()) } return msg, nil } @@ -92,7 +92,7 @@ func (a *APIServer) TranscodingRequest(_ context.Context, params *api.Transcodin if managers := p.GetProfileManagers(); managers != nil { msg, err := managers.GenerateTranscoding(params) if err != nil { - seclog.Errorf(err.Error()) + seclog.Errorf("%s", err.Error()) } return msg, nil } @@ -110,7 +110,7 @@ func (a *APIServer) ListSecurityProfiles(_ context.Context, params *api.Security if managers := p.GetProfileManagers(); managers != nil { msg, err := managers.ListSecurityProfiles(params) if err != nil { - seclog.Errorf(err.Error()) + seclog.Errorf("%s", err.Error()) } return msg, nil } @@ -128,7 +128,7 @@ func (a *APIServer) SaveSecurityProfile(_ context.Context, params *api.SecurityP if managers := p.GetProfileManagers(); managers != nil { msg, err := managers.SaveSecurityProfile(params) if err != nil { - seclog.Errorf(err.Error()) + seclog.Errorf("%s", err.Error()) } return msg, nil } diff --git a/pkg/security/probe/config/config.go b/pkg/security/probe/config/config.go index 549c61446167e..5ddd7ab15913c 100644 --- a/pkg/security/probe/config/config.go +++ b/pkg/security/probe/config/config.go @@ -15,6 +15,7 @@ import ( sysconfig "github.com/DataDog/datadog-agent/cmd/system-probe/config" coreconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/ebpf" "github.com/DataDog/datadog-agent/pkg/util/filesystem" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -26,7 +27,7 @@ const ( ) func setEnv() { - if coreconfig.IsContainerized() && filesystem.FileExists("/host") { + if env.IsContainerized() && filesystem.FileExists("/host") { if v := os.Getenv("HOST_PROC"); v == "" { os.Setenv("HOST_PROC", "/host/proc") } diff --git a/pkg/security/probe/constantfetch/btfhub/constants.json b/pkg/security/probe/constantfetch/btfhub/constants.json index 8d20627e0d5a5..7ef404ea26e4f 100644 --- a/pkg/security/probe/constantfetch/btfhub/constants.json +++ b/pkg/security/probe/constantfetch/btfhub/constants.json @@ -11848,6 +11848,13 @@ "uname_release": "4.14.349-266.564.amzn2.aarch64", "cindex": 3 }, + { + "distrib": "amzn", + "version": "2", + "arch": "arm64", + "uname_release": "4.14.350-266.564.amzn2.aarch64", + "cindex": 3 + }, { "distrib": "amzn", "version": "2", @@ -12639,6 +12646,13 @@ "uname_release": "4.14.349-266.564.amzn2.x86_64", "cindex": 8 }, + { + "distrib": "amzn", + "version": "2", + "arch": "x86_64", + "uname_release": "4.14.350-266.564.amzn2.x86_64", + "cindex": 8 + }, { "distrib": "amzn", "version": "2", @@ -13346,6 +13360,13 @@ "uname_release": "4.14.349-188.564.amzn1.x86_64", "cindex": 15 }, + { + "distrib": "amzn", + "version": "2018", + "arch": "x86_64", + "uname_release": "4.14.350-188.564.amzn1.x86_64", + "cindex": 15 + }, { "distrib": "amzn", "version": "2018", diff --git a/pkg/security/probe/field_handlers_ebpf.go b/pkg/security/probe/field_handlers_ebpf.go index d65e55e430921..b9cb03e12cfc7 100644 --- a/pkg/security/probe/field_handlers_ebpf.go +++ b/pkg/security/probe/field_handlers_ebpf.go @@ -538,7 +538,7 @@ func (fh *EBPFFieldHandlers) ResolveCGroupID(ev *model.Event, e *model.CGroupCon } // ResolveCGroupManager resolves the manager of the cgroup -func (fh *EBPFFieldHandlers) ResolveCGroupManager(ev *model.Event, e *model.CGroupContext) string { +func (fh *EBPFFieldHandlers) ResolveCGroupManager(ev *model.Event, _ *model.CGroupContext) string { if entry, _ := fh.ResolveProcessCacheEntry(ev); entry != nil { if manager := containerutils.CGroupManager(entry.CGroup.CGroupFlags); manager != 0 { return manager.String() diff --git a/pkg/security/probe/probe_ebpf.go b/pkg/security/probe/probe_ebpf.go index 87e2c71f14547..95c6c93b71ce8 100644 --- a/pkg/security/probe/probe_ebpf.go +++ b/pkg/security/probe/probe_ebpf.go @@ -33,7 +33,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/telemetry" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - aconfig "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" ebpftelemetry "github.com/DataDog/datadog-agent/pkg/ebpf/telemetry" "github.com/DataDog/datadog-agent/pkg/security/config" @@ -65,7 +65,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/serializers" "github.com/DataDog/datadog-agent/pkg/security/utils" utilkernel "github.com/DataDog/datadog-agent/pkg/util/kernel" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // EventStream describes the interface implemented by reordered perf maps or ring buffers @@ -223,7 +222,7 @@ func (p *EBPFProbe) VerifyOSVersion() error { // VerifyEnvironment returns an error if the current environment seems to be misconfigured func (p *EBPFProbe) VerifyEnvironment() *multierror.Error { var err *multierror.Error - if aconfig.IsContainerized() { + if env.IsContainerized() { if mounted, _ := mountinfo.Mounted("/etc/passwd"); !mounted { err = multierror.Append(err, errors.New("/etc/passwd doesn't seem to be a mountpoint")) } @@ -1634,7 +1633,7 @@ func (p *EBPFProbe) DumpProcessCache(withArgs bool) (string, error) { } // NewEBPFProbe instantiates a new runtime security agent probe -func NewEBPFProbe(probe *Probe, config *config.Config, opts Opts, wmeta optional.Option[workloadmeta.Component], telemetry telemetry.Component) (*EBPFProbe, error) { +func NewEBPFProbe(probe *Probe, config *config.Config, opts Opts, wmeta workloadmeta.Component, telemetry telemetry.Component) (*EBPFProbe, error) { nerpc, err := erpc.NewERPC() if err != nil { return nil, err diff --git a/pkg/security/probe/probe_linux.go b/pkg/security/probe/probe_linux.go index 884f8fb7c1038..173560f8dc302 100644 --- a/pkg/security/probe/probe_linux.go +++ b/pkg/security/probe/probe_linux.go @@ -10,7 +10,6 @@ import ( "github.com/DataDog/datadog-agent/comp/core/telemetry" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/security/config" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) const ( @@ -21,7 +20,7 @@ const ( ) // NewProbe instantiates a new runtime security agent probe -func NewProbe(config *config.Config, opts Opts, wmeta optional.Option[workloadmeta.Component], telemetry telemetry.Component) (*Probe, error) { +func NewProbe(config *config.Config, opts Opts, wmeta workloadmeta.Component, telemetry telemetry.Component) (*Probe, error) { opts.normalize() p := newProbe(config, opts) diff --git a/pkg/security/probe/probe_windows.go b/pkg/security/probe/probe_windows.go index 07ad20aa5f448..574ee112f4175 100644 --- a/pkg/security/probe/probe_windows.go +++ b/pkg/security/probe/probe_windows.go @@ -35,7 +35,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/serializers" "github.com/DataDog/datadog-agent/pkg/security/utils" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" "github.com/DataDog/datadog-agent/pkg/util/winutil" "github.com/DataDog/datadog-agent/pkg/windowsdriver/procmon" @@ -1379,7 +1378,7 @@ func (p *Probe) Origin() string { } // NewProbe instantiates a new runtime security agent probe -func NewProbe(config *config.Config, opts Opts, _ optional.Option[workloadmeta.Component], telemetry telemetry.Component) (*Probe, error) { +func NewProbe(config *config.Config, opts Opts, _ workloadmeta.Component, telemetry telemetry.Component) (*Probe, error) { opts.normalize() p := newProbe(config, opts) diff --git a/pkg/security/ptracer/proc.go b/pkg/security/ptracer/proc.go index c6fc46209cdd9..0484449f2ac94 100644 --- a/pkg/security/ptracer/proc.go +++ b/pkg/security/ptracer/proc.go @@ -282,7 +282,7 @@ func (ctx *CWSPtracerCtx) scanProcfs() { every = 500 * time.Millisecond } ticker := time.NewTicker(every) - + defer ticker.Stop() for { select { case <-ticker.C: diff --git a/pkg/security/resolvers/netns/resolver.go b/pkg/security/resolvers/netns/resolver.go index fe0caef888a41..73a5d92f8920c 100644 --- a/pkg/security/resolvers/netns/resolver.go +++ b/pkg/security/resolvers/netns/resolver.go @@ -657,7 +657,7 @@ func (nr *Resolver) DumpNetworkNamespaces(params *api.DumpNetworkNamespaceParams dumpFile, err := newTmpFile("network-namespace-dump-*.json") if err != nil { resp.Error = fmt.Sprintf("couldn't create temporary file: %v", err) - seclog.Warnf(resp.Error) + seclog.Warnf("%s", err.Error()) return resp } defer dumpFile.Close() @@ -667,13 +667,13 @@ func (nr *Resolver) DumpNetworkNamespaces(params *api.DumpNetworkNamespaceParams encoder := json.NewEncoder(dumpFile) if err = encoder.Encode(dump); err != nil { resp.Error = fmt.Sprintf("couldn't encode list of network namespace: %v", err) - seclog.Warnf(resp.Error) + seclog.Warnf("%s", err.Error()) return resp } if err = dumpFile.Close(); err != nil { resp.Error = fmt.Sprintf("could not close file [%s]: %s", dumpFile.Name(), err) - seclog.Warnf(resp.Error) + seclog.Warnf("%s", err.Error()) return resp } @@ -681,7 +681,7 @@ func (nr *Resolver) DumpNetworkNamespaces(params *api.DumpNetworkNamespaceParams graphFile, err := newTmpFile("network-namespace-graph-*.dot") if err != nil { resp.Error = fmt.Sprintf("couldn't create temporary file: %v", err) - seclog.Warnf(resp.Error) + seclog.Warnf("%s", err.Error()) return resp } defer graphFile.Close() @@ -690,13 +690,13 @@ func (nr *Resolver) DumpNetworkNamespaces(params *api.DumpNetworkNamespaceParams // generate dot graph if err = nr.generateGraph(dump, graphFile); err != nil { resp.Error = fmt.Sprintf("couldn't generate dot graph: %v", err) - seclog.Warnf(resp.Error) + seclog.Warnf("%s", err.Error()) return resp } if err = graphFile.Close(); err != nil { resp.Error = fmt.Sprintf("could not close file [%s]: %s", graphFile.Name(), err) - seclog.Warnf(resp.Error) + seclog.Warnf("%s", err.Error()) return resp } diff --git a/pkg/security/resolvers/resolvers_ebpf.go b/pkg/security/resolvers/resolvers_ebpf.go index 77ddcbbe24b06..0b4d84fa2cbeb 100644 --- a/pkg/security/resolvers/resolvers_ebpf.go +++ b/pkg/security/resolvers/resolvers_ebpf.go @@ -41,7 +41,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/resolvers/usersessions" "github.com/DataDog/datadog-agent/pkg/security/utils" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // EBPFResolvers holds the list of the event attribute resolvers @@ -65,7 +64,7 @@ type EBPFResolvers struct { } // NewEBPFResolvers creates a new instance of EBPFResolvers -func NewEBPFResolvers(config *config.Config, manager *manager.Manager, statsdClient statsd.ClientInterface, scrubber *procutil.DataScrubber, eRPC *erpc.ERPC, opts Opts, wmeta optional.Option[workloadmeta.Component], telemetry telemetry.Component) (*EBPFResolvers, error) { +func NewEBPFResolvers(config *config.Config, manager *manager.Manager, statsdClient statsd.ClientInterface, scrubber *procutil.DataScrubber, eRPC *erpc.ERPC, opts Opts, wmeta workloadmeta.Component, telemetry telemetry.Component) (*EBPFResolvers, error) { dentryResolver, err := dentry.NewResolver(config.Probe, statsdClient, eRPC) if err != nil { return nil, err diff --git a/pkg/security/resolvers/sbom/resolver.go b/pkg/security/resolvers/sbom/resolver.go index c31a73ac6ab04..2a64784d6b793 100644 --- a/pkg/security/resolvers/sbom/resolver.go +++ b/pkg/security/resolvers/sbom/resolver.go @@ -152,8 +152,8 @@ type Resolver struct { } // NewSBOMResolver returns a new instance of Resolver -func NewSBOMResolver(c *config.RuntimeSecurityConfig, statsdClient statsd.ClientInterface, wmeta optional.Option[workloadmeta.Component]) (*Resolver, error) { - sbomScanner, err := sbomscanner.CreateGlobalScanner(coreconfig.SystemProbe(), wmeta) +func NewSBOMResolver(c *config.RuntimeSecurityConfig, statsdClient statsd.ClientInterface, wmeta workloadmeta.Component) (*Resolver, error) { + sbomScanner, err := sbomscanner.CreateGlobalScanner(coreconfig.SystemProbe(), optional.NewOption(wmeta)) if err != nil { return nil, err } @@ -258,7 +258,7 @@ func (r *Resolver) Start(ctx context.Context) error { if err := retry.Do(func() error { return r.analyzeWorkload(sbom) }, retry.Attempts(maxSBOMGenerationRetries), retry.Delay(200*time.Millisecond)); err != nil { - seclog.Errorf(err.Error()) + seclog.Errorf("%s", err.Error()) } } } diff --git a/pkg/security/resolvers/sbom/resolver_unsupported.go b/pkg/security/resolvers/sbom/resolver_unsupported.go index b8464b5ad5932..43583a80e7f78 100644 --- a/pkg/security/resolvers/sbom/resolver_unsupported.go +++ b/pkg/security/resolvers/sbom/resolver_unsupported.go @@ -17,7 +17,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/config" cgroupModel "github.com/DataDog/datadog-agent/pkg/security/resolvers/cgroup/model" "github.com/DataDog/datadog-agent/pkg/security/secl/model" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) // Resolver is the Software Bill-Of-material resolver @@ -25,7 +24,7 @@ type Resolver struct { } // NewSBOMResolver returns a new instance of Resolver -func NewSBOMResolver(_ *config.RuntimeSecurityConfig, _ statsd.ClientInterface, _ optional.Option[workloadmeta.Component]) (*Resolver, error) { +func NewSBOMResolver(_ *config.RuntimeSecurityConfig, _ statsd.ClientInterface, _ workloadmeta.Component) (*Resolver, error) { return &Resolver{}, nil } diff --git a/pkg/security/secl/compiler/eval/errors.go b/pkg/security/secl/compiler/eval/errors.go index 0cd4bc3817191..3c76bf0c86f9f 100644 --- a/pkg/security/secl/compiler/eval/errors.go +++ b/pkg/security/secl/compiler/eval/errors.go @@ -168,3 +168,12 @@ type ErrFieldReadOnly struct { func (e ErrFieldReadOnly) Error() string { return fmt.Sprintf("read-only field `%s`", e.Field) } + +// ErrValueOutOfRange error when the given value is not having the correct range for the type +type ErrValueOutOfRange struct { + Field string +} + +func (e ErrValueOutOfRange) Error() string { + return fmt.Sprintf("incorrect value for type `%s`, out of range", e.Field) +} diff --git a/pkg/security/secl/compiler/generators/accessors/accessors.tmpl b/pkg/security/secl/compiler/generators/accessors/accessors.tmpl index b4b1899e62d89..b6c3d49620d78 100644 --- a/pkg/security/secl/compiler/generators/accessors/accessors.tmpl +++ b/pkg/security/secl/compiler/generators/accessors/accessors.tmpl @@ -13,12 +13,16 @@ import ( "{{.}}" {{end}} "reflect" + "math" {{if ne $.SourcePkg $.TargetPkg}}"{{.SourcePkg}}"{{end}} "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" ) +// to always require the math package +var _ = math.MaxUint16 + func (m *Model) GetIterator(field eval.Field) (eval.Iterator, error) { switch field { {{range $Name, $Field := .Iterators}} @@ -446,6 +450,11 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "{{$Field.Name}}"} } + {{- if eq $Field.OrigType "uint16" }} + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "{{$Field.Name}}"} + } + {{- end }} {{$FieldName}} = {{$Field.OrigType}}(rv) {{end}} return nil diff --git a/pkg/security/secl/go.mod b/pkg/security/secl/go.mod index 4ca3842496cf4..59dace20333ec 100644 --- a/pkg/security/secl/go.mod +++ b/pkg/security/secl/go.mod @@ -15,9 +15,9 @@ require ( github.com/skydive-project/go-debouncer v1.0.0 github.com/spf13/cast v1.6.0 github.com/stretchr/testify v1.9.0 - golang.org/x/sys v0.23.0 - golang.org/x/text v0.16.0 - golang.org/x/tools v0.23.0 + golang.org/x/sys v0.24.0 + golang.org/x/text v0.17.0 + golang.org/x/tools v0.24.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 modernc.org/mathutil v1.6.0 @@ -34,7 +34,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/shopspring/decimal v1.2.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect diff --git a/pkg/security/secl/go.sum b/pkg/security/secl/go.sum index 6a20ced73f5e1..b8e7938fb5c9e 100644 --- a/pkg/security/secl/go.sum +++ b/pkg/security/secl/go.sum @@ -69,8 +69,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= @@ -88,8 +88,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -97,13 +97,13 @@ 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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= diff --git a/pkg/security/secl/model/accessors_unix.go b/pkg/security/secl/model/accessors_unix.go index d74438d4a2eab..62015fcf3704a 100644 --- a/pkg/security/secl/model/accessors_unix.go +++ b/pkg/security/secl/model/accessors_unix.go @@ -11,10 +11,14 @@ package model import ( "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" + "math" "net" "reflect" ) +// to always require the math package +var _ = math.MaxUint16 + func (m *Model) GetIterator(field eval.Field) (eval.Iterator, error) { switch field { case "process.ancestors": @@ -31083,6 +31087,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Bind.AddrFamily"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Bind.AddrFamily"} + } ev.Bind.AddrFamily = uint16(rv) return nil case "bind.addr.ip": @@ -31097,6 +31104,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Bind.Addr.Port"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Bind.Addr.Port"} + } ev.Bind.Addr.Port = uint16(rv) return nil case "bind.retval": @@ -31273,6 +31283,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Chdir.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Chdir.File.FileFields.Mode"} + } ev.Chdir.File.FileFields.Mode = uint16(rv) return nil case "chdir.file.modification_time": @@ -31333,6 +31346,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Chdir.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Chdir.File.FileFields.Mode"} + } ev.Chdir.File.FileFields.Mode = uint16(rv) return nil case "chdir.file.uid": @@ -31434,6 +31450,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Chmod.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Chmod.File.FileFields.Mode"} + } ev.Chmod.File.FileFields.Mode = uint16(rv) return nil case "chmod.file.modification_time": @@ -31494,6 +31513,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Chmod.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Chmod.File.FileFields.Mode"} + } ev.Chmod.File.FileFields.Mode = uint16(rv) return nil case "chmod.file.uid": @@ -31616,6 +31638,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Chown.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Chown.File.FileFields.Mode"} + } ev.Chown.File.FileFields.Mode = uint16(rv) return nil case "chown.file.modification_time": @@ -31676,6 +31701,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Chown.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Chown.File.FileFields.Mode"} + } ev.Chown.File.FileFields.Mode = uint16(rv) return nil case "chown.file.uid": @@ -31768,6 +31796,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "DNS.ID"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "DNS.ID"} + } ev.DNS.ID = uint16(rv) return nil case "dns.question.class": @@ -31775,6 +31806,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "DNS.Class"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "DNS.Class"} + } ev.DNS.Class = uint16(rv) return nil case "dns.question.count": @@ -31782,6 +31816,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "DNS.Count"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "DNS.Count"} + } ev.DNS.Count = uint16(rv) return nil case "dns.question.length": @@ -31789,6 +31826,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "DNS.Size"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "DNS.Size"} + } ev.DNS.Size = uint16(rv) return nil case "dns.question.name": @@ -31805,6 +31845,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "DNS.Type"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "DNS.Type"} + } ev.DNS.Type = uint16(rv) return nil case "event.async": @@ -32175,6 +32218,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Exec.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Exec.Process.FileEvent.FileFields.Mode"} + } ev.Exec.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "exec.file.modification_time": @@ -32265,6 +32311,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Exec.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Exec.Process.FileEvent.FileFields.Mode"} + } ev.Exec.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "exec.file.uid": @@ -32428,6 +32477,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Exec.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Exec.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.Exec.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "exec.interpreter.file.modification_time": @@ -32518,6 +32570,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Exec.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Exec.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.Exec.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "exec.interpreter.file.uid": @@ -33000,6 +33055,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Exit.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Exit.Process.FileEvent.FileFields.Mode"} + } ev.Exit.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "exit.file.modification_time": @@ -33090,6 +33148,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Exit.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Exit.Process.FileEvent.FileFields.Mode"} + } ev.Exit.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "exit.file.uid": @@ -33253,6 +33314,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Exit.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Exit.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.Exit.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "exit.interpreter.file.modification_time": @@ -33343,6 +33407,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Exit.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Exit.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.Exit.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "exit.interpreter.file.uid": @@ -33598,6 +33665,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Link.Target.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Link.Target.FileFields.Mode"} + } ev.Link.Target.FileFields.Mode = uint16(rv) return nil case "link.file.destination.modification_time": @@ -33658,6 +33728,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Link.Target.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Link.Target.FileFields.Mode"} + } ev.Link.Target.FileFields.Mode = uint16(rv) return nil case "link.file.destination.uid": @@ -33724,6 +33797,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Link.Source.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Link.Source.FileFields.Mode"} + } ev.Link.Source.FileFields.Mode = uint16(rv) return nil case "link.file.modification_time": @@ -33784,6 +33860,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Link.Source.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Link.Source.FileFields.Mode"} + } ev.Link.Source.FileFields.Mode = uint16(rv) return nil case "link.file.uid": @@ -33902,6 +33981,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "LoadModule.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "LoadModule.File.FileFields.Mode"} + } ev.LoadModule.File.FileFields.Mode = uint16(rv) return nil case "load_module.file.modification_time": @@ -33962,6 +34044,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "LoadModule.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "LoadModule.File.FileFields.Mode"} + } ev.LoadModule.File.FileFields.Mode = uint16(rv) return nil case "load_module.file.uid": @@ -34070,6 +34155,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Mkdir.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Mkdir.File.FileFields.Mode"} + } ev.Mkdir.File.FileFields.Mode = uint16(rv) return nil case "mkdir.file.modification_time": @@ -34130,6 +34218,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Mkdir.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Mkdir.File.FileFields.Mode"} + } ev.Mkdir.File.FileFields.Mode = uint16(rv) return nil case "mkdir.file.uid": @@ -34210,6 +34301,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "MMap.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "MMap.File.FileFields.Mode"} + } ev.MMap.File.FileFields.Mode = uint16(rv) return nil case "mmap.file.modification_time": @@ -34270,6 +34364,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "MMap.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "MMap.File.FileFields.Mode"} + } ev.MMap.File.FileFields.Mode = uint16(rv) return nil case "mmap.file.uid": @@ -34396,6 +34493,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "NetworkContext.Destination.Port"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "NetworkContext.Destination.Port"} + } ev.NetworkContext.Destination.Port = uint16(rv) return nil case "network.device.ifindex": @@ -34417,6 +34517,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "NetworkContext.L3Protocol"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "NetworkContext.L3Protocol"} + } ev.NetworkContext.L3Protocol = uint16(rv) return nil case "network.l4_protocol": @@ -34424,6 +34527,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "NetworkContext.L4Protocol"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "NetworkContext.L4Protocol"} + } ev.NetworkContext.L4Protocol = uint16(rv) return nil case "network.size": @@ -34445,6 +34551,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "NetworkContext.Source.Port"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "NetworkContext.Source.Port"} + } ev.NetworkContext.Source.Port = uint16(rv) return nil case "ondemand.arg1.str": @@ -34574,6 +34683,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Open.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Open.File.FileFields.Mode"} + } ev.Open.File.FileFields.Mode = uint16(rv) return nil case "open.file.modification_time": @@ -34634,6 +34746,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Open.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Open.File.FileFields.Mode"} + } ev.Open.File.FileFields.Mode = uint16(rv) return nil case "open.file.uid": @@ -35104,6 +35219,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.ancestors.file.modification_time": @@ -35224,6 +35342,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.ancestors.file.uid": @@ -35435,6 +35556,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.ancestors.interpreter.file.modification_time": @@ -35555,6 +35679,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.ancestors.interpreter.file.uid": @@ -36055,6 +36182,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Process.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.file.modification_time": @@ -36145,6 +36275,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Process.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.file.uid": @@ -36308,6 +36441,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.interpreter.file.modification_time": @@ -36398,6 +36534,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.interpreter.file.uid": @@ -36859,6 +36998,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Parent.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Parent.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Parent.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.parent.file.modification_time": @@ -36979,6 +37121,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Parent.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Parent.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Parent.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.parent.file.uid": @@ -37190,6 +37335,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Parent.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.parent.interpreter.file.modification_time": @@ -37310,6 +37458,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "BaseEvent.ProcessContext.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "BaseEvent.ProcessContext.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.BaseEvent.ProcessContext.Parent.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "process.parent.interpreter.file.uid": @@ -38010,6 +38161,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.ancestors.file.modification_time": @@ -38130,6 +38284,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.ancestors.file.uid": @@ -38341,6 +38498,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.ancestors.interpreter.file.modification_time": @@ -38461,6 +38621,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.ancestors.interpreter.file.uid": @@ -38961,6 +39124,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Process.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.file.modification_time": @@ -39051,6 +39217,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Process.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.file.uid": @@ -39214,6 +39383,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.interpreter.file.modification_time": @@ -39304,6 +39476,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.interpreter.file.uid": @@ -39765,6 +39940,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Parent.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Parent.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Parent.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.parent.file.modification_time": @@ -39885,6 +40063,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Parent.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Parent.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Parent.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.parent.file.uid": @@ -40096,6 +40277,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Parent.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.parent.interpreter.file.modification_time": @@ -40216,6 +40400,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "PTrace.Tracee.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "PTrace.Tracee.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.PTrace.Tracee.Parent.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "ptrace.tracee.parent.interpreter.file.uid": @@ -40554,6 +40741,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "RemoveXAttr.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "RemoveXAttr.File.FileFields.Mode"} + } ev.RemoveXAttr.File.FileFields.Mode = uint16(rv) return nil case "removexattr.file.modification_time": @@ -40614,6 +40804,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "RemoveXAttr.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "RemoveXAttr.File.FileFields.Mode"} + } ev.RemoveXAttr.File.FileFields.Mode = uint16(rv) return nil case "removexattr.file.uid": @@ -40701,6 +40894,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Rename.New.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Rename.New.FileFields.Mode"} + } ev.Rename.New.FileFields.Mode = uint16(rv) return nil case "rename.file.destination.modification_time": @@ -40761,6 +40957,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Rename.New.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Rename.New.FileFields.Mode"} + } ev.Rename.New.FileFields.Mode = uint16(rv) return nil case "rename.file.destination.uid": @@ -40827,6 +41026,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Rename.Old.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Rename.Old.FileFields.Mode"} + } ev.Rename.Old.FileFields.Mode = uint16(rv) return nil case "rename.file.modification_time": @@ -40887,6 +41089,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Rename.Old.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Rename.Old.FileFields.Mode"} + } ev.Rename.Old.FileFields.Mode = uint16(rv) return nil case "rename.file.uid": @@ -40981,6 +41186,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Rmdir.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Rmdir.File.FileFields.Mode"} + } ev.Rmdir.File.FileFields.Mode = uint16(rv) return nil case "rmdir.file.modification_time": @@ -41041,6 +41249,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Rmdir.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Rmdir.File.FileFields.Mode"} + } ev.Rmdir.File.FileFields.Mode = uint16(rv) return nil case "rmdir.file.uid": @@ -41247,6 +41458,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "SetXAttr.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "SetXAttr.File.FileFields.Mode"} + } ev.SetXAttr.File.FileFields.Mode = uint16(rv) return nil case "setxattr.file.modification_time": @@ -41307,6 +41521,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "SetXAttr.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "SetXAttr.File.FileFields.Mode"} + } ev.SetXAttr.File.FileFields.Mode = uint16(rv) return nil case "setxattr.file.uid": @@ -41763,6 +41980,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.ancestors.file.modification_time": @@ -41883,6 +42103,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Ancestor.ProcessContext.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.ancestors.file.uid": @@ -42094,6 +42317,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.ancestors.interpreter.file.modification_time": @@ -42214,6 +42440,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Ancestor.ProcessContext.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.ancestors.interpreter.file.uid": @@ -42714,6 +42943,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Process.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.file.modification_time": @@ -42804,6 +43036,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Process.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Process.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Process.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.file.uid": @@ -42967,6 +43202,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.interpreter.file.modification_time": @@ -43057,6 +43295,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Process.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Process.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Process.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.interpreter.file.uid": @@ -43518,6 +43759,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Parent.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Parent.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Parent.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.parent.file.modification_time": @@ -43638,6 +43882,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Parent.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Parent.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Parent.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.parent.file.uid": @@ -43849,6 +44096,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Parent.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.parent.interpreter.file.modification_time": @@ -43969,6 +44219,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Signal.Target.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Signal.Target.Parent.LinuxBinprm.FileEvent.FileFields.Mode"} + } ev.Signal.Target.Parent.LinuxBinprm.FileEvent.FileFields.Mode = uint16(rv) return nil case "signal.target.parent.interpreter.file.uid": @@ -44300,6 +44553,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Splice.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Splice.File.FileFields.Mode"} + } ev.Splice.File.FileFields.Mode = uint16(rv) return nil case "splice.file.modification_time": @@ -44360,6 +44616,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Splice.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Splice.File.FileFields.Mode"} + } ev.Splice.File.FileFields.Mode = uint16(rv) return nil case "splice.file.uid": @@ -44454,6 +44713,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Unlink.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Unlink.File.FileFields.Mode"} + } ev.Unlink.File.FileFields.Mode = uint16(rv) return nil case "unlink.file.modification_time": @@ -44514,6 +44776,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Unlink.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Unlink.File.FileFields.Mode"} + } ev.Unlink.File.FileFields.Mode = uint16(rv) return nil case "unlink.file.uid": @@ -44636,6 +44901,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Utimes.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Utimes.File.FileFields.Mode"} + } ev.Utimes.File.FileFields.Mode = uint16(rv) return nil case "utimes.file.modification_time": @@ -44696,6 +44964,9 @@ func (ev *Event) SetFieldValue(field eval.Field, value interface{}) error { if !ok { return &eval.ErrValueTypeMismatch{Field: "Utimes.File.FileFields.Mode"} } + if rv < 0 || rv > math.MaxUint16 { + return &eval.ErrValueOutOfRange{Field: "Utimes.File.FileFields.Mode"} + } ev.Utimes.File.FileFields.Mode = uint16(rv) return nil case "utimes.file.uid": diff --git a/pkg/security/secl/model/accessors_windows.go b/pkg/security/secl/model/accessors_windows.go index 8d2de0bdf473e..e2fbd4cf17577 100644 --- a/pkg/security/secl/model/accessors_windows.go +++ b/pkg/security/secl/model/accessors_windows.go @@ -11,9 +11,13 @@ package model import ( "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" + "math" "reflect" ) +// to always require the math package +var _ = math.MaxUint16 + func (m *Model) GetIterator(field eval.Field) (eval.Iterator, error) { switch field { case "process.ancestors": diff --git a/pkg/security/secl/model/consts_darwin.go b/pkg/security/secl/model/consts_darwin.go index e84c43267bafa..9fd253d0ebadf 100644 --- a/pkg/security/secl/model/consts_darwin.go +++ b/pkg/security/secl/model/consts_darwin.go @@ -5,15 +5,16 @@ package model -import "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" +import ( + "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" + "golang.org/x/sys/unix" +) var ( errorConstants = map[string]int{} // KernelCapabilityConstants list of kernel capabilities KernelCapabilityConstants = map[string]uint64{} - // SignalConstants list of signals - SignalConstants = map[string]int{} - addressFamilyConstants = map[string]uint16{} + addressFamilyConstants = map[string]uint16{} ) var ( @@ -24,6 +25,11 @@ var ( "VM_WRITE": 0x2, "VM_EXEC": 0x4, } + + // SignalConstants on darwin are used by some dd-go tests, so we need them on darwin as well + SignalConstants = map[string]int{ + "SIGKILL": int(unix.SIGKILL), + } ) func initVMConstants() { diff --git a/pkg/security/secl/rules/ruleset.go b/pkg/security/secl/rules/ruleset.go index f4ace38dc36db..8b53f15a27992 100644 --- a/pkg/security/secl/rules/ruleset.go +++ b/pkg/security/secl/rules/ruleset.go @@ -148,7 +148,8 @@ func (rs *RuleSet) AddRules(parsingContext *ast.ParsingContext, pRules []*Policy return result } -func (rs *RuleSet) populateFieldsWithRuleActionsData(policyRules []*PolicyRule, opts PolicyLoaderOpts) *multierror.Error { +// PopulateFieldsWithRuleActionsData populates the fields with the data from the rule actions +func (rs *RuleSet) PopulateFieldsWithRuleActionsData(policyRules []*PolicyRule, opts PolicyLoaderOpts) *multierror.Error { var errs *multierror.Error for _, rule := range policyRules { @@ -764,7 +765,7 @@ func (rs *RuleSet) LoadPolicies(loader *PolicyLoader, opts PolicyLoaderOpts) *mu errs = multierror.Append(errs, err) } - if err := rs.populateFieldsWithRuleActionsData(allRules, opts); err.ErrorOrNil() != nil { + if err := rs.PopulateFieldsWithRuleActionsData(allRules, opts); err.ErrorOrNil() != nil { errs = multierror.Append(errs, err) } diff --git a/pkg/security/seclwin/model/accessors_win.go b/pkg/security/seclwin/model/accessors_win.go index 6b5734d296e4b..b3fc2f0d7b7af 100644 --- a/pkg/security/seclwin/model/accessors_win.go +++ b/pkg/security/seclwin/model/accessors_win.go @@ -9,9 +9,13 @@ package model import ( "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" + "math" "reflect" ) +// to always require the math package +var _ = math.MaxUint16 + func (m *Model) GetIterator(field eval.Field) (eval.Iterator, error) { switch field { case "process.ancestors": diff --git a/pkg/security/seclwin/model/consts_other.go b/pkg/security/seclwin/model/consts_win.go similarity index 83% rename from pkg/security/seclwin/model/consts_other.go rename to pkg/security/seclwin/model/consts_win.go index 5e778907eb22e..396c05a668fa4 100644 --- a/pkg/security/seclwin/model/consts_other.go +++ b/pkg/security/seclwin/model/consts_win.go @@ -3,15 +3,22 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. +// Package model holds model related files package model +const ( + // SIGKILL id for the kill action + SIGKILL = iota + 1 +) + var ( - errorConstants = map[string]int{} - // KernelCapabilityConstants list of kernel capabilities - KernelCapabilityConstants = map[string]uint64{} - // SignalConstants list of signals - SignalConstants = map[string]int{} + errorConstants = map[string]int{} addressFamilyConstants = map[string]uint16{} + + // SignalConstants list of signals + SignalConstants = map[string]int{ + "SIGKILL": SIGKILL, + } ) func initVMConstants() {} diff --git a/pkg/security/security_profile/dump/remote_storage.go b/pkg/security/security_profile/dump/remote_storage.go index b770651503cf1..9c9c8958eb303 100644 --- a/pkg/security/security_profile/dump/remote_storage.go +++ b/pkg/security/security_profile/dump/remote_storage.go @@ -12,6 +12,7 @@ import ( "bytes" "compress/gzip" "encoding/json" + "errors" "fmt" "mime/multipart" "net/http" @@ -20,6 +21,8 @@ import ( "go.uber.org/atomic" + "github.com/DataDog/datadog-go/v5/statsd" + logsconfig "github.com/DataDog/datadog-agent/comp/logs/agent/config" pkgconfig "github.com/DataDog/datadog-agent/pkg/config" "github.com/DataDog/datadog-agent/pkg/security/config" @@ -27,7 +30,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/seclog" "github.com/DataDog/datadog-agent/pkg/security/utils" ddhttputil "github.com/DataDog/datadog-agent/pkg/util/http" - "github.com/DataDog/datadog-go/v5/statsd" ) type tooLargeEntityStatsEntry struct { @@ -176,7 +178,7 @@ func (storage *ActivityDumpRemoteStorage) sendToEndpoint(url string, apiKey stri } storage.tooLargeEntities[entry].Inc() } - return fmt.Errorf(resp.Status) + return errors.New(resp.Status) } // Persist saves the provided buffer to the persistent storage diff --git a/pkg/security/tests/action_test.go b/pkg/security/tests/action_test.go index 9481d925b8184..a574b8d227054 100644 --- a/pkg/security/tests/action_test.go +++ b/pkg/security/tests/action_test.go @@ -19,7 +19,7 @@ import ( "testing" "time" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/security/ebpf/kernel" "github.com/avast/retry-go/v4" "github.com/oliveagle/jsonpath" @@ -34,7 +34,7 @@ func TestActionKill(t *testing.T) { if !ebpfLessEnabled { checkKernelCompatibility(t, "bpf_send_signal is not supported on this kernel and agent is running in container mode", func(kv *kernel.Version) bool { - return !kv.SupportBPFSendSignal() && config.IsContainerized() + return !kv.SupportBPFSendSignal() && env.IsContainerized() }) } @@ -194,7 +194,7 @@ func TestActionKillRuleSpecific(t *testing.T) { if !ebpfLessEnabled { checkKernelCompatibility(t, "bpf_send_signal is not supported on this kernel and agent is running in container mode", func(kv *kernel.Version) bool { - return !kv.SupportBPFSendSignal() && config.IsContainerized() + return !kv.SupportBPFSendSignal() && env.IsContainerized() }) } diff --git a/pkg/security/tests/dns_test.go b/pkg/security/tests/dns_test.go index 8f42c1ebe577e..b883c27f38f1b 100644 --- a/pkg/security/tests/dns_test.go +++ b/pkg/security/tests/dns_test.go @@ -18,7 +18,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/security/ebpf/kernel" "github.com/DataDog/datadog-agent/pkg/security/secl/model" "github.com/DataDog/datadog-agent/pkg/security/secl/rules" @@ -32,7 +32,7 @@ func TestDNS(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s,%v", string(out), err) } diff --git a/pkg/security/tests/files_generator.go b/pkg/security/tests/files_generator.go index cb9d617a62d84..5fc0a2e448590 100644 --- a/pkg/security/tests/files_generator.go +++ b/pkg/security/tests/files_generator.go @@ -348,7 +348,7 @@ func (fgc *FileGeneratorContext) start(wg *sync.WaitGroup) { fgc.mountWordDir() defer fgc.unmountWordDir() remountTicker := time.NewTicker(fgc.config.RemountEvery) - + defer remountTicker.Stop() var testEnd *time.Time started := false fgc.resetFirstStates() diff --git a/pkg/security/tests/imds_test.go b/pkg/security/tests/imds_test.go index 5821cbe261472..31d100c15c8c0 100644 --- a/pkg/security/tests/imds_test.go +++ b/pkg/security/tests/imds_test.go @@ -10,17 +10,18 @@ package tests import ( "fmt" - "github.com/DataDog/datadog-agent/pkg/config" - "github.com/DataDog/datadog-agent/pkg/security/ebpf/kernel" - "github.com/DataDog/datadog-agent/pkg/security/secl/model" - "github.com/DataDog/datadog-agent/pkg/security/secl/rules" - "github.com/DataDog/datadog-agent/pkg/security/tests/imds_utils" - "github.com/stretchr/testify/assert" "net/http" "os" "path" "syscall" "testing" + + "github.com/DataDog/datadog-agent/pkg/config/env" + "github.com/DataDog/datadog-agent/pkg/security/ebpf/kernel" + "github.com/DataDog/datadog-agent/pkg/security/secl/model" + "github.com/DataDog/datadog-agent/pkg/security/secl/rules" + "github.com/DataDog/datadog-agent/pkg/security/tests/imds_utils" + "github.com/stretchr/testify/assert" ) func TestAWSIMDSv1Request(t *testing.T) { @@ -31,7 +32,7 @@ func TestAWSIMDSv1Request(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() || kv.IsOpenSUSELeapKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s,%v", string(out), err) } @@ -104,7 +105,7 @@ func TestAWSIMDSv1Response(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() || kv.IsOpenSUSELeapKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s,%v", string(out), err) } @@ -185,7 +186,7 @@ func TestNoAWSIMDSv1Response(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() || kv.IsOpenSUSELeapKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s,%v", string(out), err) } @@ -252,7 +253,7 @@ func TestAWSIMDSv2Request(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() || kv.IsOpenSUSELeapKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s,%v", string(out), err) } @@ -335,7 +336,7 @@ func TestGCPIMDS(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() || kv.IsOpenSUSELeapKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s,%v", string(out), err) } @@ -413,7 +414,7 @@ func TestAzureIMDS(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() || kv.IsOpenSUSELeapKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s,%v", string(out), err) } @@ -491,7 +492,7 @@ func TestIBMIMDS(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() || kv.IsOpenSUSELeapKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s,%v", string(out), err) } @@ -569,7 +570,7 @@ func TestOracleIMDS(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() || kv.IsOpenSUSELeapKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s,%v", string(out), err) } @@ -647,7 +648,7 @@ func TestIMDSProcessContext(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() || kv.IsOpenSUSELeapKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s,%v", string(out), err) } diff --git a/pkg/security/tests/module_tester_linux.go b/pkg/security/tests/module_tester_linux.go index 1062f206d4379..46568b1074163 100644 --- a/pkg/security/tests/module_tester_linux.go +++ b/pkg/security/tests/module_tester_linux.go @@ -34,9 +34,11 @@ import ( "github.com/stretchr/testify/assert" "golang.org/x/sys/unix" + "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/core/telemetry" "github.com/DataDog/datadog-agent/comp/core/telemetry/telemetryimpl" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + wmmock "github.com/DataDog/datadog-agent/comp/core/workloadmeta/fx-mock" ebpftelemetry "github.com/DataDog/datadog-agent/pkg/ebpf/telemetry" "github.com/DataDog/datadog-agent/pkg/eventmonitor" secconfig "github.com/DataDog/datadog-agent/pkg/security/config" @@ -60,7 +62,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/util/fxutil" utilkernel "github.com/DataDog/datadog-agent/pkg/util/kernel" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) var ( @@ -790,7 +791,11 @@ func newTestModuleWithOnDemandProbes(t testing.TB, onDemandHooks []rules.OnDeman emopts.ProbeOpts.TagsResolver = NewFakeResolverDifferentImageNames() } telemetry := fxutil.Test[telemetry.Component](t, telemetryimpl.MockModule()) - testMod.eventMonitor, err = eventmonitor.NewEventMonitor(emconfig, secconfig, emopts, optional.NewNoneOption[workloadmeta.Component](), telemetry) + wmeta := fxutil.Test[workloadmeta.Component](t, + core.MockBundle(), + wmmock.MockModule(workloadmeta.NewParams()), + ) + testMod.eventMonitor, err = eventmonitor.NewEventMonitor(emconfig, secconfig, emopts, wmeta, telemetry) if err != nil { return nil, err } diff --git a/pkg/security/tests/module_tester_windows.go b/pkg/security/tests/module_tester_windows.go index 0a5c90712d1e4..e494bf347a558 100644 --- a/pkg/security/tests/module_tester_windows.go +++ b/pkg/security/tests/module_tester_windows.go @@ -18,9 +18,11 @@ import ( "github.com/hashicorp/go-multierror" + "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/core/telemetry" "github.com/DataDog/datadog-agent/comp/core/telemetry/telemetryimpl" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + wmmock "github.com/DataDog/datadog-agent/comp/core/workloadmeta/fx-mock" "github.com/DataDog/datadog-agent/pkg/eventmonitor" secconfig "github.com/DataDog/datadog-agent/pkg/security/config" "github.com/DataDog/datadog-agent/pkg/security/events" @@ -33,7 +35,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/tests/statsdclient" "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/DataDog/datadog-agent/pkg/util/log" - "github.com/DataDog/datadog-agent/pkg/util/optional" ) var ( @@ -265,7 +266,11 @@ func newTestModule(t testing.TB, macroDefs []*rules.MacroDefinition, ruleDefs [] }, } telemetry := fxutil.Test[telemetry.Component](t, telemetryimpl.MockModule()) - testMod.eventMonitor, err = eventmonitor.NewEventMonitor(emconfig, secconfig, emopts, optional.NewNoneOption[workloadmeta.Component](), telemetry) + wmeta := fxutil.Test[workloadmeta.Component](t, + core.MockBundle(), + wmmock.MockModule(workloadmeta.NewParams()), + ) + testMod.eventMonitor, err = eventmonitor.NewEventMonitor(emconfig, secconfig, emopts, wmeta, telemetry) if err != nil { return nil, err } diff --git a/pkg/security/tests/network_device_test.go b/pkg/security/tests/network_device_test.go index 9a4df7759723a..c7967282bb6e6 100644 --- a/pkg/security/tests/network_device_test.go +++ b/pkg/security/tests/network_device_test.go @@ -22,7 +22,7 @@ import ( "github.com/vishvananda/netns" "golang.org/x/sys/unix" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/security/ebpf/kernel" sprobe "github.com/DataDog/datadog-agent/pkg/security/probe" "github.com/DataDog/datadog-agent/pkg/security/secl/model" @@ -38,7 +38,7 @@ func TestNetDevice(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s, %v", string(out), err) } diff --git a/pkg/security/tests/network_test.go b/pkg/security/tests/network_test.go index fda04186efbce..0605292cd9b6b 100644 --- a/pkg/security/tests/network_test.go +++ b/pkg/security/tests/network_test.go @@ -17,7 +17,7 @@ import ( "github.com/docker/docker/libnetwork/resolvconf" "github.com/stretchr/testify/assert" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/security/ebpf/kernel" "github.com/DataDog/datadog-agent/pkg/security/secl/model" "github.com/DataDog/datadog-agent/pkg/security/secl/rules" @@ -31,7 +31,7 @@ func TestNetworkCIDR(t *testing.T) { return kv.IsRH7Kernel() || kv.IsOracleUEKKernel() || kv.IsSLESKernel() }) - if testEnvironment != DockerEnvironment && !config.IsContainerized() { + if testEnvironment != DockerEnvironment && !env.IsContainerized() { if out, err := loadModule("veth"); err != nil { t.Fatalf("couldn't load 'veth' module: %s, %v", string(out), err) } diff --git a/pkg/serializer/go.mod b/pkg/serializer/go.mod index 3c1ee88635775..b77ce66b7ddaa 100644 --- a/pkg/serializer/go.mod +++ b/pkg/serializer/go.mod @@ -21,6 +21,7 @@ replace ( github.com/DataDog/datadog-agent/pkg/collector/check/defaults => ../collector/check/defaults github.com/DataDog/datadog-agent/pkg/config/env => ../config/env github.com/DataDog/datadog-agent/pkg/config/logs => ../config/logs/ + github.com/DataDog/datadog-agent/pkg/config/mock => ../config/mock github.com/DataDog/datadog-agent/pkg/config/model => ../config/model github.com/DataDog/datadog-agent/pkg/config/setup => ../config/setup/ github.com/DataDog/datadog-agent/pkg/config/utils => ../config/utils/ @@ -93,6 +94,7 @@ require ( github.com/DataDog/datadog-agent/comp/def v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/collector/check/defaults v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/config/env v0.56.0-rc.3 // indirect + github.com/DataDog/datadog-agent/pkg/config/mock v0.58.0-devel // indirect github.com/DataDog/datadog-agent/pkg/config/utils v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/orchestrator/model v0.56.0-rc.3 // indirect github.com/DataDog/datadog-agent/pkg/status/health v0.56.0-rc.3 // indirect @@ -169,17 +171,17 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.18.2 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/serializer/go.sum b/pkg/serializer/go.sum index 8f7534bf4498e..d952c59d01660 100644 --- a/pkg/serializer/go.sum +++ b/pkg/serializer/go.sum @@ -25,8 +25,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -303,10 +301,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -324,8 +322,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U 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-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -348,8 +346,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/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.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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= @@ -377,12 +375,12 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -399,8 +397,8 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn 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/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/pkg/serverless/appsec/appsec.go b/pkg/serverless/appsec/appsec.go index 90b2634f105f8..86176b7b140c7 100644 --- a/pkg/serverless/appsec/appsec.go +++ b/pkg/serverless/appsec/appsec.go @@ -11,6 +11,7 @@ import ( "context" "errors" "math/rand" + "os" "time" appsecLog "github.com/DataDog/appsec-internal-go/log" @@ -44,11 +45,16 @@ func NewWithShutdown(demux aggregator.Demultiplexer) (lp *httpsec.ProxyLifecycle return nil, nil, nil // appsec disabled } + lambdaRuntimeAPI := os.Getenv("AWS_LAMBDA_RUNTIME_API") + if lambdaRuntimeAPI == "" { + lambdaRuntimeAPI = "127.0.0.1:9001" + } + // AppSec monitors the invocations by acting as a proxy of the AWS Lambda Runtime API. lp = httpsec.NewProxyLifecycleProcessor(appsecInstance, demux) shutdownProxy := proxy.Start( "127.0.0.1:9000", - "127.0.0.1:9001", + lambdaRuntimeAPI, lp, ) log.Debug("appsec: started successfully using the runtime api proxy monitoring mode") diff --git a/pkg/serverless/daemon/daemon_test.go b/pkg/serverless/daemon/daemon_test.go index 8d215793f3f62..dc44e72597b5d 100644 --- a/pkg/serverless/daemon/daemon_test.go +++ b/pkg/serverless/daemon/daemon_test.go @@ -10,6 +10,7 @@ import ( "net/http" "os" "reflect" + "runtime" "sync" "testing" "time" @@ -177,6 +178,9 @@ func TestSetTraceTagOk(t *testing.T) { } func TestOutOfOrderInvocations(t *testing.T) { + if os.Getenv("CI") == "true" && runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" { + t.Skip("TestOutOfOrderInvocations is known to fail on the macOS Gitlab runners because of the already running Agent") + } port := testutil.FreeTCPPort(t) d := StartDaemon(fmt.Sprint("127.0.0.1:", port)) defer d.Stop() diff --git a/pkg/serverless/metrics/metric_test.go b/pkg/serverless/metrics/metric_test.go index bea2e2737c3cb..2b07a3e07f00d 100644 --- a/pkg/serverless/metrics/metric_test.go +++ b/pkg/serverless/metrics/metric_test.go @@ -12,6 +12,7 @@ import ( "net" "net/http" "os" + "runtime" "strconv" "sync" "testing" @@ -35,6 +36,9 @@ func TestMain(m *testing.M) { } func TestStartDoesNotBlock(t *testing.T) { + if os.Getenv("CI") == "true" && runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" { + t.Skip("TestStartDoesNotBlock is known to fail on the macOS Gitlab runners because of the already running Agent") + } config.LoadWithoutSecret() metricAgent := &ServerlessMetricAgent{ SketchesBucketOffset: time.Second * 10, @@ -107,6 +111,9 @@ func TestStartWithProxy(t *testing.T) { } func TestRaceFlushVersusAddSample(t *testing.T) { + if os.Getenv("CI") == "true" && runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" { + t.Skip("TestRaceFlushVersusAddSample is known to fail on the macOS Gitlab runners because of the already running Agent") + } metricAgent := &ServerlessMetricAgent{ SketchesBucketOffset: time.Second * 10, } diff --git a/pkg/serverless/proxy/proxy_test.go b/pkg/serverless/proxy/proxy_test.go index ddde58aaa949b..8bd014ea7de17 100644 --- a/pkg/serverless/proxy/proxy_test.go +++ b/pkg/serverless/proxy/proxy_test.go @@ -12,6 +12,8 @@ import ( "net" "net/http" "net/http/httptest" + "os" + "runtime" "strings" "testing" "time" @@ -67,6 +69,9 @@ func (tp *testProcessorResponseError) GetExecutionInfo() *invocationlifecycle.Ex } func TestProxyResponseValid(t *testing.T) { + if os.Getenv("CI") == "true" && runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" { + t.Skip("TestProxyResponseValid is known to fail on the macOS Gitlab runners because of the already running Agent") + } // fake the runtime API running on 5001 l, err := net.Listen("tcp", "127.0.0.1:5001") assert.Nil(t, err) diff --git a/pkg/serverless/trace/trace.go b/pkg/serverless/trace/trace.go index 438b1157287b0..85d24eff9469f 100644 --- a/pkg/serverless/trace/trace.go +++ b/pkg/serverless/trace/trace.go @@ -8,6 +8,7 @@ package trace import ( "context" "fmt" + "os" "strings" "github.com/DataDog/datadog-agent/cmd/serverless-init/cloudservice" @@ -60,8 +61,8 @@ const tcpRemotePortMetaKey = "tcp.remote.port" // dnsAddressMetaKey is the key of the span meta containing the DNS address const dnsAddressMetaKey = "dns.address" -// lambdaRuntimeUrlPrefix is the first part of a URL for a call to the Lambda runtime API -const lambdaRuntimeURLPrefix = "http://127.0.0.1:9001" +// lambdaRuntimeUrlPrefix is the first part of a URL for a call to the Lambda runtime API. The value may be replaced if `AWS_LAMBDA_RUNTIME_API` is set. +var lambdaRuntimeURLPrefix = "http://127.0.0.1:9001" // lambdaExtensionURLPrefix is the first part of a URL for a call from the Datadog Lambda Library to the Lambda Extension const lambdaExtensionURLPrefix = "http://127.0.0.1:8124" @@ -257,3 +258,9 @@ func (t noopTraceAgent) SetTags(map[string]string) {} func (t noopTraceAgent) SetTargetTPS(float64) {} func (t noopTraceAgent) SetSpanModifier(agent.SpanModifier) {} func (t noopTraceAgent) GetSpanModifier() agent.SpanModifier { return nil } + +func init() { + if lambdaRuntime := os.Getenv("AWS_LAMBDA_RUNTIME_API"); lambdaRuntime != "" { + lambdaRuntimeURLPrefix = fmt.Sprintf("http://%s", lambdaRuntime) + } +} diff --git a/pkg/serverless/trace/trace_test.go b/pkg/serverless/trace/trace_test.go index 870cf26383a3e..c9d0c0355dc67 100644 --- a/pkg/serverless/trace/trace_test.go +++ b/pkg/serverless/trace/trace_test.go @@ -59,7 +59,7 @@ func TestStartEnabledTrueInvalidConfig(t *testing.T) { assert.IsType(t, noopTraceAgent{}, agent) } -func TestStartEnabledTrueValidConfigUnvalidPath(t *testing.T) { +func TestStartEnabledTrueValidConfigInvalidPath(t *testing.T) { setupTraceAgentTest(t) lambdaSpanChan := make(chan *pb.Span) diff --git a/pkg/snmp/gosnmplib/gosnmp_log.go b/pkg/snmp/gosnmplib/gosnmp_log.go index ff8dec9d845d3..908c2a0d99838 100644 --- a/pkg/snmp/gosnmplib/gosnmp_log.go +++ b/pkg/snmp/gosnmplib/gosnmp_log.go @@ -52,6 +52,6 @@ func (sw *TraceLevelLogWriter) Write(logInput []byte) (n int, err error) { logInput = replacer.Regex.ReplaceAll(logInput, replacer.Repl) } } - log.Tracef(string(logInput)) + log.Trace(string(logInput)) return len(logInput), nil } diff --git a/pkg/telemetry/go.mod b/pkg/telemetry/go.mod index 9e0e98119c70f..5ff9c443af1a4 100644 --- a/pkg/telemetry/go.mod +++ b/pkg/telemetry/go.mod @@ -40,11 +40,11 @@ require ( 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.uber.org/dig v1.17.0 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.23.0 // indirect - golang.org/x/sys v0.23.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/sys v0.24.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/telemetry/go.sum b/pkg/telemetry/go.sum index a0165a70e28ad..3854bdf57a7da 100644 --- a/pkg/telemetry/go.sum +++ b/pkg/telemetry/go.sum @@ -1,5 +1,3 @@ -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -28,8 +26,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= @@ -65,19 +61,19 @@ go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5 go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/pkg/trace/api/api.go b/pkg/trace/api/api.go index 4a1273f6df9ea..816a14eef938d 100644 --- a/pkg/trace/api/api.go +++ b/pkg/trace/api/api.go @@ -853,3 +853,12 @@ func getMediaType(req *http.Request) string { } return mt } + +// normalizeHTTPHeader takes a raw string and normalizes the value to be compatible +// with an HTTP header value. +func normalizeHTTPHeader(val string) string { + val = strings.ReplaceAll(val, "\r\n", "_") + val = strings.ReplaceAll(val, "\r", "_") + val = strings.ReplaceAll(val, "\n", "_") + return val +} diff --git a/pkg/trace/api/api_test.go b/pkg/trace/api/api_test.go index a922f2f7d57e7..1f4574315d344 100644 --- a/pkg/trace/api/api_test.go +++ b/pkg/trace/api/api_test.go @@ -219,7 +219,7 @@ func TestLegacyReceiver(t *testing.T) { } for _, tc := range testCases { - t.Run(fmt.Sprintf(tc.name), func(t *testing.T) { + t.Run(tc.name, func(t *testing.T) { // start testing server server := httptest.NewServer( tc.r.handleWithVersion(tc.apiVersion, tc.r.handleTraces), @@ -284,7 +284,7 @@ func TestReceiverJSONDecoder(t *testing.T) { } for _, tc := range testCases { - t.Run(fmt.Sprintf(tc.name), func(t *testing.T) { + t.Run(tc.name, func(t *testing.T) { // start testing server server := httptest.NewServer( tc.r.handleWithVersion(tc.apiVersion, tc.r.handleTraces), @@ -344,7 +344,7 @@ func TestReceiverMsgpackDecoder(t *testing.T) { } for _, tc := range testCases { - t.Run(fmt.Sprintf(tc.name), func(t *testing.T) { + t.Run(tc.name, func(t *testing.T) { // start testing server server := httptest.NewServer( tc.r.handleWithVersion(tc.apiVersion, tc.r.handleTraces), @@ -1057,6 +1057,61 @@ func TestExpvar(t *testing.T) { }) } +func TestNormalizeHTTPHeader(t *testing.T) { + tests := []struct { + input string + expected string + }{ + { + input: "Header: value\nAnother header: value", + expected: "Header: value_Another header: value", + }, + { + input: "Header: value\rAnother header: value", + expected: "Header: value_Another header: value", + }, + { + input: "Header: value\r\nAnother header: value", + expected: "Header: value_Another header: value", + }, + { + input: "SingleLineHeader: value", + expected: "SingleLineHeader: value", + }, + { + input: "\rLeading carriage return", + expected: "_Leading carriage return", + }, + { + input: "\nLeading line break", + expected: "_Leading line break", + }, + { + input: "Trailing carriage return\r", + expected: "Trailing carriage return_", + }, + { + input: "Trailing line break\n", + expected: "Trailing line break_", + }, + { + input: "Multiple\r\nline\r\nbreaks", + expected: "Multiple_line_breaks", + }, + { + input: "", + expected: "", + }, + } + + for _, test := range tests { + result := normalizeHTTPHeader(test.input) + if result != test.expected { + t.Errorf("normalizeHTTPHeader(%q) = %q; expected %q", test.input, result, test.expected) + } + } +} + func msgpTraces(t *testing.T, traces pb.Traces) []byte { bts, err := traces.MarshalMsg(nil) if err != nil { diff --git a/pkg/trace/api/evp_proxy.go b/pkg/trace/api/evp_proxy.go index 06372828a8581..4ab15b70ab36f 100644 --- a/pkg/trace/api/evp_proxy.go +++ b/pkg/trace/api/evp_proxy.go @@ -164,8 +164,9 @@ func (t *evpProxyTransport) RoundTrip(req *http.Request) (rresp *http.Response, if containerID != "" { req.Header.Set(header.ContainerID, containerID) if ctags := getContainerTags(t.conf.ContainerTags, containerID); ctags != "" { - req.Header.Set("X-Datadog-Container-Tags", ctags) - log.Debugf("Setting header X-Datadog-Container-Tags=%s for evp proxy", ctags) + ctagsHeader := normalizeHTTPHeader(ctags) + req.Header.Set("X-Datadog-Container-Tags", ctagsHeader) + log.Debugf("Setting header X-Datadog-Container-Tags=%s for evp proxy", ctagsHeader) } } req.Header.Set("X-Datadog-Hostname", t.conf.Hostname) diff --git a/pkg/trace/api/evp_proxy_test.go b/pkg/trace/api/evp_proxy_test.go index 2424a4b125e58..3016b6e5ef53c 100644 --- a/pkg/trace/api/evp_proxy_test.go +++ b/pkg/trace/api/evp_proxy_test.go @@ -161,6 +161,27 @@ func TestEVPProxyForwarder(t *testing.T) { assert.Equal(t, "", logs) }) + t.Run("normalizedContainerTags", func(t *testing.T) { + conf := newTestReceiverConfig() + conf.Site = "us3.datadoghq.com" + conf.Endpoints[0].APIKey = "test_api_key" + conf.ContainerTags = func(cid string) ([]string, error) { + return []string{"container:" + cid, "key:\nval"}, nil + } + + req := httptest.NewRequest("POST", "/mypath/mysubpath?arg=test", bytes.NewReader(randBodyBuf)) + req.Header.Set("X-Datadog-EVP-Subdomain", "my.subdomain") + req.Header.Set(header.ContainerID, "myid") + proxyreqs, resp, logs := sendRequestThroughForwarderWithMockRoundTripper(conf, req, stats) + + resp.Body.Close() + require.Equal(t, http.StatusOK, resp.StatusCode, "Got: ", fmt.Sprint(resp.StatusCode)) + require.Len(t, proxyreqs, 1) + assert.Equal(t, "container:myid,key:_val", proxyreqs[0].Header.Get("X-Datadog-Container-Tags")) + assert.Equal(t, "myid", proxyreqs[0].Header.Get(header.ContainerID)) + assert.Equal(t, "", logs) + }) + t.Run("dual-shipping", func(t *testing.T) { conf := newTestReceiverConfig() conf.Site = "us3.datadoghq.com" diff --git a/pkg/trace/api/pipeline_stats.go b/pkg/trace/api/pipeline_stats.go index b42922e4f21d3..b6fe3f2cd161c 100644 --- a/pkg/trace/api/pipeline_stats.go +++ b/pkg/trace/api/pipeline_stats.go @@ -82,8 +82,9 @@ func newPipelineStatsProxy(conf *config.AgentConfig, urls []*url.URL, apiKeys [] } containerID := cidProvider.GetContainerID(req.Context(), req.Header) if ctags := getContainerTags(conf.ContainerTags, containerID); ctags != "" { - req.Header.Set("X-Datadog-Container-Tags", ctags) - log.Debugf("Setting header X-Datadog-Container-Tags=%s for pipeline stats proxy", ctags) + ctagsHeader := normalizeHTTPHeader(ctags) + req.Header.Set("X-Datadog-Container-Tags", ctagsHeader) + log.Debugf("Setting header X-Datadog-Container-Tags=%s for pipeline stats proxy", ctagsHeader) } req.Header.Set("X-Datadog-Additional-Tags", tags) log.Debugf("Setting header X-Datadog-Additional-Tags=%s for pipeline stats proxy", tags) diff --git a/pkg/trace/api/profiles.go b/pkg/trace/api/profiles.go index 36b54150c9013..7584c50e1b360 100644 --- a/pkg/trace/api/profiles.go +++ b/pkg/trace/api/profiles.go @@ -116,8 +116,9 @@ func newProfileProxy(conf *config.AgentConfig, targets []*url.URL, keys []string } containerID := cidProvider.GetContainerID(req.Context(), req.Header) if ctags := getContainerTags(conf.ContainerTags, containerID); ctags != "" { - req.Header.Set("X-Datadog-Container-Tags", ctags) - log.Debugf("Setting header X-Datadog-Container-Tags=%s for profiles proxy", ctags) + ctagsHeader := normalizeHTTPHeader(ctags) + req.Header.Set("X-Datadog-Container-Tags", ctagsHeader) + log.Debugf("Setting header X-Datadog-Container-Tags=%s for profiles proxy", ctagsHeader) } req.Header.Set("X-Datadog-Additional-Tags", tags) log.Debugf("Setting header X-Datadog-Additional-Tags=%s for profiles proxy", tags) diff --git a/pkg/trace/api/telemetry_test.go b/pkg/trace/api/telemetry_test.go index e5c76bc14524f..5c37737da22ae 100644 --- a/pkg/trace/api/telemetry_test.go +++ b/pkg/trace/api/telemetry_test.go @@ -295,7 +295,7 @@ func TestMaxInflightBytes(t *testing.T) { done := make(chan struct{}) - srv := assertingServer(t, func(req *http.Request, body []byte) error { + srv := assertingServer(t, func(req *http.Request, _ []byte) error { assert.Equal("test_apikey", req.Header.Get("DD-API-KEY")) assert.Equal("test_hostname", req.Header.Get("DD-Agent-Hostname")) assert.Equal("test_env", req.Header.Get("DD-Agent-Env")) @@ -339,7 +339,7 @@ func TestInflightBytesReset(t *testing.T) { done := make(chan struct{}) - srv := assertingServer(t, func(req *http.Request, body []byte) error { + srv := assertingServer(t, func(req *http.Request, _ []byte) error { assert.Equal("test_apikey", req.Header.Get("DD-API-KEY")) assert.Equal("test_hostname", req.Header.Get("DD-Agent-Hostname")) assert.Equal("test_env", req.Header.Get("DD-Agent-Env")) @@ -397,7 +397,7 @@ func TestActualServer(t *testing.T) { done := make(chan struct{}) - intakeMockServer := assertingServer(t, func(req *http.Request, body []byte) error { + intakeMockServer := assertingServer(t, func(req *http.Request, _ []byte) error { assert.Equal("test_apikey", req.Header.Get("DD-API-KEY")) assert.Equal("test_hostname", req.Header.Get("DD-Agent-Hostname")) assert.Equal("test_env", req.Header.Get("DD-Agent-Env")) diff --git a/pkg/trace/filters/replacer.go b/pkg/trace/filters/replacer.go index 2616b0c46326d..7d243b21b4133 100644 --- a/pkg/trace/filters/replacer.go +++ b/pkg/trace/filters/replacer.go @@ -86,7 +86,7 @@ func (f Replacer) ReplaceStatsGroup(b *pb.ClientGroupedStats) { b.Resource = re.ReplaceAllString(b.Resource, str) fallthrough case "http.status_code": - strcode := re.ReplaceAllString(strconv.Itoa(int(b.HTTPStatusCode)), str) + strcode := re.ReplaceAllString(strconv.FormatUint(uint64(b.HTTPStatusCode), 10), str) if code, err := strconv.ParseUint(strcode, 10, 32); err == nil { b.HTTPStatusCode = uint32(code) } diff --git a/pkg/trace/go.mod b/pkg/trace/go.mod index ab7c371ec4c07..512debc4740e6 100644 --- a/pkg/trace/go.mod +++ b/pkg/trace/go.mod @@ -44,7 +44,7 @@ require ( go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/metric v1.27.0 go.uber.org/atomic v1.11.0 - golang.org/x/sys v0.23.0 + golang.org/x/sys v0.24.0 golang.org/x/time v0.6.0 google.golang.org/grpc v1.64.0 google.golang.org/protobuf v1.34.2 @@ -102,10 +102,10 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/pkg/trace/go.sum b/pkg/trace/go.sum index fc33db8342eb0..9ae6fe28770bc 100644 --- a/pkg/trace/go.sum +++ b/pkg/trace/go.sum @@ -309,8 +309,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= @@ -339,8 +339,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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= @@ -371,8 +371,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -382,8 +382,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -397,8 +397,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/pkg/trace/stats/client_stats_aggregator.go b/pkg/trace/stats/client_stats_aggregator.go index 3d8d33423b706..0c3e8fef49ca9 100644 --- a/pkg/trace/stats/client_stats_aggregator.go +++ b/pkg/trace/stats/client_stats_aggregator.go @@ -101,6 +101,7 @@ func (a *ClientStatsAggregator) Start() { // Stop stops the aggregator. Calling Stop twice will panic. func (a *ClientStatsAggregator) Stop() { close(a.exit) + a.flushTicker.Stop() <-a.done } diff --git a/pkg/trace/stats/oteltest/go.mod b/pkg/trace/stats/oteltest/go.mod index c29e45b1ed47b..7ba2f55d9b746 100644 --- a/pkg/trace/stats/oteltest/go.mod +++ b/pkg/trace/stats/oteltest/go.mod @@ -78,12 +78,12 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect google.golang.org/grpc v1.64.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/pkg/trace/stats/oteltest/go.sum b/pkg/trace/stats/oteltest/go.sum index d04b9f5c249c8..dcf72c47c645c 100644 --- a/pkg/trace/stats/oteltest/go.sum +++ b/pkg/trace/stats/oteltest/go.sum @@ -193,8 +193,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= 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/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -210,8 +210,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/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= @@ -238,8 +238,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -247,8 +247,8 @@ 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -258,8 +258,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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= diff --git a/pkg/trace/writer/trace.go b/pkg/trace/writer/trace.go index 205df6762c713..2a7b5ab6b9314 100644 --- a/pkg/trace/writer/trace.go +++ b/pkg/trace/writer/trace.go @@ -138,6 +138,7 @@ func NewTraceWriter( func (w *TraceWriter) reporter() { tck := time.NewTicker(w.tick) + defer tck.Stop() defer w.wg.Done() for { select { @@ -172,6 +173,7 @@ func (w *TraceWriter) Stop() { w.wg.Wait() w.flush() stopSenders(w.senders) + w.flushTicker.Stop() } // FlushSync blocks and sends pending payloads when syncMode is true diff --git a/pkg/util/cgroups/go.mod b/pkg/util/cgroups/go.mod index c1c856a9e9202..7dfa89b8dd857 100644 --- a/pkg/util/cgroups/go.mod +++ b/pkg/util/cgroups/go.mod @@ -27,7 +27,7 @@ require ( github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect google.golang.org/protobuf v1.27.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/pkg/util/cgroups/go.sum b/pkg/util/cgroups/go.sum index 39e364bea65c1..bf585efcca6d6 100644 --- a/pkg/util/cgroups/go.sum +++ b/pkg/util/cgroups/go.sum @@ -24,8 +24,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= diff --git a/pkg/util/cloudproviders/kubernetes/kubernetes.go b/pkg/util/cloudproviders/kubernetes/kubernetes.go index 5d8f222458a1a..4354f5edcbd4a 100644 --- a/pkg/util/cloudproviders/kubernetes/kubernetes.go +++ b/pkg/util/cloudproviders/kubernetes/kubernetes.go @@ -12,6 +12,7 @@ import ( "fmt" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/kubernetes/hostinfo" ) @@ -22,7 +23,7 @@ var ( // GetHostAliases returns the host aliases from the Kubernetes node annotations func GetHostAliases(ctx context.Context) ([]string, error) { - if !config.IsFeaturePresent(config.Kubernetes) { + if !env.IsFeaturePresent(env.Kubernetes) { return []string{}, nil } diff --git a/pkg/util/clusteragent/clusteragent.go b/pkg/util/clusteragent/clusteragent.go index aa1f63b9f55e8..46b2ddb98eb81 100644 --- a/pkg/util/clusteragent/clusteragent.go +++ b/pkg/util/clusteragent/clusteragent.go @@ -151,8 +151,9 @@ func (c *DCAClient) startReconnectHandler(reconnectPeriod time.Duration) { return } - t := time.NewTicker(reconnectPeriod) go func() { + t := time.NewTicker(reconnectPeriod) + defer t.Stop() for { <-t.C err := c.initHTTPClient() diff --git a/pkg/util/containerd/containerd_util.go b/pkg/util/containerd/containerd_util.go index 1b9b043b09268..502b237db28eb 100644 --- a/pkg/util/containerd/containerd_util.go +++ b/pkg/util/containerd/containerd_util.go @@ -19,6 +19,7 @@ import ( "github.com/opencontainers/image-spec/identity" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" dderrors "github.com/DataDog/datadog-agent/pkg/errors" "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/DataDog/datadog-agent/pkg/util/retry" @@ -26,11 +27,11 @@ import ( "github.com/containerd/containerd" "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/containers" - "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/leases" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/oci" + "github.com/containerd/errdefs" ) const ( @@ -453,7 +454,7 @@ func (c *ContainerdUtil) getMounts(ctx context.Context, expiration time.Duration } // Transforming mounts in case we're running in a container - if config.IsContainerized() { + if env.IsContainerized() { for i := range mounts { mounts[i].Source = strings.ReplaceAll(mounts[i].Source, "/var/lib", "/host/var/lib") for j := range mounts[i].Options { diff --git a/pkg/util/containers/filter.go b/pkg/util/containers/filter.go index b9994718702e4..a0c389dfdde63 100644 --- a/pkg/util/containers/filter.go +++ b/pkg/util/containers/filter.go @@ -134,7 +134,7 @@ func parseFilters(filters []string) (imageFilters, nameFilters, namespaceFilters namespaceFilters = append(namespaceFilters, r) default: warnmsg := fmt.Sprintf("Container filter %q is unknown, ignoring it. The supported filters are 'image', 'name' and 'kube_namespace'", filter) - log.Warnf(warnmsg) + log.Warn(warnmsg) filterWarnings = append(filterWarnings, warnmsg) } diff --git a/pkg/util/containers/metrics/containerd/collector.go b/pkg/util/containers/metrics/containerd/collector.go index 08ac3ae32401d..32796977df88b 100644 --- a/pkg/util/containers/metrics/containerd/collector.go +++ b/pkg/util/containers/metrics/containerd/collector.go @@ -18,7 +18,7 @@ import ( "google.golang.org/protobuf/types/known/anypb" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/containerd" "github.com/DataDog/datadog-agent/pkg/util/optional" @@ -53,7 +53,7 @@ type containerdCollector struct { func newContainerdCollector(cache *provider.Cache) (provider.CollectorMetadata, error) { var collectorMetadata provider.CollectorMetadata - if !config.IsFeaturePresent(config.Containerd) { + if !env.IsFeaturePresent(env.Containerd) { return collectorMetadata, provider.ErrPermaFail } diff --git a/pkg/util/containers/metrics/containerd/collector_linux_test.go b/pkg/util/containers/metrics/containerd/collector_linux_test.go index d127c330bdc4c..443fa65688b56 100644 --- a/pkg/util/containers/metrics/containerd/collector_linux_test.go +++ b/pkg/util/containers/metrics/containerd/collector_linux_test.go @@ -287,8 +287,7 @@ func TestGetContainerStats_Containerd(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) workloadmetaStore.Set(&workloadmeta.Container{ @@ -386,8 +385,7 @@ func TestGetContainerNetworkStats_Containerd(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) workloadmetaStore.Set(&workloadmeta.Container{ diff --git a/pkg/util/containers/metrics/containerd/collector_windows_test.go b/pkg/util/containers/metrics/containerd/collector_windows_test.go index 86a18cfe25fd6..99eccf1ecd489 100644 --- a/pkg/util/containers/metrics/containerd/collector_windows_test.go +++ b/pkg/util/containers/metrics/containerd/collector_windows_test.go @@ -109,8 +109,7 @@ func TestGetContainerStats_Containerd(t *testing.T) { workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) workloadmetaStore.Set(&workloadmeta.Container{ @@ -175,8 +174,7 @@ func TestGetContainerNetworkStats_Containerd(t *testing.T) { workloadmetaStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) workloadmetaStore.Set(&workloadmeta.Container{ diff --git a/pkg/util/containers/metrics/cri/collector.go b/pkg/util/containers/metrics/cri/collector.go index 76636baed79bb..be41ce4bd4ea3 100644 --- a/pkg/util/containers/metrics/cri/collector.go +++ b/pkg/util/containers/metrics/cri/collector.go @@ -13,7 +13,7 @@ import ( v1 "k8s.io/cri-api/pkg/apis/runtime/v1" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/containers/cri" "github.com/DataDog/datadog-agent/pkg/util/containers/metrics/provider" "github.com/DataDog/datadog-agent/pkg/util/optional" @@ -41,7 +41,7 @@ type criCollector struct { func newCRICollector(cache *provider.Cache) (provider.CollectorMetadata, error) { var collectorMetadata provider.CollectorMetadata - if !config.IsFeaturePresent(config.Cri) { + if !env.IsFeaturePresent(env.Cri) { return collectorMetadata, provider.ErrPermaFail } diff --git a/pkg/util/containers/metrics/docker/collector.go b/pkg/util/containers/metrics/docker/collector.go index 33df5b128e1a6..12c06bc84f1e9 100644 --- a/pkg/util/containers/metrics/docker/collector.go +++ b/pkg/util/containers/metrics/docker/collector.go @@ -18,7 +18,7 @@ import ( "github.com/docker/docker/api/types" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/containers/metrics/provider" "github.com/DataDog/datadog-agent/pkg/util/docker" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -52,7 +52,7 @@ type dockerCollector struct { func newDockerCollector(cache *provider.Cache, wmeta optional.Option[workloadmeta.Component]) (provider.CollectorMetadata, error) { var collectorMetadata provider.CollectorMetadata - if !config.IsFeaturePresent(config.Docker) { + if !env.IsFeaturePresent(env.Docker) { return collectorMetadata, provider.ErrPermaFail } diff --git a/pkg/util/containers/metrics/docker/collector_test.go b/pkg/util/containers/metrics/docker/collector_test.go index 43bd1a14107a2..a0d6fc94d12f7 100644 --- a/pkg/util/containers/metrics/docker/collector_test.go +++ b/pkg/util/containers/metrics/docker/collector_test.go @@ -89,8 +89,7 @@ func TestGetContainerIDForPID(t *testing.T) { mockStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( config.MockModule(), fx.Provide(func() log.Component { return logmock.New(t) }), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) collector := dockerCollector{ diff --git a/pkg/util/containers/metrics/ecsfargate/collector.go b/pkg/util/containers/metrics/ecsfargate/collector.go index 5bc809112b17d..0a8ccf85ac5af 100644 --- a/pkg/util/containers/metrics/ecsfargate/collector.go +++ b/pkg/util/containers/metrics/ecsfargate/collector.go @@ -15,7 +15,7 @@ import ( "time" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/containers/metrics/provider" "github.com/DataDog/datadog-agent/pkg/util/ecs/metadata" v2 "github.com/DataDog/datadog-agent/pkg/util/ecs/metadata/v2" @@ -57,7 +57,7 @@ type ecsFargateCollector struct { func newEcsFargateCollector(cache *provider.Cache) (provider.CollectorMetadata, error) { var collectorMetadata provider.CollectorMetadata - if !config.IsFeaturePresent(config.ECSFargate) { + if !env.IsFeaturePresent(env.ECSFargate) { return collectorMetadata, provider.ErrPermaFail } diff --git a/pkg/util/containers/metrics/kubelet/collector.go b/pkg/util/containers/metrics/kubelet/collector.go index 541c9400f77ba..e2d5a2d6e1ca7 100644 --- a/pkg/util/containers/metrics/kubelet/collector.go +++ b/pkg/util/containers/metrics/kubelet/collector.go @@ -15,7 +15,7 @@ import ( "time" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" pkgerrors "github.com/DataDog/datadog-agent/pkg/errors" "github.com/DataDog/datadog-agent/pkg/util/containers/metrics/provider" kutil "github.com/DataDog/datadog-agent/pkg/util/kubernetes/kubelet" @@ -61,7 +61,7 @@ type kubeletCollector struct { func newKubeletCollector(_ *provider.Cache, wmeta workloadmeta.Component) (provider.CollectorMetadata, error) { var collectorMetadata provider.CollectorMetadata - if !config.IsFeaturePresent(config.Kubernetes) { + if !env.IsFeaturePresent(env.Kubernetes) { return collectorMetadata, provider.ErrPermaFail } diff --git a/pkg/util/containers/metrics/kubelet/collector_test.go b/pkg/util/containers/metrics/kubelet/collector_test.go index 61bd65bcd0f50..408189d32829e 100644 --- a/pkg/util/containers/metrics/kubelet/collector_test.go +++ b/pkg/util/containers/metrics/kubelet/collector_test.go @@ -30,8 +30,7 @@ func TestKubeletCollectorLinux(t *testing.T) { metadataStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) kubeletMock := mock.NewKubeletMock() @@ -164,8 +163,7 @@ func TestKubeletCollectorWindows(t *testing.T) { metadataStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) kubeletMock := mock.NewKubeletMock() @@ -278,8 +276,7 @@ func TestContainerIDForPodUIDAndContName(t *testing.T) { metadataStore := fxutil.Test[workloadmetamock.Mock](t, fx.Options( core.MockBundle(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) kubeletMock := mock.NewKubeletMock() diff --git a/pkg/util/containers/metrics/provider/registry.go b/pkg/util/containers/metrics/provider/registry.go index 6a7de440e3129..15dc40da027f0 100644 --- a/pkg/util/containers/metrics/provider/registry.go +++ b/pkg/util/containers/metrics/provider/registry.go @@ -91,6 +91,7 @@ func (cr *collectorRegistry) run(c context.Context, cache *Cache, wmeta optional func (cr *collectorRegistry) collectorDiscovery(c context.Context, cache *Cache, wmeta optional.Option[workloadmeta.Component]) { ticker := time.NewTicker(minRetryInterval) + defer ticker.Stop() for { select { case <-c.Done(): diff --git a/pkg/util/containers/metrics/system/collector_linux.go b/pkg/util/containers/metrics/system/collector_linux.go index e4970a77548d1..9eec6d9846a2d 100644 --- a/pkg/util/containers/metrics/system/collector_linux.go +++ b/pkg/util/containers/metrics/system/collector_linux.go @@ -18,6 +18,7 @@ import ( workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/cgroups" "github.com/DataDog/datadog-agent/pkg/util/containers/metrics/provider" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -89,7 +90,7 @@ func newSystemCollector(cache *provider.Cache, wlm optional.Option[workloadmeta. selfReader, err := cgroups.NewSelfReader( procPath, - config.IsContainerized(), + env.IsContainerized(), cgroups.WithCgroupV1BaseController(cgroupV1BaseController), ) if err != nil { @@ -120,20 +121,20 @@ func newSystemCollector(cache *provider.Cache, wlm optional.Option[workloadmeta. // Build available Collectors based on environment var collectors *provider.Collectors - if config.IsContainerized() { + if env.IsContainerized() { collectors = &provider.Collectors{} // When the Agent runs as a sidecar (e.g. Fargate) with shared PID namespace, we can use the system collector in some cases. // TODO: Check how we could detect shared PID namespace instead of makeing assumption - isAgentSidecar := config.IsFeaturePresent(config.ECSFargate) || config.IsFeaturePresent(config.EKSFargate) + isAgentSidecar := env.IsFeaturePresent(env.ECSFargate) || env.IsFeaturePresent(env.EKSFargate) // With sysfs we can always get cgroup stats - if config.IsHostSysAvailable() { + if env.IsHostSysAvailable() { collectors.Stats = provider.MakeRef[provider.ContainerStatsGetter](systemCollector, collectorHighPriority) } // With host proc we can always get network stats and pids - if config.IsHostProcAvailable() { + if env.IsHostProcAvailable() { collectors.Network = provider.MakeRef[provider.ContainerNetworkStatsGetter](systemCollector, collectorHighPriority) collectors.OpenFilesCount = provider.MakeRef[provider.ContainerOpenFilesCountGetter](systemCollector, collectorHighPriority) collectors.PIDs = provider.MakeRef[provider.ContainerPIDsGetter](systemCollector, collectorHighPriority) diff --git a/pkg/util/containers/metrics/system/filter_container_test.go b/pkg/util/containers/metrics/system/filter_container_test.go index 27dba224aed0d..2a98c70511cc8 100644 --- a/pkg/util/containers/metrics/system/filter_container_test.go +++ b/pkg/util/containers/metrics/system/filter_container_test.go @@ -95,8 +95,7 @@ func TestListenWorkloadmeta(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) cf := newContainerFilter(wlm) go cf.start() diff --git a/pkg/util/docker/metadata.go b/pkg/util/docker/metadata.go index 5f9d85672a240..4c08d8729212b 100644 --- a/pkg/util/docker/metadata.go +++ b/pkg/util/docker/metadata.go @@ -12,14 +12,13 @@ import ( "errors" "time" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/docker/docker/api/types/swarm" - - "github.com/DataDog/datadog-agent/pkg/config" ) // GetMetadata returns metadata about the docker runtime such as docker_version and if docker_swarm is enabled or not. func GetMetadata() (map[string]string, error) { - if !config.IsFeaturePresent(config.Docker) { + if !env.IsFeaturePresent(env.Docker) { return nil, errors.New("Docker feature deactivated") } diff --git a/pkg/util/ec2/ec2.go b/pkg/util/ec2/ec2.go index 8c78e5ae0ba40..d4c8025ced09f 100644 --- a/pkg/util/ec2/ec2.go +++ b/pkg/util/ec2/ec2.go @@ -15,6 +15,7 @@ import ( "time" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/cachedfetch" httputils "github.com/DataDog/datadog-agent/pkg/util/http" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -136,7 +137,7 @@ func IsRunningOn(ctx context.Context) bool { return true } - return config.IsFeaturePresent(config.ECSEC2) || config.IsFeaturePresent(config.ECSFargate) + return env.IsFeaturePresent(env.ECSEC2) || env.IsFeaturePresent(env.ECSFargate) } // GetHostAliases returns the host aliases from the EC2 metadata API. diff --git a/pkg/util/ec2/network.go b/pkg/util/ec2/network.go index c7f7277b30714..5fafa6bed62d7 100644 --- a/pkg/util/ec2/network.go +++ b/pkg/util/ec2/network.go @@ -83,14 +83,14 @@ func GetSubnetForHardwareAddr(ctx context.Context, hwAddr net.HardwareAddr) (sub } var resp string - resp, err = getMetadataItem(ctx, fmt.Sprintf("%s/%s/subnet-id", imdsNetworkMacs, hwAddr), false) + resp, err = getMetadataItem(ctx, fmt.Sprintf("%s/%s/subnet-id", imdsNetworkMacs, hwAddr), true) if err != nil { return } subnet.ID = strings.TrimSpace(resp) - resp, err = getMetadataItem(ctx, fmt.Sprintf("%s/%s/subnet-ipv4-cidr-block", imdsNetworkMacs, hwAddr), false) + resp, err = getMetadataItem(ctx, fmt.Sprintf("%s/%s/subnet-ipv4-cidr-block", imdsNetworkMacs, hwAddr), true) if err != nil { return } diff --git a/pkg/util/ecs/ecs.go b/pkg/util/ecs/ecs.go new file mode 100644 index 0000000000000..40f083270a2de --- /dev/null +++ b/pkg/util/ecs/ecs.go @@ -0,0 +1,52 @@ +// 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 2020-present Datadog, Inc. + +//go:build docker + +// Package ecs provides information about the ECS Agent Version when running in ECS +package ecs + +import ( + "context" + "github.com/DataDog/datadog-agent/pkg/util/ecs/metadata" + v1 "github.com/DataDog/datadog-agent/pkg/util/ecs/metadata/v1" +) + +var metaV1 v1.Client +var err error + +// MetaECS stores ECS metadata to be exported to a json file in the agent flare +type MetaECS struct { + ECSCluster string + ECSAgentVersion string +} + +// NewECSMeta returns a MetaECS object +func NewECSMeta(ctx context.Context) (*MetaECS, error) { + cluster, version, err := getECSInstanceMetadata(ctx) + if err != nil { + return nil, err + } + + ecsMeta := MetaECS{ + ECSCluster: cluster, + ECSAgentVersion: version, + } + return &ecsMeta, nil +} + +func getECSInstanceMetadata(ctx context.Context) (string, string, error) { + metaV1, err = metadata.V1() + if err != nil { + return "", "", err + } + + ecsInstance, err := metaV1.GetInstance(ctx) + if err != nil { + return "", "", err + } + + return ecsInstance.Cluster, ecsInstance.Version, err +} diff --git a/pkg/util/ecs/metadata/detection.go b/pkg/util/ecs/metadata/detection.go index 71b08ad07479d..58d5814d1c783 100644 --- a/pkg/util/ecs/metadata/detection.go +++ b/pkg/util/ecs/metadata/detection.go @@ -19,6 +19,7 @@ import ( "github.com/hashicorp/go-version" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/docker" "github.com/DataDog/datadog-agent/pkg/util/system" @@ -44,7 +45,7 @@ func detectAgentV1URL() (string, error) { urls = append(urls, config.Datadog().GetString("ecs_agent_url")) } - if config.IsContainerized() { + if env.IsContainerized() { // List all interfaces for the ecs-agent container agentURLS, err := getAgentV1ContainerURLs(context.TODO()) if err != nil { @@ -79,7 +80,7 @@ func detectAgentV1URL() (string, error) { func getAgentV1ContainerURLs(ctx context.Context) ([]string, error) { var urls []string - if !config.IsFeaturePresent(config.Docker) { + if !env.IsFeaturePresent(env.Docker) { return nil, errors.New("Docker feature not activated") } diff --git a/pkg/util/ecs/metadata/detection_test.go b/pkg/util/ecs/metadata/detection_test.go index f59c7b02f3167..a88a5b815e9dd 100644 --- a/pkg/util/ecs/metadata/detection_test.go +++ b/pkg/util/ecs/metadata/detection_test.go @@ -19,6 +19,7 @@ import ( "github.com/stretchr/testify/require" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/cache" "github.com/DataDog/datadog-agent/pkg/util/docker" "github.com/DataDog/datadog-agent/pkg/util/ecs/metadata/testutil" @@ -73,7 +74,7 @@ func TestLocateECSHTTPFail(t *testing.T) { } func TestGetAgentV1ContainerURLs(t *testing.T) { - config.SetFeatures(t, config.Docker) + config.SetFeatures(t, env.Docker) ctx := context.Background() config.Datadog().SetDefault("ecs_agent_container_name", "ecs-agent-custom") diff --git a/pkg/util/ecs/metadata/testutil/dummy_ecs.go b/pkg/util/ecs/metadata/testutil/dummy_ecs.go index a1a874b566723..368a8a353d11b 100644 --- a/pkg/util/ecs/metadata/testutil/dummy_ecs.go +++ b/pkg/util/ecs/metadata/testutil/dummy_ecs.go @@ -11,20 +11,19 @@ import ( "net/http" "net/http/httptest" "os" - "sync" + "sync/atomic" "time" ) // DummyECS allows tests to mock ECS metadata server responses type DummyECS struct { - sync.Mutex mux *http.ServeMux fileHandlers map[string]string fileHandlersDelay map[string]time.Duration rawHandlers map[string]string rawHandlersDelay map[string]time.Duration Requests chan *http.Request - RequestCount int + RequestCount atomic.Uint64 } // Option represents an option used to create a new mock of the ECS metadata @@ -100,9 +99,7 @@ func NewDummyECS(ops ...Option) (*DummyECS, error) { // ServeHTTP is used to handle HTTP requests. func (d *DummyECS) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Printf("dummyECS received %s on %s\n", r.Method, r.URL.Path) - d.Lock() - d.RequestCount++ - d.Unlock() + d.RequestCount.Add(1) d.Requests <- r d.mux.ServeHTTP(w, r) } diff --git a/pkg/util/ecs/metadata/v3or4/client_test.go b/pkg/util/ecs/metadata/v3or4/client_test.go index c45aa2546b0a1..f8d55bf8135d7 100644 --- a/pkg/util/ecs/metadata/v3or4/client_test.go +++ b/pkg/util/ecs/metadata/v3or4/client_test.go @@ -53,7 +53,7 @@ func TestGetV4TaskWithTagsWithoutRetryWithDelay(t *testing.T) { // default timeout is 500ms while the delay is 1.5s require.True(t, os.IsTimeout(err)) require.Nil(t, task) - require.Equal(t, 1, dummyECS.RequestCount) + require.Equal(t, uint64(1), dummyECS.RequestCount.Load()) } func TestGetV4TaskWithTagsWithRetryWithDelay(t *testing.T) { @@ -81,7 +81,7 @@ func TestGetV4TaskWithTagsWithRetryWithDelay(t *testing.T) { // 1st request failed: request timeout is 500ms // 2nd request failed: request timeout is 1s // 3rd request succeed: request timeout is 2s - require.Equal(t, 3, dummyECS.RequestCount) + require.Equal(t, uint64(3), dummyECS.RequestCount.Load()) } // expected is an expected Task from ./testdata/task.json diff --git a/pkg/util/ecs/no_ecs.go b/pkg/util/ecs/no_ecs.go new file mode 100644 index 0000000000000..6c6719c838da3 --- /dev/null +++ b/pkg/util/ecs/no_ecs.go @@ -0,0 +1,21 @@ +// 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 2020-present Datadog, Inc. + +//go:build !docker + +// Package ecs provides information about the ECS Agent Version when running in ECS +package ecs + +import ( + "context" +) + +// MetaECS stores ECS metadata to be exported to a json file in the agent flare +type MetaECS struct{} + +// NewECSMeta returns a MetaECS object +func NewECSMeta(_ context.Context) (*MetaECS, error) { + return nil, nil +} diff --git a/pkg/util/fargate/detection.go b/pkg/util/fargate/detection.go index 583d3a5c0d83d..20a7d80aa0c12 100644 --- a/pkg/util/fargate/detection.go +++ b/pkg/util/fargate/detection.go @@ -9,19 +9,20 @@ import ( "errors" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" ) // IsFargateInstance returns whether the Agent is running in Fargate. func IsFargateInstance() bool { - return config.IsFeaturePresent(config.ECSFargate) || config.IsFeaturePresent(config.EKSFargate) + return env.IsFeaturePresent(env.ECSFargate) || env.IsFeaturePresent(env.EKSFargate) } // GetOrchestrator returns whether the Agent is running on ECS or EKS. func GetOrchestrator() OrchestratorName { - if config.IsFeaturePresent(config.EKSFargate) { + if env.IsFeaturePresent(env.EKSFargate) { return EKS } - if config.IsFeaturePresent(config.ECSFargate) { + if env.IsFeaturePresent(env.ECSFargate) { return ECS } return Unknown diff --git a/pkg/util/filesystem/go.mod b/pkg/util/filesystem/go.mod index 74977233e7ed6..74ac1e9026854 100644 --- a/pkg/util/filesystem/go.mod +++ b/pkg/util/filesystem/go.mod @@ -13,7 +13,7 @@ require ( github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 github.com/shirou/gopsutil/v3 v3.23.9 github.com/stretchr/testify v1.9.0 - golang.org/x/sys v0.23.0 + golang.org/x/sys v0.24.0 ) require ( diff --git a/pkg/util/filesystem/go.sum b/pkg/util/filesystem/go.sum index f9b76ba0bbac6..e20ca16020701 100644 --- a/pkg/util/filesystem/go.sum +++ b/pkg/util/filesystem/go.sum @@ -38,8 +38,8 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w 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.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/util/flavor/go.mod b/pkg/util/flavor/go.mod index 85825bb481ed5..2e595d37fa9ca 100644 --- a/pkg/util/flavor/go.mod +++ b/pkg/util/flavor/go.mod @@ -74,12 +74,12 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/util/flavor/go.sum b/pkg/util/flavor/go.sum index 79c2fcb395d02..77ba213060c82 100644 --- a/pkg/util/flavor/go.sum +++ b/pkg/util/flavor/go.sum @@ -234,25 +234,25 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -295,11 +295,11 @@ golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBc 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -312,8 +312,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/util/fxutil/go.mod b/pkg/util/fxutil/go.mod index 7facc12f6be28..123448cb4abe1 100644 --- a/pkg/util/fxutil/go.mod +++ b/pkg/util/fxutil/go.mod @@ -7,7 +7,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/optional v0.55.0 github.com/spf13/cobra v1.7.0 github.com/stretchr/testify v1.9.0 - go.uber.org/fx v1.18.2 + go.uber.org/fx v1.22.2 ) replace ( @@ -21,10 +21,9 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/dig v1.17.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.23.0 // indirect - golang.org/x/sys v0.23.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/sys v0.24.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/util/fxutil/go.sum b/pkg/util/fxutil/go.sum index c0c82340f4f98..fe7d4e245cb35 100644 --- a/pkg/util/fxutil/go.sum +++ b/pkg/util/fxutil/go.sum @@ -1,13 +1,8 @@ -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/cpuguy83/go-md2man/v2 v2.0.2/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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -15,24 +10,20 @@ github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= -go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= +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/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/pkg/util/fxutil/provide_comp.go b/pkg/util/fxutil/provide_comp.go index ba9b256061996..e483a4df90666 100644 --- a/pkg/util/fxutil/provide_comp.go +++ b/pkg/util/fxutil/provide_comp.go @@ -10,6 +10,8 @@ import ( "fmt" "reflect" "slices" + "unicode" + "unicode/utf8" compdef "github.com/DataDog/datadog-agent/comp/def" "go.uber.org/fx" @@ -225,6 +227,10 @@ func ensureFieldsNotAllowed(typ reflect.Type, badEmbeds []reflect.Type) error { if slices.Contains(badEmbeds, field.Type) { return fmt.Errorf("invalid embedded field: %v", field.Type) } + firstRune, _ := utf8.DecodeRuneInString(field.Name) + if unicode.IsLower(firstRune) { + return fmt.Errorf("field is not exported: %v", field.Name) + } } return nil } diff --git a/pkg/util/fxutil/provide_comp_test.go b/pkg/util/fxutil/provide_comp_test.go index f2dab659e0148..32055ce007a1b 100644 --- a/pkg/util/fxutil/provide_comp_test.go +++ b/pkg/util/fxutil/provide_comp_test.go @@ -300,6 +300,14 @@ func TestConstructFxAwareStructWithLifecycle(t *testing.T) { require.Equal(t, typ.Field(1).Type, reflect.TypeOf((*compdef.Lifecycle)(nil)).Elem()) } +func TestInvalidPrivateOutput(t *testing.T) { + prv := providesPrivate{} + typ := reflect.TypeOf(prv) + err := ensureFieldsNotAllowed(typ, nil) + require.Error(t, err) + require.Equal(t, err.Error(), "field is not exported: private") +} + // test that fx App is able to use constructor with no reqs func TestFxNoRequirements(t *testing.T) { // plain component constructor, no fx @@ -668,6 +676,14 @@ type provides5 struct { First FirstComp } +// providesPrivate has an unexported field + +type providesPrivate struct { + compdef.Out + //nolint:unused + private FirstComp +} + // requires1 requires 1 component using a composite struct type requires1 struct { diff --git a/pkg/util/grpc/go.mod b/pkg/util/grpc/go.mod index ad70d6e0cc748..0c53ed492d484 100644 --- a/pkg/util/grpc/go.mod +++ b/pkg/util/grpc/go.mod @@ -14,7 +14,7 @@ require ( github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 github.com/stretchr/testify v1.9.0 - golang.org/x/net v0.27.0 + golang.org/x/net v0.28.0 google.golang.org/grpc v1.59.0 ) @@ -28,8 +28,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/tinylib/msgp v1.1.8 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/pkg/util/grpc/go.sum b/pkg/util/grpc/go.sum index 2ff4d8237f16e..62468dcc900c6 100644 --- a/pkg/util/grpc/go.sum +++ b/pkg/util/grpc/go.sum @@ -92,8 +92,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= @@ -114,8 +114,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= @@ -123,8 +123,8 @@ 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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= diff --git a/pkg/util/hostname/common.go b/pkg/util/hostname/common.go index c870b731ae220..968316db8adcb 100644 --- a/pkg/util/hostname/common.go +++ b/pkg/util/hostname/common.go @@ -14,6 +14,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/hostname/hostnameinterface" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/cloudproviders/azure" "github.com/DataDog/datadog-agent/pkg/util/cloudproviders/gce" "github.com/DataDog/datadog-agent/pkg/util/ec2" @@ -26,7 +27,7 @@ import ( var ( isFargateInstance = fargate.IsFargateInstance ec2GetInstanceID = ec2.GetInstanceID - isContainerized = config.IsContainerized //nolint:unused + isContainerized = env.IsContainerized //nolint:unused gceGetHostname = gce.GetHostname azureGetHostname = azure.GetHostname osHostname = os.Hostname @@ -133,7 +134,7 @@ func fromEC2(ctx context.Context, currentHostname string) (string, error) { // We use the instance id if we're on an ECS cluster or we're on EC2 and the hostname is one of the default ones // or ec2_prioritize_instance_id_as_hostname is set to true - if config.IsFeaturePresent(config.ECSEC2) || ec2.IsDefaultHostname(currentHostname) || prioritizeEC2Hostname { + if env.IsFeaturePresent(env.ECSEC2) || ec2.IsDefaultHostname(currentHostname) || prioritizeEC2Hostname { log.Debugf("Trying to fetch hostname from EC2 metadata") return getValidEC2Hostname(ctx) } else if ec2.IsWindowsDefaultHostname(currentHostname) { diff --git a/pkg/util/hostname/container.go b/pkg/util/hostname/container.go index b7930a8ec2f9e..72a1f4db0f936 100644 --- a/pkg/util/hostname/container.go +++ b/pkg/util/hostname/container.go @@ -11,7 +11,7 @@ import ( "context" "fmt" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/docker" "github.com/DataDog/datadog-agent/pkg/util/hostname/validate" "github.com/DataDog/datadog-agent/pkg/util/kubelet" @@ -21,8 +21,8 @@ import ( // for testing purposes var ( - configIsContainerized = config.IsContainerized - configIsFeaturePresent = config.IsFeaturePresent + configIsContainerized = env.IsContainerized + configIsFeaturePresent = env.IsFeaturePresent kubernetesGetKubeAPIServerHostname = kubernetes.GetKubeAPIServerHostname dockerGetHostname = docker.GetHostname @@ -51,20 +51,20 @@ func fromContainer(ctx context.Context, _ string) (string, error) { } // Cluster-agent logic: Kube apiserver - if configIsFeaturePresent(config.Kubernetes) { + if configIsFeaturePresent(env.Kubernetes) { if hostname := callContainerProvider(ctx, kubernetesGetKubeAPIServerHostname, "kube_apiserver"); hostname != "" { return hostname, nil } } // Node-agent logic: docker or kubelet - if configIsFeaturePresent(config.Docker) { + if configIsFeaturePresent(env.Docker) { if hostname := callContainerProvider(ctx, dockerGetHostname, "docker"); hostname != "" { return hostname, nil } } - if configIsFeaturePresent(config.Kubernetes) { + if configIsFeaturePresent(env.Kubernetes) { if hostname := callContainerProvider(ctx, kubeletGetHostname, "kubelet"); hostname != "" { return hostname, nil } diff --git a/pkg/util/hostname/container_test.go b/pkg/util/hostname/container_test.go index e41123da87906..87bd91a943939 100644 --- a/pkg/util/hostname/container_test.go +++ b/pkg/util/hostname/container_test.go @@ -12,18 +12,17 @@ import ( "fmt" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/docker" "github.com/DataDog/datadog-agent/pkg/util/kubelet" "github.com/DataDog/datadog-agent/pkg/util/kubernetes" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestFromContainerNotContainerized(t *testing.T) { defer func() { - configIsContainerized = config.IsContainerized + configIsContainerized = env.IsContainerized }() configIsContainerized = func() bool { return false } @@ -33,16 +32,16 @@ func TestFromContainerNotContainerized(t *testing.T) { func TestFromContainer(t *testing.T) { defer func() { - configIsContainerized = config.IsContainerized - configIsFeaturePresent = config.IsFeaturePresent + configIsContainerized = env.IsContainerized + configIsFeaturePresent = env.IsFeaturePresent kubernetesGetKubeAPIServerHostname = kubernetes.GetKubeAPIServerHostname dockerGetHostname = docker.GetHostname kubeletGetHostname = kubelet.GetHostname }() configIsContainerized = func() bool { return true } - enabledFeature := config.Kubernetes - configIsFeaturePresent = func(f config.Feature) bool { return f == enabledFeature } + enabledFeature := env.Kubernetes + configIsFeaturePresent = func(f env.Feature) bool { return f == enabledFeature } kubernetesGetKubeAPIServerHostname = func(context.Context) (string, error) { return "kubernetes-hostname", nil } dockerGetHostname = func(context.Context) (string, error) { return "docker-hostname", nil } kubeletGetHostname = func(context.Context) (string, error) { return "kubelet-hostname", nil } @@ -67,7 +66,7 @@ func TestFromContainer(t *testing.T) { assert.Error(t, err) // Docker - enabledFeature = config.Docker + enabledFeature = env.Docker hostname, err = fromContainer(ctx, "") require.NoError(t, err) @@ -80,15 +79,15 @@ func TestFromContainer(t *testing.T) { func TestFromContainerInvalidHostname(t *testing.T) { defer func() { - configIsContainerized = config.IsContainerized - configIsFeaturePresent = config.IsFeaturePresent + configIsContainerized = env.IsContainerized + configIsFeaturePresent = env.IsFeaturePresent kubernetesGetKubeAPIServerHostname = kubernetes.GetKubeAPIServerHostname dockerGetHostname = docker.GetHostname kubeletGetHostname = kubelet.GetHostname }() configIsContainerized = func() bool { return true } - configIsFeaturePresent = func(config.Feature) bool { return true } + configIsFeaturePresent = func(env.Feature) bool { return true } kubernetesGetKubeAPIServerHostname = func(context.Context) (string, error) { return "hostname_with_underscore", nil } dockerGetHostname = func(context.Context) (string, error) { return "hostname_with_underscore", nil } kubeletGetHostname = func(context.Context) (string, error) { return "hostname_with_underscore", nil } diff --git a/pkg/util/hostname/providers_test.go b/pkg/util/hostname/providers_test.go index 42dd404dc70de..e95605acb92ab 100644 --- a/pkg/util/hostname/providers_test.go +++ b/pkg/util/hostname/providers_test.go @@ -16,6 +16,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" configmock "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/util/cache" "github.com/DataDog/datadog-agent/pkg/util/cloudproviders/azure" @@ -49,7 +50,7 @@ func setupHostnameTest(t *testing.T, tc testCase) { t.Cleanup(func() { isFargateInstance = fargate.IsFargateInstance ec2GetInstanceID = ec2.GetInstanceID - isContainerized = config.IsContainerized + isContainerized = env.IsContainerized gceGetHostname = gce.GetHostname azureGetHostname = azure.GetHostname osHostname = os.Hostname diff --git a/pkg/util/http/go.mod b/pkg/util/http/go.mod index 12222a42947a6..1ae7113755589 100644 --- a/pkg/util/http/go.mod +++ b/pkg/util/http/go.mod @@ -13,7 +13,7 @@ require ( github.com/DataDog/datadog-agent/pkg/config/model v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/util/log v0.56.0-rc.3 github.com/stretchr/testify v1.9.0 - golang.org/x/net v0.27.0 + golang.org/x/net v0.28.0 ) require ( @@ -33,9 +33,9 @@ require ( github.com/spf13/jwalterweatherman v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/util/http/go.sum b/pkg/util/http/go.sum index aaccc361d97de..064bdfb93bb35 100644 --- a/pkg/util/http/go.sum +++ b/pkg/util/http/go.sum @@ -297,8 +297,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -359,8 +359,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +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/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -420,8 +420,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -431,8 +431,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/pkg/util/kubelet/hostname.go b/pkg/util/kubelet/hostname.go index e189690579242..1024a251d85d3 100644 --- a/pkg/util/kubelet/hostname.go +++ b/pkg/util/kubelet/hostname.go @@ -11,7 +11,7 @@ import ( "context" "fmt" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/kubernetes/clustername" k "github.com/DataDog/datadog-agent/pkg/util/kubernetes/kubelet" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -23,7 +23,7 @@ var kubeUtilGet kubeUtilGetter = k.GetKubeUtil // GetHostname builds a hostname from the kubernetes nodename and an optional cluster-name func GetHostname(ctx context.Context) (string, error) { - if !config.IsFeaturePresent(config.Kubernetes) { + if !env.IsFeaturePresent(env.Kubernetes) { return "", nil } @@ -51,7 +51,7 @@ func GetHostname(ctx context.Context) (string, error) { // Some kubernetes cluster-names (EKS,AKS) are not RFC1123 compliant, mostly due to an `_`. // This function replaces the invalid `_` with a valid `-`. func getRFC1123CompliantClusterName(ctx context.Context, hostname string) (string, string) { - if !config.IsFeaturePresent(config.Kubernetes) { + if !env.IsFeaturePresent(env.Kubernetes) { return "", "" } clusterName := clustername.GetClusterName(ctx, hostname) diff --git a/pkg/util/kubelet/hostname_test.go b/pkg/util/kubelet/hostname_test.go index c87a65d196878..e29c1d0f61d41 100644 --- a/pkg/util/kubelet/hostname_test.go +++ b/pkg/util/kubelet/hostname_test.go @@ -16,6 +16,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" configmock "github.com/DataDog/datadog-agent/pkg/config/mock" "github.com/DataDog/datadog-agent/pkg/util/kubernetes/clustername" k "github.com/DataDog/datadog-agent/pkg/util/kubernetes/kubelet" @@ -32,7 +33,7 @@ func (m *kubeUtilMock) GetNodename(_ context.Context) (string, error) { } func TestHostnameProvider(t *testing.T) { - config.SetFeatures(t, config.Kubernetes) + config.SetFeatures(t, env.Kubernetes) ctx := context.Background() mockConfig := configmock.New(t) @@ -65,7 +66,7 @@ func TestHostnameProvider(t *testing.T) { } func TestHostnameProviderInvalid(t *testing.T) { - config.SetFeatures(t, config.Kubernetes) + config.SetFeatures(t, env.Kubernetes) ctx := context.Background() mockConfig := configmock.New(t) diff --git a/pkg/util/kubernetes/apiserver/controllers/controller_util.go b/pkg/util/kubernetes/apiserver/controllers/controller_util.go index 47995379d8664..ab277b7f040fb 100644 --- a/pkg/util/kubernetes/apiserver/controllers/controller_util.go +++ b/pkg/util/kubernetes/apiserver/controllers/controller_util.go @@ -228,9 +228,11 @@ func (h *autoscalersController) updateExternalMetrics() { // processingLoop is a go routine that schedules the garbage collection and the refreshing of external metrics // in the GlobalStore. func (h *autoscalersController) processingLoop(stopCh <-chan struct{}) { - tickerAutoscalerRefreshProcess := time.NewTicker(time.Duration(h.poller.refreshPeriod) * time.Second) - gcPeriodSeconds := time.NewTicker(time.Duration(h.poller.gcPeriodSeconds) * time.Second) go func() { + tickerAutoscalerRefreshProcess := time.NewTicker(time.Duration(h.poller.refreshPeriod) * time.Second) + defer tickerAutoscalerRefreshProcess.Stop() + gcPeriodSeconds := time.NewTicker(time.Duration(h.poller.gcPeriodSeconds) * time.Second) + defer gcPeriodSeconds.Stop() for { select { case <-stopCh: diff --git a/pkg/util/kubernetes/apiserver/controllers/metadata_controller_test.go b/pkg/util/kubernetes/apiserver/controllers/metadata_controller_test.go index 3c2df511854ef..e01683d992bf1 100644 --- a/pkg/util/kubernetes/apiserver/controllers/metadata_controller_test.go +++ b/pkg/util/kubernetes/apiserver/controllers/metadata_controller_test.go @@ -493,8 +493,7 @@ func newMockWorkloadMeta(t *testing.T) workloadmeta.Component { fx.Options( fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), ), ) } diff --git a/pkg/util/kubernetes/autoscalers/processor.go b/pkg/util/kubernetes/autoscalers/processor.go index 3e575e1a7eac4..3440c6ba01e2d 100644 --- a/pkg/util/kubernetes/autoscalers/processor.go +++ b/pkg/util/kubernetes/autoscalers/processor.go @@ -237,7 +237,7 @@ func makeChunks(batch []string) (chunks [][]string) { uriLength = uriLength + tempSize beyond, err := isURLBeyondLimits(uriLength, len(tempBucket)) if err != nil { - log.Errorf(fmt.Sprintf("%s: %s", err.Error(), val)) + log.Errorf("%v: %s", err, val) continue } if beyond { diff --git a/pkg/util/kubernetes/clustername/clustername.go b/pkg/util/kubernetes/clustername/clustername.go index 5b894e0db9bbf..d6b283aff3d7a 100644 --- a/pkg/util/kubernetes/clustername/clustername.go +++ b/pkg/util/kubernetes/clustername/clustername.go @@ -15,6 +15,7 @@ import ( "sync" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/util/cache" "github.com/DataDog/datadog-agent/pkg/util/cloudproviders/azure" "github.com/DataDog/datadog-agent/pkg/util/cloudproviders/gce" @@ -68,7 +69,7 @@ func getClusterName(ctx context.Context, data *clusterNameData, hostname string) data.mutex.Lock() defer data.mutex.Unlock() - if !config.IsFeaturePresent(config.Kubernetes) { + if !env.IsFeaturePresent(env.Kubernetes) { return "" } diff --git a/pkg/util/kubernetes/clustername/clustername_test.go b/pkg/util/kubernetes/clustername/clustername_test.go index 97db31121625b..f9c0ca366f8c9 100644 --- a/pkg/util/kubernetes/clustername/clustername_test.go +++ b/pkg/util/kubernetes/clustername/clustername_test.go @@ -12,13 +12,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" configmock "github.com/DataDog/datadog-agent/pkg/config/mock" ) func TestGetClusterName(t *testing.T) { ctx := context.Background() mockConfig := configmock.New(t) - config.SetFeatures(t, config.Kubernetes) + config.SetFeatures(t, env.Kubernetes) data := newClusterNameData() testClusterName := "laika" diff --git a/pkg/util/kubernetes/hostinfo/no_tags.go b/pkg/util/kubernetes/hostinfo/no_tags.go index d0380bfbff8ec..f81cd46cbd673 100644 --- a/pkg/util/kubernetes/hostinfo/no_tags.go +++ b/pkg/util/kubernetes/hostinfo/no_tags.go @@ -7,11 +7,23 @@ package hostinfo -import "context" +import ( + "context" + + "github.com/DataDog/datadog-agent/pkg/config" +) + +// KubeNodeTagsProvider allows computing node tags based on the user configurations for node labels and annotations as tags +type KubeNodeTagsProvider struct{} + +// NewKubeNodeTagsProvider creates and returns a new kube node tags provider object +func NewKubeNodeTagsProvider(_ config.Reader) KubeNodeTagsProvider { + return KubeNodeTagsProvider{} +} // GetTags gets the tags from the kubernetes apiserver // //nolint:revive // TODO(CINT) Fix revive linter -func GetTags(_ context.Context) ([]string, error) { +func (k KubeNodeTagsProvider) GetTags(_ context.Context) ([]string, error) { return nil, nil } diff --git a/pkg/util/kubernetes/hostinfo/tags.go b/pkg/util/kubernetes/hostinfo/tags.go index 89cb8192915aa..6fc7e4314b722 100644 --- a/pkg/util/kubernetes/hostinfo/tags.go +++ b/pkg/util/kubernetes/hostinfo/tags.go @@ -9,23 +9,34 @@ package hostinfo import ( "context" - "strings" + "maps" k8smetadata "github.com/DataDog/datadog-agent/comp/core/tagger/k8s_metadata" "github.com/DataDog/datadog-agent/comp/core/tagger/taglist" "github.com/DataDog/datadog-agent/pkg/config" + configutils "github.com/DataDog/datadog-agent/pkg/config/utils" "github.com/DataDog/datadog-agent/pkg/util/kubernetes" "github.com/DataDog/datadog-agent/pkg/util/log" ) +// KubeNodeTagsProvider allows computing node tags based on the user configurations for node labels and annotations as tags +type KubeNodeTagsProvider struct { + metadataAsTags configutils.MetadataAsTags +} + +// NewKubeNodeTagsProvider creates and returns a new kube node tags provider object +func NewKubeNodeTagsProvider(conf config.Reader) KubeNodeTagsProvider { + return KubeNodeTagsProvider{configutils.GetMetadataAsTags(conf)} +} + // GetTags gets the tags from the kubernetes apiserver and the kubelet -func GetTags(ctx context.Context) ([]string, error) { - tags, err := getNodeInfoTags(ctx) +func (k KubeNodeTagsProvider) GetTags(ctx context.Context) ([]string, error) { + tags, err := k.getNodeInfoTags(ctx) if err != nil { return nil, err } - annotationsToTags := getAnnotationsToTags() + annotationsToTags := k.getNodeAnnotationsAsTags() if len(annotationsToTags) == 0 { return tags, nil } @@ -39,8 +50,12 @@ func GetTags(ctx context.Context) ([]string, error) { return tags, nil } +func (k KubeNodeTagsProvider) getNodeAnnotationsAsTags() map[string]string { + return k.metadataAsTags.GetNodeAnnotationsAsTags() +} + // getNodeInfoTags gets the tags from the kubelet and the cluster-agent -func getNodeInfoTags(ctx context.Context) ([]string, error) { +func (k KubeNodeTagsProvider) getNodeInfoTags(ctx context.Context) ([]string, error) { nodeInfo, err := NewNodeInfo() if err != nil { log.Debugf("Unable to auto discover node info tags: %s", err) @@ -55,10 +70,6 @@ func getNodeInfoTags(ctx context.Context) ([]string, error) { return nil, err } tags := []string{"kube_node:" + nodeName} - labelsToTags := getLabelsToTags() - if len(labelsToTags) == 0 { - return tags, nil - } nodeLabels, err := nodeInfo.GetNodeLabels(ctx) if err != nil { @@ -66,36 +77,22 @@ func getNodeInfoTags(ctx context.Context) ([]string, error) { return nil, err } if len(nodeLabels) > 0 { - tags = append(tags, extractTags(nodeLabels, labelsToTags)...) + tags = append(tags, extractTags(nodeLabels, k.getNodeLabelsAsTags())...) } return tags, nil } -func getDefaultLabelsToTags() map[string]string { - return map[string]string{ - NormalizedRoleLabel: kubernetes.KubeNodeRoleTagName, - } -} - -func getLabelsToTags() map[string]string { +func (k KubeNodeTagsProvider) getNodeLabelsAsTags() map[string]string { labelsToTags := getDefaultLabelsToTags() - for k, v := range config.Datadog().GetStringMapString("kubernetes_node_labels_as_tags") { - // viper lower-cases map keys from yaml, but not from envvars - labelsToTags[strings.ToLower(k)] = v - } - + maps.Copy(labelsToTags, k.metadataAsTags.GetNodeLabelsAsTags()) return labelsToTags } -func getAnnotationsToTags() map[string]string { - annotationsToTags := map[string]string{} - for k, v := range config.Datadog().GetStringMapString("kubernetes_node_annotations_as_tags") { - // viper lower-cases map keys from yaml, but not from envvars - annotationsToTags[strings.ToLower(k)] = v +func getDefaultLabelsToTags() map[string]string { + return map[string]string{ + NormalizedRoleLabel: kubernetes.KubeNodeRoleTagName, } - - return annotationsToTags } func extractTags(nodeLabels, labelsToTags map[string]string) []string { diff --git a/pkg/util/kubernetes/hostinfo/tags_test.go b/pkg/util/kubernetes/hostinfo/tags_test.go index 4bd722a0bd864..c86a58a0712b6 100644 --- a/pkg/util/kubernetes/hostinfo/tags_test.go +++ b/pkg/util/kubernetes/hostinfo/tags_test.go @@ -8,13 +8,56 @@ package hostinfo import ( + "reflect" "testing" "github.com/stretchr/testify/assert" - configmock "github.com/DataDog/datadog-agent/pkg/config/mock" + configutils "github.com/DataDog/datadog-agent/pkg/config/utils" + "github.com/DataDog/datadog-agent/pkg/util/kubernetes" ) +type mockMetadataAsTags struct { + configutils.MetadataAsTags + nodeLabelsAsTags map[string]string + nodeAnnotationsAsTags map[string]string +} + +var _ configutils.MetadataAsTags = &mockMetadataAsTags{} + +// GetNodeLabelsAsTags implements MetadataAsTags#GetNodeLabelsAsTags +func (m *mockMetadataAsTags) GetNodeLabelsAsTags() map[string]string { + return m.nodeLabelsAsTags +} + +// GetNodeAnnotationsAsTags implements MetadataAsTags#GetNodeAnnotationsAsTags +func (m *mockMetadataAsTags) GetNodeAnnotationsAsTags() map[string]string { + return m.nodeAnnotationsAsTags +} + +func newMockMetadataAsTags(nodeLabelsAsTags, nodeAnnotationsAsTags map[string]string) configutils.MetadataAsTags { + return &mockMetadataAsTags{ + nodeLabelsAsTags: nodeLabelsAsTags, + nodeAnnotationsAsTags: nodeAnnotationsAsTags, + } +} + +func TestKubeNodeTagsProvider__getNodeLabelsAsTags(t *testing.T) { + labelsAsTagsFromConfig := map[string]string{ + "foo": "bar", + } + + expectedNodeLabelsAsTags := map[string]string{ + "foo": "bar", + NormalizedRoleLabel: kubernetes.KubeNodeRoleTagName, + } + + metadataAsTags := newMockMetadataAsTags(labelsAsTagsFromConfig, map[string]string{}) + kubeNodeTagsProvider := KubeNodeTagsProvider{metadataAsTags} + labelsAsTags := kubeNodeTagsProvider.getNodeLabelsAsTags() + assert.Truef(t, reflect.DeepEqual(labelsAsTags, expectedNodeLabelsAsTags), "Expected %v, found %v", expectedNodeLabelsAsTags, labelsAsTags) +} + func TestExtractTags(t *testing.T) { gkeLabels := map[string]string{ "beta.kubernetes.io/arch": "amd64", @@ -114,47 +157,3 @@ func TestExtractTags(t *testing.T) { }) } } - -func TestGetLabelsToTags(t *testing.T) { - tests := []struct { - name string - configLabelsAsTags map[string]string - expectLabelsAsTags map[string]string - }{ - { - name: "no labels in config", - expectLabelsAsTags: map[string]string{ - "kubernetes.io/role": "kube_node_role", - }, - }, - { - name: "override node role label", - configLabelsAsTags: map[string]string{ - "kubernetes.io/role": "role", - }, - expectLabelsAsTags: map[string]string{ - "kubernetes.io/role": "role", - }, - }, - { - name: "lower case all labels", - configLabelsAsTags: map[string]string{ - "A": "a", - }, - expectLabelsAsTags: map[string]string{ - "kubernetes.io/role": "kube_node_role", - "a": "a", - }, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - config := configmock.New(t) - config.SetWithoutSource("kubernetes_node_labels_as_tags", test.configLabelsAsTags) - - actuaLabelsAsTags := getLabelsToTags() - assert.Equal(t, test.expectLabelsAsTags, actuaLabelsAsTags) - }) - } -} diff --git a/pkg/util/kubernetes/kubelet/metadata.go b/pkg/util/kubernetes/kubelet/metadata.go index beebac02909c2..5a973b94c9f87 100644 --- a/pkg/util/kubernetes/kubelet/metadata.go +++ b/pkg/util/kubernetes/kubelet/metadata.go @@ -13,12 +13,12 @@ import ( "fmt" "regexp" - "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" ) // GetMetadata returns metadata about the kubelet runtime such as the kubelet_version. func GetMetadata() (map[string]string, error) { - if !config.IsFeaturePresent(config.Kubernetes) { + if !env.IsFeaturePresent(env.Kubernetes) { return nil, errors.New("kubelet feature deactivated") } diff --git a/pkg/util/log/klog_redirect.go b/pkg/util/log/klog_redirect.go index ea6f9e66e84de..fad01af487572 100644 --- a/pkg/util/log/klog_redirect.go +++ b/pkg/util/log/klog_redirect.go @@ -46,11 +46,11 @@ func (l KlogRedirectLogger) Write(b []byte) (int, error) { case 'I': InfoStackDepth(l.stackDepth, msg) case 'W': - WarnStackDepth(l.stackDepth, msg) + _ = WarnStackDepth(l.stackDepth, msg) case 'E': - ErrorStackDepth(l.stackDepth, msg) + _ = ErrorStackDepth(l.stackDepth, msg) case 'F': - CriticalStackDepth(l.stackDepth, msg) + _ = CriticalStackDepth(l.stackDepth, msg) default: InfoStackDepth(l.stackDepth, msg) } diff --git a/pkg/util/log/log.go b/pkg/util/log/log.go index 86f3e7d0dcd9c..0e1ecaa23e3e5 100644 --- a/pkg/util/log/log.go +++ b/pkg/util/log/log.go @@ -878,25 +878,25 @@ func InfoFunc(logFunc func() string) { // Warn logs at the warn level and returns an error containing the formated log message func Warn(v ...interface{}) error { - return logWithError(seelog.WarnLvl, func() { Warn(v...) }, logger.warn, false, v...) + return logWithError(seelog.WarnLvl, func() { _ = Warn(v...) }, logger.warn, false, v...) } // Warnf logs with format at the warn level and returns an error containing the formated log message func Warnf(format string, params ...interface{}) error { - return logFormatWithError(seelog.WarnLvl, func() { Warnf(format, params...) }, logger.warnf, format, false, params...) + return logFormatWithError(seelog.WarnLvl, func() { _ = Warnf(format, params...) }, logger.warnf, format, false, params...) } // WarnfStackDepth logs with format at the warn level and the current stack depth plus the given depth func WarnfStackDepth(depth int, format string, params ...interface{}) error { msg := fmt.Sprintf(format, params...) - return logWithError(seelog.WarnLvl, func() { WarnStackDepth(depth, msg) }, func(s string) error { + return logWithError(seelog.WarnLvl, func() { _ = WarnStackDepth(depth, msg) }, func(s string) error { return logger.warnStackDepth(s, depth) }, false, msg) } // WarncStackDepth logs at the warn level with context and the current stack depth plus the additional given one and returns an error containing the formated log message func WarncStackDepth(message string, depth int, context ...interface{}) error { - return logContextWithError(seelog.WarnLvl, func() { Warnc(message, context...) }, logger.warn, message, false, depth, context...) + return logContextWithError(seelog.WarnLvl, func() { _ = Warnc(message, context...) }, logger.warn, message, false, depth, context...) } // Warnc logs at the warn level with context and returns an error containing the formated log message @@ -908,31 +908,31 @@ func Warnc(message string, context ...interface{}) error { func WarnFunc(logFunc func() string) { currentLevel, _ := GetLogLevel() if currentLevel <= seelog.WarnLvl { - WarnStackDepth(2, logFunc()) + _ = WarnStackDepth(2, logFunc()) } } // Error logs at the error level and returns an error containing the formated log message func Error(v ...interface{}) error { - return logWithError(seelog.ErrorLvl, func() { Error(v...) }, logger.error, true, v...) + return logWithError(seelog.ErrorLvl, func() { _ = Error(v...) }, logger.error, true, v...) } // Errorf logs with format at the error level and returns an error containing the formated log message func Errorf(format string, params ...interface{}) error { - return logFormatWithError(seelog.ErrorLvl, func() { Errorf(format, params...) }, logger.errorf, format, true, params...) + return logFormatWithError(seelog.ErrorLvl, func() { _ = Errorf(format, params...) }, logger.errorf, format, true, params...) } // ErrorfStackDepth logs with format at the error level and the current stack depth plus the given depth func ErrorfStackDepth(depth int, format string, params ...interface{}) error { msg := fmt.Sprintf(format, params...) - return logWithError(seelog.ErrorLvl, func() { ErrorStackDepth(depth, msg) }, func(s string) error { + return logWithError(seelog.ErrorLvl, func() { _ = ErrorStackDepth(depth, msg) }, func(s string) error { return logger.errorStackDepth(s, depth) }, true, msg) } // ErrorcStackDepth logs at the error level with context and the current stack depth plus the additional given one and returns an error containing the formated log message func ErrorcStackDepth(message string, depth int, context ...interface{}) error { - return logContextWithError(seelog.ErrorLvl, func() { Errorc(message, context...) }, logger.error, message, true, depth, context...) + return logContextWithError(seelog.ErrorLvl, func() { _ = Errorc(message, context...) }, logger.error, message, true, depth, context...) } // Errorc logs at the error level with context and returns an error containing the formated log message @@ -944,31 +944,31 @@ func Errorc(message string, context ...interface{}) error { func ErrorFunc(logFunc func() string) { currentLevel, _ := GetLogLevel() if currentLevel <= seelog.ErrorLvl { - ErrorStackDepth(2, logFunc()) + _ = ErrorStackDepth(2, logFunc()) } } // Critical logs at the critical level and returns an error containing the formated log message func Critical(v ...interface{}) error { - return logWithError(seelog.CriticalLvl, func() { Critical(v...) }, logger.critical, true, v...) + return logWithError(seelog.CriticalLvl, func() { _ = Critical(v...) }, logger.critical, true, v...) } // Criticalf logs with format at the critical level and returns an error containing the formated log message func Criticalf(format string, params ...interface{}) error { - return logFormatWithError(seelog.CriticalLvl, func() { Criticalf(format, params...) }, logger.criticalf, format, true, params...) + return logFormatWithError(seelog.CriticalLvl, func() { _ = Criticalf(format, params...) }, logger.criticalf, format, true, params...) } // CriticalfStackDepth logs with format at the critical level and the current stack depth plus the given depth func CriticalfStackDepth(depth int, format string, params ...interface{}) error { msg := fmt.Sprintf(format, params...) - return logWithError(seelog.CriticalLvl, func() { CriticalStackDepth(depth, msg) }, func(s string) error { + return logWithError(seelog.CriticalLvl, func() { _ = CriticalStackDepth(depth, msg) }, func(s string) error { return logger.criticalStackDepth(s, depth) }, false, msg) } // CriticalcStackDepth logs at the critical level with context and the current stack depth plus the additional given one and returns an error containing the formated log message func CriticalcStackDepth(message string, depth int, context ...interface{}) error { - return logContextWithError(seelog.CriticalLvl, func() { Criticalc(message, context...) }, logger.critical, message, true, depth, context...) + return logContextWithError(seelog.CriticalLvl, func() { _ = Criticalc(message, context...) }, logger.critical, message, true, depth, context...) } // Criticalc logs at the critical level with context and returns an error containing the formated log message @@ -980,7 +980,7 @@ func Criticalc(message string, context ...interface{}) error { func CriticalFunc(logFunc func() string) { currentLevel, _ := GetLogLevel() if currentLevel <= seelog.CriticalLvl { - CriticalStackDepth(2, logFunc()) + _ = CriticalStackDepth(2, logFunc()) } } @@ -993,7 +993,7 @@ func InfoStackDepth(depth int, v ...interface{}) { // WarnStackDepth logs at the warn level and the current stack depth plus the additional given one and returns an error containing the formated log message func WarnStackDepth(depth int, v ...interface{}) error { - return logWithError(seelog.WarnLvl, func() { WarnStackDepth(depth, v...) }, func(s string) error { + return logWithError(seelog.WarnLvl, func() { _ = WarnStackDepth(depth, v...) }, func(s string) error { return logger.warnStackDepth(s, depth) }, false, v...) } @@ -1014,14 +1014,14 @@ func TraceStackDepth(depth int, v ...interface{}) { // ErrorStackDepth logs at the error level and the current stack depth plus the additional given one and returns an error containing the formated log message func ErrorStackDepth(depth int, v ...interface{}) error { - return logWithError(seelog.ErrorLvl, func() { ErrorStackDepth(depth, v...) }, func(s string) error { + return logWithError(seelog.ErrorLvl, func() { _ = ErrorStackDepth(depth, v...) }, func(s string) error { return logger.errorStackDepth(s, depth) }, true, v...) } // CriticalStackDepth logs at the critical level and the current stack depth plus the additional given one and returns an error containing the formated log message func CriticalStackDepth(depth int, v ...interface{}) error { - return logWithError(seelog.CriticalLvl, func() { CriticalStackDepth(depth, v...) }, func(s string) error { + return logWithError(seelog.CriticalLvl, func() { _ = CriticalStackDepth(depth, v...) }, func(s string) error { return logger.criticalStackDepth(s, depth) }, true, v...) } @@ -1032,7 +1032,7 @@ func CriticalStackDepth(depth int, v ...interface{}) error { // JMXError Logs for JMX check func JMXError(v ...interface{}) error { - return logWithError(seelog.ErrorLvl, func() { JMXError(v...) }, jmxLogger.error, true, v...) + return logWithError(seelog.ErrorLvl, func() { _ = JMXError(v...) }, jmxLogger.error, true, v...) } // JMXInfo Logs diff --git a/pkg/util/log/setup/go.mod b/pkg/util/log/setup/go.mod index 7877421b1cd23..777f05121c2cd 100644 --- a/pkg/util/log/setup/go.mod +++ b/pkg/util/log/setup/go.mod @@ -31,9 +31,9 @@ require ( github.com/spf13/jwalterweatherman v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/util/log/setup/go.sum b/pkg/util/log/setup/go.sum index 2d0841eb54f66..17a6b55b5cc64 100644 --- a/pkg/util/log/setup/go.sum +++ b/pkg/util/log/setup/go.sum @@ -178,8 +178,8 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +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= @@ -212,11 +212,11 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/pkg/util/lsof/errors.go b/pkg/util/lsof/errors.go new file mode 100644 index 0000000000000..545db05b8de19 --- /dev/null +++ b/pkg/util/lsof/errors.go @@ -0,0 +1,11 @@ +// 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 lsof + +import "errors" + +// ErrNotImplemented is returned when the function is not implemented +var ErrNotImplemented = errors.New("not implemented") diff --git a/pkg/util/lsof/lsof.go b/pkg/util/lsof/lsof.go new file mode 100644 index 0000000000000..6cc49244e5667 --- /dev/null +++ b/pkg/util/lsof/lsof.go @@ -0,0 +1,21 @@ +// 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 lsof provides a way to list open files for a given process +package lsof + +import ( + "os" +) + +// ListOpenFiles returns a list of open files for the given process +func ListOpenFiles(pid int) (Files, error) { + return openFiles(pid) +} + +// ListOpenFilesFromSelf returns a list of open files for the current process +func ListOpenFilesFromSelf() (Files, error) { + return ListOpenFiles(os.Getpid()) +} diff --git a/pkg/util/lsof/lsof_darwin.go b/pkg/util/lsof/lsof_darwin.go new file mode 100644 index 0000000000000..12a59d0b78445 --- /dev/null +++ b/pkg/util/lsof/lsof_darwin.go @@ -0,0 +1,10 @@ +// 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 lsof + +func openFiles(_ int) (Files, error) { + return nil, ErrNotImplemented +} diff --git a/pkg/util/lsof/lsof_linux.go b/pkg/util/lsof/lsof_linux.go new file mode 100644 index 0000000000000..62a287133a039 --- /dev/null +++ b/pkg/util/lsof/lsof_linux.go @@ -0,0 +1,396 @@ +// 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 lsof + +import ( + "fmt" + "os" + "strings" + "syscall" + + "github.com/prometheus/procfs" + + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +// see the documentation for /proc for more details about files and their format +// https://www.kernel.org/doc/html/latest/filesystems/proc.html + +// openFilesLister stores the state needed to list open files +// this is helpful for tests to help with mocking +type openFilesLister struct { + pid int + procPath string + + readlink func(string) (string, error) + stat func(string) (os.FileInfo, error) + lstat func(string) (os.FileInfo, error) + + proc procfsProc + socketInfo map[uint64]socketInfo +} + +// procfsProc is an interface to allow mocking of procfs.Proc +type procfsProc interface { + ProcMaps() ([]*procfs.ProcMap, error) + FileDescriptors() ([]uintptr, error) + Cwd() (string, error) +} + +type socketInfo struct { + Description string + State string + Protocol string +} + +func openFiles(pid int) (Files, error) { + ofl := &openFilesLister{ + pid: pid, + + readlink: os.Readlink, + stat: os.Stat, + lstat: os.Lstat, + } + + ofl.procPath = procPath() + + fs, err := procfs.NewFS(ofl.procPath) + if err != nil { + return nil, err + } + + ofl.proc, err = fs.Proc(pid) + if err != nil { + return nil, err + } + + ofl.socketInfo = readSocketInfo(ofl.procPIDPath()) + + return ofl.openFiles(), nil +} + +func (ofl *openFilesLister) procPIDPath() string { + return fmt.Sprintf("%s/%d", ofl.procPath, ofl.pid) +} + +func (ofl *openFilesLister) openFiles() Files { + var files Files + + // open files, socket, pipe (everything with a file descriptor, from /proc//fd) + openFDFiles, err := ofl.fdMetadata() + if err != nil { + log.Debugf("Failed to get open FDs for pid %d: %s", ofl.pid, err) + } else { + files = append(files, openFDFiles...) + } + + // memory mapped files, code, regions (from /proc//maps) + mmapFiles, err := ofl.mmapMetadata() + if err != nil { + log.Debugf("Failed to get memory maps for pid %d: %s", ofl.pid, err) + } else { + files = append(files, mmapFiles...) + } + + return files +} + +func (ofl *openFilesLister) mmapMetadata() (Files, error) { + maps, err := ofl.proc.ProcMaps() + if err != nil { + return nil, err + } + + cwd, _ := ofl.proc.Cwd() + + var files Files + for i, m := range maps { + if i > 0 && m.Pathname == maps[i-1].Pathname { + // skip duplicate entries + continue + } + if m.Pathname == "" { + // anonymous mapping + continue + } + + if m.Dev == 0 || m.Inode == 0 { + // virtual memory region, eg. [heap], [stack], [vvar], etc + continue + } + + file := File{ + Name: m.Pathname, + OpenPerm: permToString(m.Perms), + } + + if file.Type, file.FilePerm, file.Size, _ = fileStats(ofl.stat, m.Pathname); file.Type == "" { + continue + } + file.Fd = mmapFD(m.Pathname, file.Type, cwd) + + files = append(files, file) + } + + return files, nil +} + +func permToString(perms *procfs.ProcMapPermissions) string { + s := "" + + for _, perm := range []struct { + set bool + charSet string + charUnset string + }{ + {perms.Read, "r", "-"}, + {perms.Write, "w", "-"}, + {perms.Execute, "x", "-"}, + {perms.Private, "p", ""}, + {perms.Shared, "s", ""}, + } { + if perm.set { + s += perm.charSet + } else { + s += perm.charUnset + } + } + + return s +} + +func mmapFD(path string, fileType, cwd string) string { + /* + cwd current working directory; + ltx shared library text (code and data); + mem memory-mapped file; + mmap memory-mapped device; + rtd root directory; + txt program text (code and data); + */ + + if fileType == "REG" { + // knowing whether the file is memory mapped or program text would require reading /proc//stat + // but the specific fields needed are not parsed by procfs.Proc + // just assume it's a memory mapped file + return "mem" + } + + if fileType == "DIR" { + if path == "/" { + return "rtd" + } + if cwd != "" && path == cwd { + return "cwd" + } + } + return "unknown" +} + +func (ofl *openFilesLister) fdMetadata() (Files, error) { + openFDs, err := ofl.proc.FileDescriptors() + if err != nil { + return nil, err + } + + var files Files + for _, openFD := range openFDs { + file, ok := ofl.fdStat(openFD) + if ok { + files = append(files, file) + } + } + + return files, nil +} + +func (ofl *openFilesLister) fdStat(fd uintptr) (File, bool) { + var err error + file := File{ + Fd: fmt.Sprintf("%d", fd), + } + + fdLinkPath := fmt.Sprintf("%s/fd/%d", ofl.procPIDPath(), fd) + + if file.Type, file.OpenPerm, _, _ = fileStats(ofl.lstat, fdLinkPath); file.Type == "" { + return File{}, false + } + + var ok bool + // remove some unnecessary information from permissions string + // if the expectations are not met, the permissions are left as is + + // file descriptors always have no sticky bit, setuid, setgid + file.OpenPerm = strings.TrimPrefix(file.OpenPerm, "-") + // file descriptors always have no permission for group and others + file.OpenPerm, ok = strings.CutSuffix(file.OpenPerm, "------") + if ok { + // file descriptors always have execute permission + file.OpenPerm = strings.TrimSuffix(file.OpenPerm, "x") + } + + var inode uint64 + if file.Type, file.FilePerm, file.Size, inode = fileStats(ofl.stat, fdLinkPath); file.Type == "" { + return File{}, false + } + + if info, ok := ofl.socketInfo[inode]; ok { + file.Name = info.Description + file.FilePerm = info.State + file.Type = info.Protocol + } else { + file.Name, err = ofl.readlink(fdLinkPath) + if err != nil { + return File{}, false + } + } + + return file, true +} + +// TCP state codes, from the Linux kernel +// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/net/tcp_states.h +// +// The same codes are used for UDP, but only ESTABLISHED and CLOSE are valid +var tcpStates = map[uint64]string{ + 1: "ESTABLISHED", + 2: "SYN_SENT", + 3: "SYN_RECV", + 4: "FIN_WAIT1", + 5: "FIN_WAIT2", + 6: "TIME_WAIT", + 7: "CLOSE", + 8: "CLOSE_WAIT", + 9: "LAST_ACK", + 10: "LISTEN", + 11: "CLOSING", + 12: "NEW_SYN_RECV", + 13: "BOUND_INACTIVE", +} + +func stateStr(state uint64) string { + if s, ok := tcpStates[state]; ok { + return s + } + return fmt.Sprintf("UNKNOWN(%d)", state) +} + +// readSocketInfo reads the socket information from /proc//net/{tcp,tcp6,udp,udp6,unix} +// returns a map of inode to socketInfo +// see https://www.kernel.org/doc/Documentation/networking/proc_net_tcp.txt +func readSocketInfo(procPIDPath string) map[uint64]socketInfo { + si := make(map[uint64]socketInfo) + + fs, err := procfs.NewFS(procPIDPath) + if err != nil { + log.Debugf("Failed to read %s: %s", procPIDPath, err) + return si + } + + for protocol, parser := range map[string]func() (procfs.NetTCP, error){ + "tcp": fs.NetTCP, + "tcp6": fs.NetTCP6, + } { + addrs, err := parser() + if err != nil { + log.Debugf("Failed to read %s socket info in %s: %s", protocol, procPIDPath, err) + continue + } + for _, entry := range addrs { + si[entry.Inode] = socketInfo{ + fmt.Sprintf("%s:%d->%s:%d", entry.LocalAddr, entry.LocalPort, entry.RemAddr, entry.RemPort), + stateStr(entry.St), + protocol, + } + } + } + + for protocol, parser := range map[string]func() (procfs.NetUDP, error){ + "udp": fs.NetUDP, + "udp6": fs.NetUDP6, + } { + addrs, err := parser() + if err != nil { + log.Debugf("Failed to read %s socket info in %s: %s", protocol, procPIDPath, err) + continue + } + for _, entry := range addrs { + si[entry.Inode] = socketInfo{ + fmt.Sprintf("%s:%d->%s:%d", entry.LocalAddr, entry.LocalPort, entry.RemAddr, entry.RemPort), + stateStr(entry.St), + protocol, + } + } + } + + unix, err := fs.NetUNIX() + if err == nil { + for _, entry := range unix.Rows { + si[entry.Inode] = socketInfo{ + fmt.Sprintf("%s:%s", entry.Type, entry.Path), + fmt.Sprintf("%s:%s", entry.State, entry.Flags), + "unix", + } + } + } else { + log.Debugf("Failed to read unix socket info in %s: %s", procPIDPath, err) + } + + return si +} + +func modeTypeToString(mode os.FileMode) string { + switch mode & os.ModeType { + case os.ModeSocket: + return "SOCKET" + case os.ModeNamedPipe: + return "PIPE" + case os.ModeDevice: + return "DEV" + case os.ModeDir: + return "DIR" + case os.ModeCharDevice: + return "CHAR" + case os.ModeSymlink: + return "LINK" + case os.ModeIrregular: + return "?" + default: + return "REG" + } +} + +// fileStats returns the type, permission, size, and inode of a file +func fileStats(statf func(string) (os.FileInfo, error), path string) (string, string, int64, uint64) { + stat, err := statf(path) + if err != nil { + log.Debugf("stat failed for %s: %v", path, err) + return "", "", 0, 0 + } + + fileType := modeTypeToString(stat.Mode()) + + size := stat.Size() + perm := stat.Mode().Perm().String() + + var ino uint64 + // The inode number is not part of the exported interface of `os.FileInfo`, + // so we need to use the underlying type to get it + // `syscall.Stat_t` is the underlying type of `os.FileInfo.Sys()` on Linux + // but type check to be safe and avoid unexpected panics + if sys, ok := stat.Sys().(*syscall.Stat_t); ok { + ino = sys.Ino + } + + return fileType, perm, size, ino +} + +func procPath() string { + if procPath, ok := os.LookupEnv("HOST_PROC"); ok { + return procPath + } + return "/proc" +} diff --git a/pkg/util/lsof/lsof_linux_test.go b/pkg/util/lsof/lsof_linux_test.go new file mode 100644 index 0000000000000..061880bdb8697 --- /dev/null +++ b/pkg/util/lsof/lsof_linux_test.go @@ -0,0 +1,613 @@ +// 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 lsof + +import ( + "errors" + "io/fs" + "os" + "syscall" + "testing" + "time" + + "github.com/prometheus/procfs" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestOpenFiles(t *testing.T) { + t.Run("success", func(t *testing.T) { + pid := os.Getpid() + + files, err := openFiles(pid) + + require.NoError(t, err) + require.NotEmpty(t, files) + }) + + t.Run("error", func(t *testing.T) { + ofl := &openFilesLister{ + pid: 123, + proc: &procMock{}, + } + files := ofl.openFiles() + require.Empty(t, files) + }) +} + +func TestMmapMetadata(t *testing.T) { + fs, err := procfs.NewFS("testdata/mmapMetadata") + require.NoError(t, err) + + proc, err := fs.Proc(1) + require.NoError(t, err) + + ofl := &openFilesLister{ + pid: 1, + procPath: "testdata", + proc: proc, + + readlink: func(string) (string, error) { + return "/some/file", nil + }, + lstat: func(string) (os.FileInfo, error) { + return &mockFileInfo{ + mode: os.ModeSymlink | 0500, + name: "10", + size: 16, + sys: &syscall.Stat_t{Ino: 123}, + }, nil + }, + stat: func(path string) (os.FileInfo, error) { + if path == "/usr/lib/aarch64-linux-gnu/libgcc_s.so.1" { + return nil, errors.New("some error") + } + return &mockFileInfo{ + mode: 0400, + name: "file", + size: 8, + sys: &syscall.Stat_t{Ino: 456}, + }, nil + }, + } + + mmaps, err := ofl.mmapMetadata() + require.NoError(t, err) + + expected := Files{ + {"mem", "REG", "r-xp", "-r--------", 8, "/vscode/vscode-server/bin/linux-arm64/eaa41d57266683296de7d118f574d0c2652e1fc4/node"}, + {"mem", "REG", "r-xp", "-r--------", 8, "/usr/lib/aarch64-linux-gnu/libutil.so.1"}, + {"mem", "REG", "r-xp", "-r--------", 8, "/vscode/vscode-server/bin/linux-arm64/eaa41d57266683296de7d118f574d0c2652e1fc4/node_modules/node-pty/build/Release/pty.node"}, + {"mem", "REG", "r-xp", "-r--------", 8, "/usr/lib/aarch64-linux-gnu/libc.so.6"}, + {"mem", "REG", "r-xp", "-r--------", 8, "/usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.30"}, + {"mem", "REG", "r-xp", "-r--------", 8, "/usr/lib/aarch64-linux-gnu/libpthread.so.0"}, + {"mem", "REG", "r-xp", "-r--------", 8, "/usr/lib/aarch64-linux-gnu/libm.so.6"}, + {"mem", "REG", "r-xp", "-r--------", 8, "/usr/lib/aarch64-linux-gnu/libdl.so.2"}, + {"mem", "REG", "r-xp", "-r--------", 8, "/usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1"}, + {"mem", "REG", "r--p", "-r--------", 8, "/usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1"}, + } + + require.Equal(t, expected, mmaps) +} + +func TestMmapMetadataError(t *testing.T) { + ofl := &openFilesLister{ + proc: &procMock{}, + } + + _, err := ofl.mmapMetadata() + require.Error(t, err) +} + +type procMock struct { + fileDescriptors []uintptr + procMaps []*procfs.ProcMap + cwd string +} + +func (p *procMock) ProcMaps() ([]*procfs.ProcMap, error) { + if p.procMaps == nil { + return nil, errors.New("no proc maps") + } + return p.procMaps, nil +} + +func (p *procMock) FileDescriptors() ([]uintptr, error) { + if p.fileDescriptors == nil { + return nil, errors.New("no file descriptors") + } + return p.fileDescriptors, nil +} + +func (p *procMock) Cwd() (string, error) { + if p.cwd == "" { + return "", errors.New("no cwd") + } + return p.cwd, nil +} + +func TestFdMetadata(t *testing.T) { + ofl := &openFilesLister{ + pid: 123, + procPath: "/myproc", + + proc: &procMock{ + fileDescriptors: []uintptr{3, 4, 5}, + }, + + lstat: func(path string) (os.FileInfo, error) { + if path == "/myproc/123/fd/4" { + return nil, errors.New("some error") + } + return &mockFileInfo{ + mode: os.ModeSymlink | 0500, + name: "10", + size: 8, + sys: &syscall.Stat_t{Ino: 123}, + }, nil + }, + stat: func(string) (os.FileInfo, error) { + return &mockFileInfo{ + mode: 0400, + name: "file", + size: 0, + sys: &syscall.Stat_t{Ino: 456}, + }, nil + }, + readlink: func(string) (string, error) { + return "/some/file", nil + }, + socketInfo: map[uint64]socketInfo{}, + } + + files, err := ofl.fdMetadata() + require.NoError(t, err) + + expected := Files{ + {"3", "REG", "r-", "-r--------", 0, "/some/file"}, + {"5", "REG", "r-", "-r--------", 0, "/some/file"}, + } + + require.ElementsMatch(t, expected, files) +} + +func TestFdMetadataError(t *testing.T) { + ofl := &openFilesLister{ + proc: &procMock{}, + } + + _, err := ofl.fdMetadata() + require.Error(t, err) +} + +func TestFDStat(t *testing.T) { + testCases := []struct { + name string + fd uintptr + lstat func(string) (os.FileInfo, error) + stat func(string) (os.FileInfo, error) + readlink func(string) (string, error) + socketInfo map[uint64]socketInfo + expected *File + }{ + { + "success socket", + 3, + func(string) (os.FileInfo, error) { + return &mockFileInfo{ + mode: os.ModeSymlink | 0700, + name: "3", + size: 8, + sys: &syscall.Stat_t{Ino: 123}, + }, nil + }, + func(string) (os.FileInfo, error) { + return &mockFileInfo{ + mode: os.ModeSocket | 0600, + name: "socket[456]", + size: 0, + sys: &syscall.Stat_t{Ino: 456}, + }, nil + }, + func(string) (string, error) { + return "socket", nil + }, + map[uint64]socketInfo{ + 456: {"127.0.0.1:42->127.0.0.1:43", "connected", "tcp"}, + }, + &File{ + Fd: "3", + Type: "tcp", + FilePerm: "connected", + OpenPerm: "rw", + Size: 0, + Name: "127.0.0.1:42->127.0.0.1:43", + }, + }, + { + "success regular", + 4, + func(string) (os.FileInfo, error) { + return &mockFileInfo{ + mode: os.ModeSymlink | 0500, + name: "4", + size: 8, + sys: &syscall.Stat_t{Ino: 124}, + }, nil + }, + func(string) (os.FileInfo, error) { + return &mockFileInfo{ + mode: 0400, + name: "filename", + size: 34567890, + sys: &syscall.Stat_t{Ino: 789}, + }, nil + }, + func(string) (string, error) { + return "/some/filename", nil + }, + map[uint64]socketInfo{}, + &File{ + Fd: "4", + Type: "REG", + FilePerm: "-r--------", + OpenPerm: "r-", + Size: 34567890, + Name: "/some/filename", + }, + }, + { + "error lstat", + 5, + func(string) (os.FileInfo, error) { + return nil, errors.New("some error") + }, + func(string) (os.FileInfo, error) { + return &mockFileInfo{ + mode: os.ModeSymlink | 0500, + name: "4", + size: 8, + sys: &syscall.Stat_t{Ino: 124}, + }, nil + }, + func(string) (string, error) { + return "/some/filename", nil + }, + map[uint64]socketInfo{}, + nil, + }, + { + "error stat", + 6, + func(string) (os.FileInfo, error) { + return &mockFileInfo{ + mode: os.ModeSymlink | 0500, + name: "6", + size: 8, + sys: &syscall.Stat_t{Ino: 126}, + }, nil + }, + func(string) (os.FileInfo, error) { + return nil, errors.New("some error") + }, + func(string) (string, error) { + return "/some/filename", nil + }, + map[uint64]socketInfo{}, + nil, + }, + { + "error readlink", + 7, + func(string) (os.FileInfo, error) { + return &mockFileInfo{ + mode: os.ModeSymlink | 0500, + name: "7", + size: 8, + sys: &syscall.Stat_t{Ino: 127}, + }, nil + }, + func(string) (os.FileInfo, error) { + return &mockFileInfo{ + mode: 0400, + name: "filename", + size: 34567890, + sys: &syscall.Stat_t{Ino: 789}, + }, nil + }, + func(string) (string, error) { + return "", errors.New("some error") + }, + map[uint64]socketInfo{}, + nil, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ofl := &openFilesLister{ + lstat: tc.lstat, + stat: tc.stat, + readlink: tc.readlink, + socketInfo: tc.socketInfo, + } + + file, ok := ofl.fdStat(tc.fd) + if tc.expected == nil { + assert.False(t, ok) + } else { + require.True(t, ok) + assert.Equal(t, *tc.expected, file) + } + }) + } +} + +func TestReadSocketInfo(t *testing.T) { + t.Run("success", func(t *testing.T) { + info := readSocketInfo("testdata/readSocketInfo/1") + + expected := map[uint64]socketInfo{ + 10975: {"0.0.0.0:18777->0.0.0.0:0", "CLOSE", "udp6"}, + 40124: {"10.254.219.58:123->0.0.0.0:0", "UNKNOWN(42)", "udp"}, + 1986475: {"127.0.0.1:38489->0.0.0.0:0", "LISTEN", "tcp"}, + 1987112: {"stream:/tmp/.X11-unix/X2", "unconnected:listen", "unix"}, + 2506353: {"stream:", "connected:default", "unix"}, + 3359554: {"172.17.0.2:44594->20.199.39.224:443", "ESTABLISHED", "tcp6"}, + } + + require.Equal(t, expected, info) + }) + + t.Run("empty", func(t *testing.T) { + assert.Empty(t, readSocketInfo("testdata/readSocketInfo/2")) + }) + + t.Run("does not exist", func(t *testing.T) { + assert.Empty(t, readSocketInfo("testdata/readSocketInfo/3")) + }) +} + +func TestPermToString(t *testing.T) { + testCases := []struct { + perms *procfs.ProcMapPermissions + expected string + }{ + { + perms: &procfs.ProcMapPermissions{ + Private: true, + }, + expected: "---p", + }, + { + perms: &procfs.ProcMapPermissions{ + Read: true, + Shared: true, + }, + expected: "r--s", + }, + { + perms: &procfs.ProcMapPermissions{ + Write: true, + Private: true, + }, + expected: "-w-p", + }, + { + perms: &procfs.ProcMapPermissions{ + Execute: true, + Shared: true, + }, + expected: "--xs", + }, + { + perms: &procfs.ProcMapPermissions{ + Read: true, + Write: true, + Execute: true, + Shared: true, + }, + expected: "rwxs", + }, + } + + for _, tc := range testCases { + t.Run(tc.expected, func(t *testing.T) { + res := permToString(tc.perms) + assert.Equal(t, tc.expected, res) + }) + } +} + +func TestMmapFD(t *testing.T) { + testCases := []struct { + name string + path string + fileType string + cwd string + expected string + }{ + { + "regular file", + "/some/path", + "REG", + "/some/cwd", + "mem", + }, + { + "directory", + "/", + "DIR", + "", + "rtd", + }, + { + "cwd", + "/some/cwd", + "DIR", + "/some/cwd", + "cwd", + }, + { + "unknown", + "/some/path", + "PIPE", + "", + "unknown", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res := mmapFD(tc.path, tc.fileType, tc.cwd) + assert.Equal(t, tc.expected, res) + }) + } +} + +type mockFileInfo struct { + modTime time.Time + mode fs.FileMode + name string + size int64 + sys any +} + +func (m *mockFileInfo) IsDir() bool { + return m.mode.IsDir() +} +func (m *mockFileInfo) ModTime() time.Time { + return m.modTime +} +func (m *mockFileInfo) Mode() fs.FileMode { + return m.mode +} +func (m *mockFileInfo) Name() string { + return m.name +} +func (m *mockFileInfo) Size() int64 { + return m.size +} +func (m *mockFileInfo) Sys() any { + return m.sys +} + +func TestModeTypeToString(t *testing.T) { + testCases := []struct { + mode os.FileMode + expected string + }{ + {os.ModeSocket, "SOCKET"}, + {os.ModeNamedPipe | os.ModeAppend, "PIPE"}, + {os.ModeDevice | os.ModeSetgid, "DEV"}, + {os.ModeDir | os.ModeSetuid, "DIR"}, + {os.ModeCharDevice | os.ModeExclusive, "CHAR"}, + {os.ModeSymlink | os.ModeSticky, "LINK"}, + {os.ModeIrregular, "?"}, + {0, "REG"}, + } + + for _, tc := range testCases { + t.Run(tc.expected, func(t *testing.T) { + res := modeTypeToString(tc.mode) + assert.Equal(t, tc.expected, res) + }) + } +} + +func TestFileStats(t *testing.T) { + testCases := []struct { + name string + fileType os.FileMode + fileTy string + filePerm os.FileMode + size int64 + inode uint64 + }{ + { + "regular file", + 0, + "REG", + 0777, + 12, + 42, + }, + { + "socket", + os.ModeSocket, + "SOCKET", + 0600, + 0, + 123456789, + }, + { + "symlink", + os.ModeSymlink, + "LINK", + 0666, + 8, + 9999, + }, + { + "irregular", + os.ModeIrregular, + "?", + 0, + 0, + 0, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + stat := func(string) (os.FileInfo, error) { + fi := &mockFileInfo{ + modTime: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), + mode: tc.fileType | tc.filePerm, + name: "somename", + size: tc.size, + sys: &syscall.Stat_t{Ino: tc.inode}, + } + return fi, nil + } + + fileType, perm, size, ino := fileStats(stat, "/some/path") + require.NotEmpty(t, fileType) + + assert.Equal(t, tc.fileTy, fileType) + assert.Equal(t, tc.filePerm.String(), perm) + assert.Equal(t, tc.size, size) + assert.Equal(t, tc.inode, ino) + }) + } +} + +func TestFileStatsErr(t *testing.T) { + stat := func(string) (os.FileInfo, error) { + return nil, errors.New("some error") + } + fileType, _, _, _ := fileStats(stat, "/some/path") + require.Empty(t, fileType) +} + +func TestFileStatsNoSys(t *testing.T) { + stat := func(string) (os.FileInfo, error) { + return &mockFileInfo{}, nil + } + + fileType, perm, size, ino := fileStats(stat, "/some/path") + assert.Equal(t, "REG", fileType) + assert.Equal(t, "----------", perm) + assert.EqualValues(t, 0, size) + assert.EqualValues(t, 0, ino) +} + +func TestProcPath(t *testing.T) { + assert.Equal(t, "/proc", procPath()) + + t.Setenv("HOST_PROC", "/myproc") + assert.Equal(t, "/myproc", procPath()) +} diff --git a/pkg/util/lsof/lsof_windows.go b/pkg/util/lsof/lsof_windows.go new file mode 100644 index 0000000000000..12a59d0b78445 --- /dev/null +++ b/pkg/util/lsof/lsof_windows.go @@ -0,0 +1,10 @@ +// 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 lsof + +func openFiles(_ int) (Files, error) { + return nil, ErrNotImplemented +} diff --git a/pkg/util/lsof/testdata/mmapMetadata/1/maps b/pkg/util/lsof/testdata/mmapMetadata/1/maps new file mode 100644 index 0000000000000..37dcade292898 --- /dev/null +++ b/pkg/util/lsof/testdata/mmapMetadata/1/maps @@ -0,0 +1,113 @@ +00400000-051f9000 r-xp 00000000 fe:01 2700336 /vscode/vscode-server/bin/linux-arm64/eaa41d57266683296de7d118f574d0c2652e1fc4/node +0520c000-05210000 r--p 04dfc000 fe:01 2700336 /vscode/vscode-server/bin/linux-arm64/eaa41d57266683296de7d118f574d0c2652e1fc4/node +05210000-0524d000 rw-p 04e00000 fe:01 2700336 /vscode/vscode-server/bin/linux-arm64/eaa41d57266683296de7d118f574d0c2652e1fc4/node +0524d000-05278000 rw-p 00000000 00:00 0 +20845000-20a14000 rw-p 00000000 00:00 0 [heap] +47d6d4c0000-47d6d4c4000 rw-p 00000000 00:00 0 +6f111880000-6f1118c0000 rw-p 00000000 00:00 0 +bd4dc040000-bd4dc080000 rw-p 00000000 00:00 0 +10c774fc0000-10c775000000 rw-p 00000000 00:00 0 +110f88640000-110f88680000 rw-p 00000000 00:00 0 +11d92bcc0000-11d92bd00000 rw-p 00000000 00:00 0 +123f34200000-123f34240000 rw-p 00000000 00:00 0 +13ba9e700000-13ba9e740000 rw-p 00000000 00:00 0 +16a407400000-16a407440000 rw-p 00000000 00:00 0 +1714928c0000-171492900000 rw-p 00000000 00:00 0 +191d9ca80000-191d9cac0000 rw-p 00000000 00:00 0 +1986a9f40000-1986a9f80000 rw-p 00000000 00:00 0 +1db13ddc0000-1db13de00000 rw-p 00000000 00:00 0 +1e91ef040000-1e91ef07c000 r--p 00000000 00:00 0 +20da0d040000-20da0d080000 rw-p 00000000 00:00 0 +25f793e80000-25f793ec0000 ---p 00000000 00:00 0 +276641500000-276641540000 rw-p 00000000 00:00 0 +27cec5340000-27cec5380000 rw-p 00000000 00:00 0 +2c2e16b00000-2c2e16b40000 ---p 00000000 00:00 0 +33510d900000-33510d940000 rw-p 00000000 00:00 0 +33ea56ac0000-33ea56b00000 rw-p 00000000 00:00 0 +340acfc00000-340acfc42000 rw-p 00000000 00:00 0 +36b130b80000-36b130bc0000 ---p 00000000 00:00 0 +37a8bbc80000-37a8bbcc0000 rw-p 00000000 00:00 0 +3e6850cc0000-3e6850d00000 rw-p 00000000 00:00 0 +3eba17100000-3eba17140000 ---p 00000000 00:00 0 +ffff88000000-ffff88050000 rw-p 00000000 00:00 0 +ffff88050000-ffff8c000000 ---p 00000000 00:00 0 +ffff90000000-ffff9015c000 rw-p 00000000 00:00 0 +ffff9015c000-ffff94000000 ---p 00000000 00:00 0 +ffff94000000-ffff94022000 rw-p 00000000 00:00 0 +ffff94022000-ffff98000000 ---p 00000000 00:00 0 +ffff9b600000-ffff9b610000 ---p 00000000 00:00 0 +ffff9b610000-ffff9be10000 rw-p 00000000 00:00 0 +ffff9c000000-ffff9c04a000 rw-p 00000000 00:00 0 +ffff9c04a000-ffffa0000000 ---p 00000000 00:00 0 +ffffa0200000-ffffa0210000 ---p 00000000 00:00 0 +ffffa0210000-ffffa0a10000 rw-p 00000000 00:00 0 +ffffa0c00000-ffffa0c10000 ---p 00000000 00:00 0 +ffffa0c10000-ffffa1410000 rw-p 00000000 00:00 0 +ffffa1600000-ffffa1610000 ---p 00000000 00:00 0 +ffffa1610000-ffffa1e10000 rw-p 00000000 00:00 0 +ffffa2000000-ffffa2002000 rw-p 00000000 00:00 0 +ffffa2002000-ffffa2003000 ---p 00000000 00:00 0 +ffffa2003000-ffffa203f000 rwxp 00000000 00:00 0 +ffffa203f000-ffffa2040000 ---p 00000000 00:00 0 +ffffa2040000-ffffa2042000 rw-p 00000000 00:00 0 +ffffa2042000-ffffa2043000 ---p 00000000 00:00 0 +ffffa2043000-ffffa207f000 rwxp 00000000 00:00 0 +ffffa207f000-ffffb2000000 ---p 00000000 00:00 0 +ffffb2200000-ffffb2210000 ---p 00000000 00:00 0 +ffffb2210000-ffffb2a10000 rw-p 00000000 00:00 0 +ffffb2c00000-ffffb2c10000 ---p 00000000 00:00 0 +ffffb2c10000-ffffb3410000 rw-p 00000000 00:00 0 +ffffb3600000-ffffb3610000 ---p 00000000 00:00 0 +ffffb3610000-ffffb3e10000 rw-p 00000000 00:00 0 +ffffb4000000-ffffb4021000 rw-p 00000000 00:00 0 +ffffb4021000-ffffb8000000 ---p 00000000 00:00 0 +ffffb8200000-ffffb8210000 ---p 00000000 00:00 0 +ffffb8210000-ffffb8a10000 rw-p 00000000 00:00 0 +ffffb8b60000-ffffb8b61000 r-xp 00000000 00:3d 2238667 /usr/lib/aarch64-linux-gnu/libutil.so.1 +ffffb8b61000-ffffb8b70000 ---p 00001000 00:3d 2238667 /usr/lib/aarch64-linux-gnu/libutil.so.1 +ffffb8b70000-ffffb8b71000 r--p 00000000 00:3d 2238667 /usr/lib/aarch64-linux-gnu/libutil.so.1 +ffffb8b71000-ffffb8b72000 rw-p 00001000 00:3d 2238667 /usr/lib/aarch64-linux-gnu/libutil.so.1 +ffffb8b80000-ffffb8b84000 rw-p 00000000 00:00 0 +ffffb8b84000-ffffb8c00000 ---p 00000000 00:00 0 +ffffb8c00000-ffffb8c10000 ---p 00000000 00:00 0 +ffffb8c10000-ffffb9410000 rw-p 00000000 00:00 0 +ffffb9430000-ffffb943e000 r-xp 00000000 fe:01 2700855 /vscode/vscode-server/bin/linux-arm64/eaa41d57266683296de7d118f574d0c2652e1fc4/node_modules/node-pty/build/Release/pty.node +ffffb943e000-ffffb944d000 ---p 0000e000 fe:01 2700855 /vscode/vscode-server/bin/linux-arm64/eaa41d57266683296de7d118f574d0c2652e1fc4/node_modules/node-pty/build/Release/pty.node +ffffb944d000-ffffb944e000 r--p 0000d000 fe:01 2700855 /vscode/vscode-server/bin/linux-arm64/eaa41d57266683296de7d118f574d0c2652e1fc4/node_modules/node-pty/build/Release/pty.node +ffffb944e000-ffffb944f000 rw-p 0000e000 fe:01 2700855 /vscode/vscode-server/bin/linux-arm64/eaa41d57266683296de7d118f574d0c2652e1fc4/node_modules/node-pty/build/Release/pty.node +ffffb9450000-ffffb95d8000 r-xp 00000000 00:3d 2238543 /usr/lib/aarch64-linux-gnu/libc.so.6 +ffffb95d8000-ffffb95e7000 ---p 00188000 00:3d 2238543 /usr/lib/aarch64-linux-gnu/libc.so.6 +ffffb95e7000-ffffb95eb000 r--p 00187000 00:3d 2238543 /usr/lib/aarch64-linux-gnu/libc.so.6 +ffffb95eb000-ffffb95ed000 rw-p 0018b000 00:3d 2238543 /usr/lib/aarch64-linux-gnu/libc.so.6 +ffffb95ed000-ffffb95f9000 rw-p 00000000 00:00 0 +ffffb9600000-ffffb980a000 r-xp 00000000 00:3d 2238651 /usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.30 +ffffb980a000-ffffb9819000 ---p 0020a000 00:3d 2238651 /usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.30 +ffffb9819000-ffffb9824000 r--p 00209000 00:3d 2238651 /usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.30 +ffffb9824000-ffffb9827000 rw-p 00214000 00:3d 2238651 /usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.30 +ffffb9827000-ffffb982a000 rw-p 00000000 00:00 0 +ffffb9830000-ffffb9840000 ---p 00000000 00:00 0 +ffffb9840000-ffffb9860000 rw-p 00000000 00:00 0 +ffffb9860000-ffffb9861000 r-xp 00000000 00:3d 2238637 /usr/lib/aarch64-linux-gnu/libpthread.so.0 +ffffb9861000-ffffb9870000 ---p 00001000 00:3d 2238637 /usr/lib/aarch64-linux-gnu/libpthread.so.0 +ffffb9870000-ffffb9871000 r--p 00000000 00:3d 2238637 /usr/lib/aarch64-linux-gnu/libpthread.so.0 +ffffb9871000-ffffb9872000 rw-p 00001000 00:3d 2238637 /usr/lib/aarch64-linux-gnu/libpthread.so.0 +ffffb9880000-ffffb9894000 r-xp 00000000 00:3d 2238568 /usr/lib/aarch64-linux-gnu/libgcc_s.so.1 +ffffb9894000-ffffb98a3000 ---p 00014000 00:3d 2238568 /usr/lib/aarch64-linux-gnu/libgcc_s.so.1 +ffffb98a3000-ffffb98a4000 r--p 00013000 00:3d 2238568 /usr/lib/aarch64-linux-gnu/libgcc_s.so.1 +ffffb98a4000-ffffb98a5000 rw-p 00014000 00:3d 2238568 /usr/lib/aarch64-linux-gnu/libgcc_s.so.1 +ffffb98b0000-ffffb9936000 r-xp 00000000 00:3d 2238595 /usr/lib/aarch64-linux-gnu/libm.so.6 +ffffb9936000-ffffb9945000 ---p 00086000 00:3d 2238595 /usr/lib/aarch64-linux-gnu/libm.so.6 +ffffb9945000-ffffb9946000 r--p 00085000 00:3d 2238595 /usr/lib/aarch64-linux-gnu/libm.so.6 +ffffb9946000-ffffb9947000 rw-p 00086000 00:3d 2238595 /usr/lib/aarch64-linux-gnu/libm.so.6 +ffffb9950000-ffffb9951000 r-xp 00000000 00:3d 2238557 /usr/lib/aarch64-linux-gnu/libdl.so.2 +ffffb9951000-ffffb9960000 ---p 00001000 00:3d 2238557 /usr/lib/aarch64-linux-gnu/libdl.so.2 +ffffb9960000-ffffb9961000 r--p 00000000 00:3d 2238557 /usr/lib/aarch64-linux-gnu/libdl.so.2 +ffffb9961000-ffffb9962000 rw-p 00001000 00:3d 2238557 /usr/lib/aarch64-linux-gnu/libdl.so.2 +ffffb9972000-ffffb999d000 r-xp 00000000 00:3d 2238525 /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1 +ffffb999d000-ffffb99a2000 rw-p 00000000 00:00 0 +ffffb99a7000-ffffb99a9000 rw-p 00000000 00:00 0 +ffffb99a9000-ffffb99ab000 r--p 00000000 00:00 0 [vvar] +ffffb99ab000-ffffb99ac000 r-xp 00000000 00:00 0 [vdso] +ffffb99ac000-ffffb99ae000 r--p 0002a000 00:3d 2238525 /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1 +ffffb99ae000-ffffb99b0000 rw-p 0002c000 00:3d 2238525 /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1 +ffffd2308000-ffffd2329000 rw-p 00000000 00:00 0 [stack] diff --git a/pkg/util/lsof/testdata/mmapMetadata/2/.gitkeep b/pkg/util/lsof/testdata/mmapMetadata/2/.gitkeep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/pkg/util/lsof/testdata/readSocketInfo/1/net/tcp b/pkg/util/lsof/testdata/readSocketInfo/1/net/tcp new file mode 100644 index 0000000000000..d97c63f1ffc26 --- /dev/null +++ b/pkg/util/lsof/testdata/readSocketInfo/1/net/tcp @@ -0,0 +1,2 @@ + sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode + 0: 0100007F:9659 00000000:0000 0A 00000000:00000000 00:00000000 00000000 503 0 1986475 1 00000000472d971e 100 0 0 10 0 diff --git a/pkg/util/lsof/testdata/readSocketInfo/1/net/tcp6 b/pkg/util/lsof/testdata/readSocketInfo/1/net/tcp6 new file mode 100644 index 0000000000000..2a1a21ef63527 --- /dev/null +++ b/pkg/util/lsof/testdata/readSocketInfo/1/net/tcp6 @@ -0,0 +1,2 @@ + sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode + 5: 020011AC:AE32 E027C714:01BB 01 00000000:00000000 00:00000000 00000000 503 0 3359554 1 000000000e4d519b 20 4 11 10 -1 diff --git a/pkg/util/lsof/testdata/readSocketInfo/1/net/udp b/pkg/util/lsof/testdata/readSocketInfo/1/net/udp new file mode 100644 index 0000000000000..773c99d7d0bbe --- /dev/null +++ b/pkg/util/lsof/testdata/readSocketInfo/1/net/udp @@ -0,0 +1,2 @@ + sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops + 16: 3ADBFE0A:007B 00000000:0000 2A 00000000:00000000 00:00000000 00000000 74 0 40124 2 f203ca80 0 diff --git a/pkg/util/lsof/testdata/readSocketInfo/1/net/udp6 b/pkg/util/lsof/testdata/readSocketInfo/1/net/udp6 new file mode 100644 index 0000000000000..3d7b246465ba9 --- /dev/null +++ b/pkg/util/lsof/testdata/readSocketInfo/1/net/udp6 @@ -0,0 +1,2 @@ + sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops +110: 00000000:4959 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 10975 2 ffff88023bbd30c0 0 diff --git a/pkg/util/lsof/testdata/readSocketInfo/1/net/unix b/pkg/util/lsof/testdata/readSocketInfo/1/net/unix new file mode 100644 index 0000000000000..06dcbd8d655ec --- /dev/null +++ b/pkg/util/lsof/testdata/readSocketInfo/1/net/unix @@ -0,0 +1,3 @@ +Num RefCount Protocol Flags Type St Inode Path +000000007ffe6556: 00000003 00000000 00000000 0001 03 2506353 +00000000bde37b66: 00000002 00000000 00010000 0001 01 1987112 /tmp/.X11-unix/X2 diff --git a/pkg/util/lsof/testdata/readSocketInfo/2/net/.gitkeep b/pkg/util/lsof/testdata/readSocketInfo/2/net/.gitkeep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/pkg/util/lsof/types.go b/pkg/util/lsof/types.go new file mode 100644 index 0000000000000..60138bcda4d02 --- /dev/null +++ b/pkg/util/lsof/types.go @@ -0,0 +1,61 @@ +// 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 lsof + +import ( + "bytes" + "fmt" + "text/tabwriter" +) + +/* +Abstract of lsof output (see `man lsof` for details): + +COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME +systemd 1477 ubuntu rtd DIR 259,1 4096 2 / +systemd 1477 ubuntu txt REG 259,1 1849992 3324 /usr/lib/systemd/systemd +systemd 1477 ubuntu mem REG 259,1 613064 4798 /usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.10.4 +systemd 1477 ubuntu 0r CHR 1,3 0t0 5 /dev/null +systemd 1477 ubuntu 1u unix 0x0000000000000000 0t0 21781 type=STREAM +systemd 1477 ubuntu 3u unix 0x0000000000000000 0t0 21261 type=DGRAM +systemd 1477 ubuntu 4u a_inode 0,15 0 51 [eventpoll] +systemd 1477 ubuntu 5u a_inode 0,15 0 51 [signalfd] +systemd 1477 ubuntu 6r a_inode 0,15 0 51 inotify +systemd 1477 ubuntu 7r DIR 0,28 0 4945 /sys/fs/cgroup/user.slice/user-1000.slice/user@1000.service +systemd 1477 ubuntu 8u a_inode 0,15 0 51 [timerfd] +systemd 1477 ubuntu 9u a_inode 0,15 0 51 [eventpoll] +systemd 1477 ubuntu 14r REG 0,22 0 4026532073 /proc/swaps +systemd 1477 ubuntu 15u netlink 0t0 21277 KOBJECT_UEVENT + +Here we don't care about COMMAND, PID, and USER, since we only look at a single process +*/ + +// File represents an open file +// The fields are not guaranteed to match lsof output, but they are good enough for debugging +type File struct { + Fd string + Type string + OpenPerm string + FilePerm string + Size int64 + Name string +} + +// Files represents a list of open files +type Files []File + +func (files Files) String() string { + var out bytes.Buffer + writer := tabwriter.NewWriter(&out, 1, 1, 1, ' ', 0) + + fmt.Fprint(writer, "FD\tType\tSize\tOpenPerm\tFilePerm\tName\t\n") + for _, file := range files { + fmt.Fprintf(writer, "%s\t%s\t%d\t%s\t%s\t%s\t\n", file.Fd, file.Type, file.Size, file.OpenPerm, file.FilePerm, file.Name) + } + + _ = writer.Flush() + return out.String() +} diff --git a/pkg/util/lsof/types_test.go b/pkg/util/lsof/types_test.go new file mode 100644 index 0000000000000..c2f6dc829281e --- /dev/null +++ b/pkg/util/lsof/types_test.go @@ -0,0 +1,26 @@ +// 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 lsof + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFilesString(t *testing.T) { + files := Files{ + {"3", "REG", "r-", "-rwx------", 0, "/some/file"}, + {"mem", "REG", "r-xp", "-r--------", 8, "/usr/lib/aarch64-linux-gnu/libutil.so.1"}, + } + + expected := `FD Type Size OpenPerm FilePerm Name +3 REG 0 r- -rwx------ /some/file +mem REG 8 r-xp -r-------- /usr/lib/aarch64-linux-gnu/libutil.so.1 +` + + require.Equal(t, expected, files.String()) +} diff --git a/pkg/util/pdhutil/pdhhelper.go b/pkg/util/pdhutil/pdhhelper.go index a5e41503862bd..48a43f4487b58 100644 --- a/pkg/util/pdhutil/pdhhelper.go +++ b/pkg/util/pdhutil/pdhhelper.go @@ -7,6 +7,7 @@ package pdhutil import ( + "errors" "fmt" "reflect" "strconv" @@ -98,8 +99,8 @@ func refreshPdhObjectCache(forceRefresh bool) (didrefresh bool, err error) { } else if refreshInterval < 0 { // invalid value e := "windows_counter_refresh_interval cannot be a negative number" - log.Errorf(e) - return false, fmt.Errorf(e) + log.Errorf("%s", e) + return false, errors.New(e) } // Only refresh at most every refresh_interval seconds @@ -132,8 +133,8 @@ func refreshPdhObjectCache(forceRefresh bool) (didrefresh bool, err error) { uintptr(1)) // do refresh if r != PDH_MORE_DATA { e := fmt.Sprintf("Failed to refresh performance counters (%#x)", r) - log.Errorf(e) - return false, fmt.Errorf(e) + log.Errorf("%s", e) + return false, errors.New(e) } // refresh successful diff --git a/pkg/util/static_tags.go b/pkg/util/static_tags.go index 2587b98c36a07..5239f3371ab6f 100644 --- a/pkg/util/static_tags.go +++ b/pkg/util/static_tags.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" configUtils "github.com/DataDog/datadog-agent/pkg/config/utils" "github.com/DataDog/datadog-agent/pkg/util/fargate" "github.com/DataDog/datadog-agent/pkg/util/kubernetes/clustername" @@ -35,7 +36,7 @@ func GetStaticTagsSlice(ctx context.Context) []string { tags = append(tags, configUtils.GetConfiguredTags(config.Datadog(), false)...) // EKS Fargate specific tags - if config.IsFeaturePresent(config.EKSFargate) { + if env.IsFeaturePresent(env.EKSFargate) { // eks_fargate_node node, err := fargate.GetEKSFargateNodename() if err != nil { diff --git a/pkg/util/static_tags_test.go b/pkg/util/static_tags_test.go index 2bbb368ef8f2c..8ab0ab515f0aa 100644 --- a/pkg/util/static_tags_test.go +++ b/pkg/util/static_tags_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/DataDog/datadog-agent/pkg/config" + "github.com/DataDog/datadog-agent/pkg/config/env" configmock "github.com/DataDog/datadog-agent/pkg/config/mock" ) @@ -20,7 +21,7 @@ func TestStaticTags(t *testing.T) { mockConfig.SetWithoutSource("kubernetes_kubelet_nodename", "eksnode") defer mockConfig.SetWithoutSource("kubernetes_kubelet_nodename", "") - config.SetFeatures(t, config.EKSFargate) + config.SetFeatures(t, env.EKSFargate) t.Run("just tags", func(t *testing.T) { mockConfig.SetWithoutSource("tags", []string{"some:tag", "another:tag", "nocolon"}) @@ -62,7 +63,7 @@ func TestStaticTagsSlice(t *testing.T) { mockConfig.SetWithoutSource("kubernetes_kubelet_nodename", "eksnode") defer mockConfig.SetWithoutSource("kubernetes_kubelet_nodename", "") - config.SetFeatures(t, config.EKSFargate) + config.SetFeatures(t, env.EKSFargate) t.Run("just tags", func(t *testing.T) { mockConfig.SetWithoutSource("tags", []string{"some:tag", "another:tag", "nocolon"}) diff --git a/pkg/util/system/go.mod b/pkg/util/system/go.mod index 9f7c785dc50bb..94fb814f4328c 100644 --- a/pkg/util/system/go.mod +++ b/pkg/util/system/go.mod @@ -20,7 +20,7 @@ require ( github.com/shirou/gopsutil/v3 v3.23.12 github.com/stretchr/testify v1.9.0 go.uber.org/atomic v1.11.0 - golang.org/x/sys v0.23.0 + golang.org/x/sys v0.24.0 ) require ( diff --git a/pkg/util/system/go.sum b/pkg/util/system/go.sum index 81eb10e853cb4..20e9ba105b1c4 100644 --- a/pkg/util/system/go.sum +++ b/pkg/util/system/go.sum @@ -45,8 +45,8 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w 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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/util/system/socket/go.mod b/pkg/util/system/socket/go.mod index 6cf00f4bb186c..1926a7b86e021 100644 --- a/pkg/util/system/socket/go.mod +++ b/pkg/util/system/socket/go.mod @@ -7,6 +7,6 @@ require github.com/Microsoft/go-winio v0.6.1 require ( golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/tools v0.24.0 // indirect ) diff --git a/pkg/util/system/socket/go.sum b/pkg/util/system/socket/go.sum index d0ab11c4371cf..a14cc3b7182a8 100644 --- a/pkg/util/system/socket/go.sum +++ b/pkg/util/system/socket/go.sum @@ -4,7 +4,7 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +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/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= diff --git a/pkg/util/trivy/cache_test.go b/pkg/util/trivy/cache_test.go index bf9e673e3ab6a..8d969bc85d0e2 100644 --- a/pkg/util/trivy/cache_test.go +++ b/pkg/util/trivy/cache_test.go @@ -239,8 +239,7 @@ func TestCustomBoltCache_GarbageCollector(t *testing.T) { fx.Provide(func() log.Component { return logmock.New(t) }), config.MockModule(), fx.Supply(context.Background()), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) image1 := &workloadmeta.ContainerImageMetadata{ @@ -398,7 +397,6 @@ type cacheDeps struct { func createCacheDeps(t *testing.T) cacheDeps { return fxutil.Test[cacheDeps](t, fx.Options( core.MockBundle(), - fx.Supply(workloadmeta.NewParams()), - workloadmetafxmock.MockModule(), + workloadmetafxmock.MockModule(workloadmeta.NewParams()), )) } diff --git a/pkg/util/trivy/containerd.go b/pkg/util/trivy/containerd.go index 36e3242c57ee7..94b8b7dab0f8b 100644 --- a/pkg/util/trivy/containerd.go +++ b/pkg/util/trivy/containerd.go @@ -21,7 +21,7 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/images/archive" "github.com/containerd/containerd/namespaces" - refdocker "github.com/containerd/containerd/reference/docker" + refdocker "github.com/distribution/reference" api "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/go-connections/nat" diff --git a/pkg/util/trivy/trivy.go b/pkg/util/trivy/trivy.go index 7c36b4aafb6c9..c37803c49d78d 100644 --- a/pkg/util/trivy/trivy.go +++ b/pkg/util/trivy/trivy.go @@ -46,8 +46,8 @@ import ( "github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/vulnerability" "github.com/containerd/containerd" - "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/leases" + "github.com/containerd/errdefs" "github.com/docker/docker/client" // This is required to load sqlite based RPM databases diff --git a/pkg/util/uuid/go.mod b/pkg/util/uuid/go.mod index 03f77d6de09c2..06d13935990a4 100644 --- a/pkg/util/uuid/go.mod +++ b/pkg/util/uuid/go.mod @@ -12,7 +12,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/cache v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/util/log v0.56.0-rc.3 github.com/shirou/gopsutil/v3 v3.24.1 - golang.org/x/sys v0.23.0 + golang.org/x/sys v0.24.0 ) require ( diff --git a/pkg/util/uuid/go.sum b/pkg/util/uuid/go.sum index b8a2045fcdf57..2dfbaa1533fbf 100644 --- a/pkg/util/uuid/go.sum +++ b/pkg/util/uuid/go.sum @@ -44,8 +44,8 @@ golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7w 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.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/util/winutil/go.mod b/pkg/util/winutil/go.mod index 0b79c248b22d1..7e13fa6ea5dc4 100644 --- a/pkg/util/winutil/go.mod +++ b/pkg/util/winutil/go.mod @@ -13,7 +13,7 @@ require ( github.com/fsnotify/fsnotify v1.7.0 github.com/stretchr/testify v1.9.0 go.uber.org/atomic v1.11.0 - golang.org/x/sys v0.23.0 + golang.org/x/sys v0.24.0 ) require ( diff --git a/pkg/util/winutil/go.sum b/pkg/util/winutil/go.sum index 86a03e3ae7a2e..a7b7f298fe1a0 100644 --- a/pkg/util/winutil/go.sum +++ b/pkg/util/winutil/go.sum @@ -10,8 +10,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/pkg/util/winutil/iisconfig/apmtags.go b/pkg/util/winutil/iisconfig/apmtags.go new file mode 100644 index 0000000000000..ee940ac2b7f5e --- /dev/null +++ b/pkg/util/winutil/iisconfig/apmtags.go @@ -0,0 +1,116 @@ +// 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. +//go:build windows + +// Package iisconfig manages iis configuration +package iisconfig + +/* +the file datadog.json can be located anywhere; it is path-relative to a .net application +give the path name, read the json and return it as a map of string/string +*/ + +import ( + "encoding/json" + "encoding/xml" + "os" + + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +// APMTags holds the APM tags +type APMTags struct { + DDService string + DDEnv string + DDVersion string +} + +// ReadDatadogJSON reads a datadog.json file and returns the APM tags +func ReadDatadogJSON(datadogJSONPath string) (APMTags, error) { + var datadogJSON map[string]string + var apmtags APMTags + + file, err := os.Open(datadogJSONPath) + if err != nil { + return apmtags, err + } + defer file.Close() + + decoder := json.NewDecoder(file) + err = decoder.Decode(&datadogJSON) + if err != nil { + return apmtags, err + } + apmtags.DDService = datadogJSON["DD_SERVICE"] + apmtags.DDEnv = datadogJSON["DD_ENV"] + apmtags.DDVersion = datadogJSON["DD_VERSION"] + return apmtags, nil +} + +type iisAppSetting struct { + Key string `xml:"key,attr"` + Value string `xml:"value,attr"` +} +type iisAppSettings struct { + XMLName xml.Name `xml:"appSettings"` + Adds []iisAppSetting `xml:"add"` +} + +type appConfiguration struct { + XMLName xml.Name `xml:"configuration"` + AppSettings iisAppSettings +} + +var ( + errorlogcount = 0 +) + +// ReadDotNetConfig reads an iis config file(xml) and returns the APM tags +func ReadDotNetConfig(cfgpath string) (APMTags, error) { //(APMTags, error) { + var newcfg appConfiguration + var apmtags APMTags + var chasedatadogJSON string + f, err := os.ReadFile(cfgpath) + if err != nil { + return apmtags, err + } + err = xml.Unmarshal(f, &newcfg) + if err != nil { + return apmtags, err + } + for _, setting := range newcfg.AppSettings.Adds { + switch setting.Key { + case "DD_SERVICE": + apmtags.DDService = setting.Value + case "DD_ENV": + apmtags.DDEnv = setting.Value + case "DD_VERSION": + apmtags.DDVersion = setting.Value + case "DD_TRACE_CONFIG_FILE": + chasedatadogJSON = setting.Value + } + } + if len(chasedatadogJSON) > 0 { + ddjson, err := ReadDatadogJSON(chasedatadogJSON) + if err == nil { + if len(ddjson.DDService) > 0 { + apmtags.DDService = ddjson.DDService + } + if len(ddjson.DDEnv) > 0 { + apmtags.DDEnv = ddjson.DDEnv + } + if len(ddjson.DDVersion) > 0 { + apmtags.DDVersion = ddjson.DDVersion + } + } else { + // only log every 1000 occurrences because if this is misconfigured, it could flood the log + if errorlogcount%1000 == 0 { + log.Warnf("Error reading configured datadog.json file %s: %v", chasedatadogJSON, err) + } + errorlogcount++ + } + } + return apmtags, nil +} diff --git a/pkg/util/winutil/iisconfig/apmtags_test.go b/pkg/util/winutil/iisconfig/apmtags_test.go new file mode 100644 index 0000000000000..2844d5c515715 --- /dev/null +++ b/pkg/util/winutil/iisconfig/apmtags_test.go @@ -0,0 +1,120 @@ +// 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. +//go:build windows + +package iisconfig + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestAppConfig(t *testing.T) { + path, err := os.Getwd() + require.Nil(t, err) + + apppath := filepath.Join(path, "testdata", "app_1.config.xml") + //apppath := filepath.Join(path, "testdata", "iisconfig.xml") + iisCfg, err := ReadDotNetConfig(apppath) + assert.Nil(t, err) + assert.NotNil(t, iisCfg) + + assert.Equal(t, iisCfg.DDService, "service1") + assert.Equal(t, iisCfg.DDEnv, "false") + assert.Equal(t, iisCfg.DDVersion, "1.0-prerelease") + +} + +func TestPathSplitting(t *testing.T) { + + t.Run("Test Root path", func(t *testing.T) { + sp := splitPaths("/") + assert.Equal(t, 0, len(sp)) + }) + + t.Run("Test path depth 3", func(t *testing.T) { + sp := splitPaths("/path/to/app") + assert.Equal(t, 3, len(sp)) + assert.Equal(t, "path", sp[0]) + assert.Equal(t, "to", sp[1]) + assert.Equal(t, "app", sp[2]) + }) + + t.Run("Test path depth 3 with trailing slash", func(t *testing.T) { + sp := splitPaths("/path/to/app/") + assert.Equal(t, 3, len(sp)) + assert.Equal(t, "path", sp[0]) + assert.Equal(t, "to", sp[1]) + assert.Equal(t, "app", sp[2]) + }) + +} + +func TestAPMTags(t *testing.T) { + path, err := os.Getwd() + require.Nil(t, err) + + iisCfgPath = filepath.Join(path, "testdata", "apptest.xml") + testroot := filepath.Join(path, "testdata") + os.Setenv("TESTROOTDIR", testroot) + defer os.Unsetenv("TESTROOTDIR") + + iisCfg, err := NewDynamicIISConfig() + assert.Nil(t, err) + assert.NotNil(t, iisCfg) + + err = iisCfg.Start() + assert.Nil(t, err) + + t.Run("Test simple root path", func(t *testing.T) { + tags, _ := iisCfg.GetAPMTags(2, "/") + assert.Equal(t, "app1", tags.DDService) + }) + t.Run("Test deeper path from top app", func(t *testing.T) { + tags, _ := iisCfg.GetAPMTags(2, "/path/to/app") + assert.Equal(t, "app1", tags.DDService) + }) + + t.Run("test top level app2", func(t *testing.T) { + tags, _ := iisCfg.GetAPMTags(2, "/app2") + assert.Equal(t, "app2", tags.DDService) + }) + t.Run("test deeper app2", func(t *testing.T) { + tags, _ := iisCfg.GetAPMTags(2, "/app2/some/path") + assert.Equal(t, "app2", tags.DDService) + }) + + t.Run("test app3 nested in app2", func(t *testing.T) { + tags, _ := iisCfg.GetAPMTags(2, "/app2/app3") + assert.Equal(t, "app3", tags.DDService) + }) + t.Run("test app3 nested in app2 with path", func(t *testing.T) { + tags, _ := iisCfg.GetAPMTags(2, "/app2/app3/some/path") + assert.Equal(t, "app3", tags.DDService) + }) + + t.Run("test secondary site", func(t *testing.T) { + tags, _ := iisCfg.GetAPMTags(3, "/") + assert.Equal(t, "app1", tags.DDService) + }) + t.Run("test secondary site app 3", func(t *testing.T) { + // this should still be app1 because the root path on the + // second site is different + tags, _ := iisCfg.GetAPMTags(3, "/app2/app3") + assert.Equal(t, "app1", tags.DDService) + }) + t.Run("test secondary site actual app3", func(t *testing.T) { + tags, _ := iisCfg.GetAPMTags(3, "/siteapp2/siteapp3") + assert.Equal(t, "app3", tags.DDService) + }) + t.Run("test secondary site actual app3 with file", func(t *testing.T) { + tags, _ := iisCfg.GetAPMTags(3, "/siteapp2/siteapp3/somefile") + assert.Equal(t, "app3", tags.DDService) + }) +} diff --git a/pkg/util/winutil/iisconfig.go b/pkg/util/winutil/iisconfig/iisconfig.go similarity index 91% rename from pkg/util/winutil/iisconfig.go rename to pkg/util/winutil/iisconfig/iisconfig.go index be6eb091baded..61af8bb534645 100644 --- a/pkg/util/winutil/iisconfig.go +++ b/pkg/util/winutil/iisconfig/iisconfig.go @@ -4,7 +4,7 @@ // Copyright 2016-present Datadog, Inc. //go:build windows -package winutil +package iisconfig import ( "encoding/xml" @@ -34,6 +34,7 @@ type DynamicIISConfig struct { stopChannel chan bool xmlcfg *iisConfiguration siteIDToName map[uint32]string + pathTrees map[uint32]*pathTreeEntry } // NewDynamicIISConfig creates a new DynamicIISConfig @@ -114,18 +115,20 @@ type iisApplication struct { VirtualDirs []iisVirtualDirectory `xml:"virtualDirectory"` } type iisSite struct { - Name string `xml:"name,attr"` - SiteID string `xml:"id,attr"` - Application iisApplication - Bindings []iisBinding `xml:"bindings>binding"` + Name string `xml:"name,attr"` + SiteID string `xml:"id,attr"` + Applications []iisApplication `xml:"application"` + Bindings []iisBinding `xml:"bindings>binding"` } type iisSystemApplicationHost struct { XMLName xml.Name `xml:"system.applicationHost"` Sites []iisSite `xml:"sites>site"` } + type iisConfiguration struct { XMLName xml.Name `xml:"configuration"` ApplicationHost iisSystemApplicationHost + AppSettings iisAppSettings } func (iiscfg *DynamicIISConfig) readXMLConfig() error { @@ -147,10 +150,13 @@ func (iiscfg *DynamicIISConfig) readXMLConfig() error { } idmap[uint32(id)] = site.Name } + + pt := buildPathTagTree(&newcfg) iiscfg.mux.Lock() defer iiscfg.mux.Unlock() iiscfg.xmlcfg = &newcfg iiscfg.siteIDToName = idmap + iiscfg.pathTrees = pt return nil } diff --git a/pkg/util/winutil/iisconfig_test.go b/pkg/util/winutil/iisconfig/iisconfig_test.go similarity index 58% rename from pkg/util/winutil/iisconfig_test.go rename to pkg/util/winutil/iisconfig/iisconfig_test.go index 9ae9c5127fdbe..1757e9b7e9e88 100644 --- a/pkg/util/winutil/iisconfig_test.go +++ b/pkg/util/winutil/iisconfig/iisconfig_test.go @@ -4,7 +4,7 @@ // Copyright 2016-present Datadog, Inc. //go:build windows -package winutil +package iisconfig import ( "os" @@ -35,3 +35,25 @@ func TestConfigLoading(t *testing.T) { assert.Equal(t, name, "TestSite") iisCfg.Stop() } + +func TestUninitializedConfig(t *testing.T) { + path, err := os.Getwd() + require.Nil(t, err) + + iisCfgPath = filepath.Join(path, "testdata", "iisconfig.xml") + iisCfg, err := NewDynamicIISConfig() + + // by not calling start, this will simulate either a caller trying to use w/o calling + // start, or a race where the start is still "in progress" when the caller tries to use it + + assert.Nil(t, err) + assert.NotNil(t, iisCfg) + + name := iisCfg.GetSiteNameFromID(0) + assert.Equal(t, name, "") + + atags, cfgtags := iisCfg.GetAPMTags(0, "/") + assert.Equal(t, atags.DDService, "") + assert.Equal(t, cfgtags.DDService, "") + +} diff --git a/pkg/util/winutil/iisconfig/tagtree.go b/pkg/util/winutil/iisconfig/tagtree.go new file mode 100644 index 0000000000000..79d77557a16d9 --- /dev/null +++ b/pkg/util/winutil/iisconfig/tagtree.go @@ -0,0 +1,184 @@ +// 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. +//go:build windows + +package iisconfig + +import ( + "os" + "path/filepath" + "strconv" + + "golang.org/x/sys/windows/registry" +) + +/* + IIS can have multiple sites. Each site can have multiple applications. + each application can have its own config. + + Such as + + + + + + + + + + + + + in the above, there each application should be treated separately. + + so if theURL is /app2/app3/appx, then we look in d:\source + /app2/app4/appx, then we look in d:\tmp + /app3 then we look in app1 + + pathTreeEntry implements a search tree to simplify the search for matching paths. +*/ +type pathTreeEntry struct { + nodes map[string]*pathTreeEntry + ddjson APMTags + appconfig APMTags +} + +func splitPaths(path string) []string { + path = filepath.Clean(path) + if path == "/" || path == "\\" { + return make([]string, 0) + } + a, b := filepath.Split(path) + s := splitPaths(a) + return append(s, b) +} + +func findInPathTree(pathTrees map[uint32]*pathTreeEntry, siteID uint32, urlpath string) (APMTags, APMTags) { + // urlpath will come in as something like + // /path/to/app + + // break down the path + pathparts := splitPaths(urlpath) + + if _, ok := pathTrees[siteID]; !ok { + return APMTags{}, APMTags{} + } + if len(pathparts) == 0 { + return pathTrees[siteID].ddjson, pathTrees[siteID].appconfig + } + + currNode := pathTrees[siteID] + + for _, part := range pathparts { + if _, ok := currNode.nodes[part]; !ok { + return currNode.ddjson, currNode.appconfig + } + currNode = currNode.nodes[part] + } + return currNode.ddjson, currNode.appconfig +} + +func addToPathTree(pathTrees map[uint32]*pathTreeEntry, siteID string, urlpath string, ddjson, appconfig APMTags) { + + intid, err := strconv.Atoi(siteID) + if err != nil { + return + } + id := uint32(intid) + // urlpath will come in as something like + // /path/to/app + // need to build the tree all the way down + + // break down the path + pathparts := splitPaths(urlpath) + + if _, ok := pathTrees[id]; !ok { + pathTrees[id] = &pathTreeEntry{ + nodes: make(map[string]*pathTreeEntry), + } + } + if len(pathparts) == 0 { + pathTrees[id].ddjson = ddjson + pathTrees[id].appconfig = appconfig + return + } + + currNode := pathTrees[id] + + for _, part := range pathparts { + if _, ok := currNode.nodes[part]; !ok { + currNode.nodes[part] = &pathTreeEntry{ + nodes: make(map[string]*pathTreeEntry), + } + } + currNode = currNode.nodes[part] + } + currNode.ddjson = ddjson + currNode.appconfig = appconfig +} + +// GetAPMTags returns the APM tags for the given siteID and URL path +func (iiscfg *DynamicIISConfig) GetAPMTags(siteID uint32, urlpath string) (APMTags, APMTags) { + iiscfg.mux.Lock() + defer iiscfg.mux.Unlock() + return findInPathTree(iiscfg.pathTrees, siteID, urlpath) +} + +func buildPathTagTree(xmlcfg *iisConfiguration) map[uint32]*pathTreeEntry { + pathTrees := make(map[uint32]*pathTreeEntry) + + for _, site := range xmlcfg.ApplicationHost.Sites { + for _, app := range site.Applications { + for _, vdir := range app.VirtualDirs { + if vdir.Path != "/" { + // assume that non `/` virtual paths mean that + // it's a virtual directory and not an application + // the application root will always be at / + continue + } + + // check to see if the datadog.json or web.config exists + ppath := vdir.PhysicalPath + ppath, err := registry.ExpandString(ppath) + if err != nil { + ppath = vdir.PhysicalPath + } + + ddjsonpath := filepath.Join(ppath, "datadog.json") + webcfg := filepath.Join(ppath, "web.config") + hasddjson := false + haswebcfg := false + var ddjson APMTags + var appconfig APMTags + + if _, err := os.Stat(ddjsonpath); err == nil { + hasddjson = true + } + if _, err := os.Stat(webcfg); err == nil { + haswebcfg = true + } + + if hasddjson { + ddjson, err = ReadDatadogJSON(ddjsonpath) + if err != nil { + hasddjson = false + } + } + if haswebcfg { + appconfig, err = ReadDotNetConfig(webcfg) + if err != nil { + haswebcfg = false + } + } + if !hasddjson && !haswebcfg { + continue + } + + addToPathTree(pathTrees, site.SiteID, app.Path, ddjson, appconfig) + } + } + } + return pathTrees +} diff --git a/pkg/util/winutil/iisconfig/testdata/app1/datadog.json b/pkg/util/winutil/iisconfig/testdata/app1/datadog.json new file mode 100644 index 0000000000000..deb9f3e52db63 --- /dev/null +++ b/pkg/util/winutil/iisconfig/testdata/app1/datadog.json @@ -0,0 +1,5 @@ +{ + "DD_SERVICE": "app1", + "DD_ENV": "staging", + "DD_VERSION": "1.0-prerelease" + } \ No newline at end of file diff --git a/pkg/util/winutil/iisconfig/testdata/app2/datadog.json b/pkg/util/winutil/iisconfig/testdata/app2/datadog.json new file mode 100644 index 0000000000000..e1a8718f32fec --- /dev/null +++ b/pkg/util/winutil/iisconfig/testdata/app2/datadog.json @@ -0,0 +1,5 @@ +{ + "DD_SERVICE": "app2", + "DD_ENV": "staging", + "DD_VERSION": "1.0-prerelease" + } \ No newline at end of file diff --git a/pkg/util/winutil/iisconfig/testdata/app3/datadog.json b/pkg/util/winutil/iisconfig/testdata/app3/datadog.json new file mode 100644 index 0000000000000..ee2153f9835f3 --- /dev/null +++ b/pkg/util/winutil/iisconfig/testdata/app3/datadog.json @@ -0,0 +1,5 @@ +{ + "DD_SERVICE": "app3", + "DD_ENV": "staging", + "DD_VERSION": "1.0-prerelease" + } \ No newline at end of file diff --git a/pkg/util/winutil/iisconfig/testdata/app4/datadog.json b/pkg/util/winutil/iisconfig/testdata/app4/datadog.json new file mode 100644 index 0000000000000..5dd98fd3f7fea --- /dev/null +++ b/pkg/util/winutil/iisconfig/testdata/app4/datadog.json @@ -0,0 +1,5 @@ +{ + "DD_SERVICE": "app4", + "DD_ENV": "staging", + "DD_VERSION": "1.0-prerelease" + } \ No newline at end of file diff --git a/pkg/util/winutil/iisconfig/testdata/app_1.config.xml b/pkg/util/winutil/iisconfig/testdata/app_1.config.xml new file mode 100644 index 0000000000000..4bab99ded3c6c --- /dev/null +++ b/pkg/util/winutil/iisconfig/testdata/app_1.config.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/pkg/util/winutil/iisconfig/testdata/apptest.xml b/pkg/util/winutil/iisconfig/testdata/apptest.xml new file mode 100644 index 0000000000000..29a90bfb0b8a8 --- /dev/null +++ b/pkg/util/winutil/iisconfig/testdata/apptest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pkg/util/winutil/testdata/iisconfig.xml b/pkg/util/winutil/iisconfig/testdata/iisconfig.xml similarity index 99% rename from pkg/util/winutil/testdata/iisconfig.xml rename to pkg/util/winutil/iisconfig/testdata/iisconfig.xml index 7e0dda430c94b..a059929881090 100644 --- a/pkg/util/winutil/testdata/iisconfig.xml +++ b/pkg/util/winutil/iisconfig/testdata/iisconfig.xml @@ -11,7 +11,11 @@ --> - + + + + +