diff --git a/.github/workflows/create_rc_pr.yml b/.github/workflows/create_rc_pr.yml index 4522ddd4100a2..2a685c3cc85df 100644 --- a/.github/workflows/create_rc_pr.yml +++ b/.github/workflows/create_rc_pr.yml @@ -5,10 +5,12 @@ on: schedule: - 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 + - cron: '0 9 * * 1' # Run Agent 6 workflow on Monday at 09:00 UTC env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - + AGENT6_RELEASE_BRANCH: '6.53.x' + IS_AGENT6_RELEASE: ${{ github.event.schedule == '0 9 * * 1' }} permissions: {} jobs: @@ -19,18 +21,21 @@ jobs: warning: ${{ steps.warning.outputs.value }} steps: - name: Checkout repository + if: ${{ env.IS_AGENT6_RELEASE == 'false' }} uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: sparse-checkout: 'tasks' persist-credentials: false - name: Install python + if: ${{ env.IS_AGENT6_RELEASE == 'false' }} uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: 3.11 cache: "pip" - name: Install Python dependencies + if: ${{ env.IS_AGENT6_RELEASE == 'false' }} run: | python -m pip install --upgrade pip pip install -r requirements.txt @@ -40,7 +45,11 @@ jobs: - name: Determine the release active branches id: branches run: | - echo "value=$(inv release.get-unreleased-release-branches)" >> $GITHUB_OUTPUT + if ${{ env.IS_AGENT6_RELEASE == 'true' }}; then + echo "value=[\"$AGENT6_RELEASE_BRANCH\"]" >> $GITHUB_OUTPUT + else + echo "value=$(inv release.get-unreleased-release-branches)" >> $GITHUB_OUTPUT + fi - name: Set the warning option id: warning @@ -93,11 +102,12 @@ jobs: fi - name: Create RC PR - if: ${{ steps.check_for_changes.outputs.CHANGES == 'true'}} + if: ${{ steps.check_for_changes.outputs.CHANGES == 'true' || env.IS_AGENT6_RELEASE == 'true' }} env: MATRIX: ${{ matrix.value }} run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git fetch - inv -e release.create-rc -r "$MATRIX" --slack-webhook=${{ secrets.AGENT_RELEASE_SYNC_SLACK_WEBHOOK }} + if ${{ env.IS_AGENT6_RELEASE == 'true' }}; then + inv -e release.create-rc -r "$MATRIX" --slack-webhook=${{ secrets.AGENT_RELEASE_SYNC_SLACK_WEBHOOK }} --patch-version + else + inv -e release.create-rc -r "$MATRIX" --slack-webhook=${{ secrets.AGENT_RELEASE_SYNC_SLACK_WEBHOOK }} + fi diff --git a/.github/workflows/cws-btfhub-sync.yml b/.github/workflows/cws-btfhub-sync.yml index b5f1ba4df7b0c..795953b22a354 100644 --- a/.github/workflows/cws-btfhub-sync.yml +++ b/.github/workflows/cws-btfhub-sync.yml @@ -97,7 +97,7 @@ jobs: inv -e security-agent.generate-btfhub-constants --archive-path=./dev/dist/archive --output-path=./"$ARTIFACT_NAME".json --force-refresh - name: Upload artifact - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: ${{ steps.artifact-name.outputs.ARTIFACT_NAME }} path: ./${{ steps.artifact-name.outputs.ARTIFACT_NAME }}.json diff --git a/.github/workflows/docs-dev.yml b/.github/workflows/docs-dev.yml index 8602adc372c1f..1eab6460db4b6 100644 --- a/.github/workflows/docs-dev.yml +++ b/.github/workflows/docs-dev.yml @@ -50,7 +50,7 @@ jobs: - name: Build documentation run: invoke docs.build - - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: documentation path: site diff --git a/.github/workflows/serverless-benchmarks.yml b/.github/workflows/serverless-benchmarks.yml index 195f3441c4591..8ad83b34d36d1 100644 --- a/.github/workflows/serverless-benchmarks.yml +++ b/.github/workflows/serverless-benchmarks.yml @@ -48,7 +48,7 @@ jobs: ./pkg/serverless/... | tee "$TEMP_RUNNER"/benchmark.log - name: Upload result artifact - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: baseline.log path: ${{runner.temp}}/benchmark.log @@ -87,7 +87,7 @@ jobs: ./pkg/serverless/... | tee "$TEMP_RUNNER"/benchmark.log - name: Upload result artifact - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: current.log path: ${{runner.temp}}/benchmark.log diff --git a/.github/workflows/serverless-binary-size.yml b/.github/workflows/serverless-binary-size.yml index 5bf7a69b36177..7be692d81d51a 100644 --- a/.github/workflows/serverless-binary-size.yml +++ b/.github/workflows/serverless-binary-size.yml @@ -152,7 +152,7 @@ jobs: done - name: Archive dependency graphs - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 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 f94ed5ca56b52..ace5e88fbda98 100644 --- a/.github/workflows/serverless-integration.yml +++ b/.github/workflows/serverless-integration.yml @@ -80,7 +80,7 @@ jobs: - name: Archive raw logs if: always() - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: rawlogs-${{ matrix.suite }}-${{ matrix.architecture }} path: ${{ steps.rawlogs.outputs.dir }} diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 05351cee64faf..b2761698a9b16 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -584,8 +584,10 @@ workflow: when: always .on_deploy_stable_or_beta_repo_branch: + - !reference [.except_mergequeue] - <<: *if_not_stable_or_beta_repo_branch - when: never + when: manual + allow_failure: true - <<: *if_deploy .on_deploy_stable_or_beta_repo_branch_manual: @@ -614,7 +616,8 @@ workflow: .except_no_tests_no_deploy: - if: $DEPLOY_AGENT == "false" && $DDR_WORKFLOW_ID == null && $RUN_E2E_TESTS == "off" - when: never + when: manual + allow_failure: true .on_main_or_release_branch: - <<: *if_main_branch diff --git a/.gitlab/choco_build/choco_build.yml b/.gitlab/choco_build/choco_build.yml index 97ef76cd478f0..8ec5bac814d18 100644 --- a/.gitlab/choco_build/choco_build.yml +++ b/.gitlab/choco_build/choco_build.yml @@ -14,8 +14,13 @@ windows_choco_offline_7_x64: script: - $ErrorActionPreference = "Stop" - Get-ChildItem omnibus\pkg - - copy omnibus\pkg\*.msi .\chocolatey\tools-offline\ - - docker run --rm -v "$(Get-Location):c:\mnt" registry.ddbuild.io/ci/datadog-agent-buildimages/windows_1809_${ARCH}${Env:DATADOG_AGENT_WINBUILDIMAGES_SUFFIX}:${Env:DATADOG_AGENT_WINBUILDIMAGES} c:\mnt\tasks\winbuildscripts\chocopack.bat offline + - copy omnibus\pkg\*.msi .\chocolatey\datadog-agent\offline\tools\ + - > + docker run --rm + -v "$(Get-Location):c:\mnt" + -e AWS_NETWORKING=true + registry.ddbuild.io/ci/datadog-agent-buildimages/windows_1809_${ARCH}${Env:DATADOG_AGENT_WINBUILDIMAGES_SUFFIX}:${Env:DATADOG_AGENT_WINBUILDIMAGES} + powershell.exe -C "C:\mnt\tasks\winbuildscripts\Generate-Chocolatey-Package.ps1 -InstallMethod offline -Flavor $FLAVOR -InstallDeps 1" - If ($lastExitCode -ne "0") { throw "Previous command returned $lastExitCode" } - copy build-out\*.nupkg omnibus\pkg artifacts: @@ -24,12 +29,11 @@ windows_choco_offline_7_x64: - omnibus/pkg # The online version of the choco job gets the msi package through the gitlab artifacts -windows_choco_online_7_x64: +.windows_choco_online_7_x64: rules: !reference [.on_deploy_stable_or_beta_repo_branch] stage: choco_and_install_script_build tags: ["runner:windows-docker", "windowsversion:1809"] - needs: ["deploy_packages_windows-x64-7"] variables: ARCH: "x64" script: @@ -43,10 +47,12 @@ windows_choco_online_7_x64: - > docker run --rm -v "$(Get-Location):c:\mnt" + -e CI_PROJECT_NAME=${CI_PROJECT_NAME} -e CI_PIPELINE_ID=${CI_PIPELINE_ID} -e BUCKET_BRANCH="$BUCKET_BRANCH" + -e AWS_NETWORKING=true registry.ddbuild.io/ci/datadog-agent-buildimages/windows_1809_${ARCH}${Env:DATADOG_AGENT_WINBUILDIMAGES_SUFFIX}:${Env:DATADOG_AGENT_WINBUILDIMAGES} - c:\mnt\tasks\winbuildscripts\chocopack.bat online c:\mnt\temp + powershell.exe -C "C:\mnt\tasks\winbuildscripts\Generate-Chocolatey-Package.ps1 -InstallMethod online -MSIDirectory c:\mnt\temp -Flavor $FLAVOR -InstallDeps 1" - If ($lastExitCode -ne "0") { throw "Previous command returned $lastExitCode" } - Remove-Item -Path "temp\" -Recurse -Force - copy build-out\*.nupkg omnibus\pkg @@ -58,3 +64,23 @@ windows_choco_online_7_x64: - omnibus/pkg # Sometimes Chocolatey is flakey retry: 2 + +windows_choco_online_7_x64: + extends: .windows_choco_online_7_x64 + # On dev/PR branches: + # - if the job is run manually it will create a package, but before the + # package can be installed, the deploy_windows_testing-a7 job must + # be run to push the MSI to the dd-agent-mstesting bucket. + needs: ["windows_msi_and_bosh_zip_x64-a7"] + variables: + FLAVOR: "datadog-agent" + +windows_choco_online_7_x64-fips: + extends: .windows_choco_online_7_x64 + # On dev/PR branches: + # - if the job is run manually it will create a package, but before the + # package can be installed, the deploy_windows_testing-a7-fips job must + # be run to push the MSI to the dd-agent-mstesting bucket. + needs: ["windows_msi_and_bosh_zip_x64-a7-fips"] + variables: + FLAVOR: "datadog-fips-agent" diff --git a/.gitlab/common/test_infra_version.yml b/.gitlab/common/test_infra_version.yml index 7d435a4bc3a4b..71934be35d15a 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: 9c7c5005ca28 + TEST_INFRA_DEFINITIONS_BUILDIMAGES: 4b4112f5f64d diff --git a/.gitlab/deploy_packages/e2e.yml b/.gitlab/deploy_packages/e2e.yml index a72844e37c245..78bb3286f1292 100644 --- a/.gitlab/deploy_packages/e2e.yml +++ b/.gitlab/deploy_packages/e2e.yml @@ -1,31 +1,5 @@ # Jobs that deploy agent packages on QA environment, to be used by e2e tests -qa_agent_oci: - extends: .docker_publish_job_definition - stage: deploy_packages - rules: - - !reference [.on_installer_or_e2e_changes] - - !reference [.manual] - needs: - - deploy_agent_oci - variables: - IMG_REGISTRIES: agent-qa - IMG_SOURCES: registry.ddbuild.io/ci/remote-updates/datadog-agent:pipeline-${CI_PIPELINE_ID} - IMG_DESTINATIONS: agent-package:pipeline-${CI_PIPELINE_ID} - -qa_installer_oci: - extends: .docker_publish_job_definition - stage: deploy_packages - rules: - - !reference [.on_installer_or_e2e_changes] - - !reference [.manual] - needs: - - deploy_installer_oci - variables: - IMG_REGISTRIES: agent-qa - IMG_SOURCES: registry.ddbuild.io/ci/remote-updates/datadog-installer:pipeline-${CI_PIPELINE_ID} - IMG_DESTINATIONS: installer-package:pipeline-${CI_PIPELINE_ID} - qa_installer_script: image: registry.ddbuild.io/ci/datadog-agent-buildimages/gitlab_agent_deploy$DATADOG_AGENT_BUILDIMAGES_SUFFIX:$DATADOG_AGENT_BUILDIMAGES stage: deploy_packages diff --git a/.gitlab/deploy_packages/oci.yml b/.gitlab/deploy_packages/oci.yml index 7db0433b743dd..bcefacac8d134 100644 --- a/.gitlab/deploy_packages/oci.yml +++ b/.gitlab/deploy_packages/oci.yml @@ -24,9 +24,10 @@ include: - datadog-package push registry.ddbuild.io/ci/remote-updates/${OCI_PRODUCT}:${VERSION} ${OMNIBUS_PACKAGE_DIR}/${OCI_PRODUCT}-${VERSION}.oci.tar # This is used for E2E tests. Doesn't cost more than an additional tag to the registry. - datadog-package push registry.ddbuild.io/ci/remote-updates/${OCI_PRODUCT}:pipeline-${CI_PIPELINE_ID} ${OMNIBUS_PACKAGE_DIR}/${OCI_PRODUCT}-${VERSION}.oci.tar - # Used for install scripts e2e tests + # Used for e2e tests - datadog-package replicate-s3 registry.ddbuild.io/ci/remote-updates/${OCI_PRODUCT}:pipeline-${CI_PIPELINE_ID} us-east-1 ${INSTALLER_TESTING_S3_BUCKET} ${S3_PACKAGE} ${VERSION} - datadog-package replicate-s3 registry.ddbuild.io/ci/remote-updates/${OCI_PRODUCT}:pipeline-${CI_PIPELINE_ID} us-east-1 ${INSTALLER_TESTING_S3_BUCKET} ${S3_PACKAGE} ${CI_COMMIT_SHA} + - datadog-package replicate-s3 registry.ddbuild.io/ci/remote-updates/${OCI_PRODUCT}:pipeline-${CI_PIPELINE_ID} us-east-1 ${INSTALLER_TESTING_S3_BUCKET} ${S3_PACKAGE} pipeline-${CI_PIPELINE_ID} variables: MAJOR_VERSION: 7 diff --git a/.gitlab/e2e/e2e.yml b/.gitlab/e2e/e2e.yml index b23939329f011..f944f407fa2dd 100644 --- a/.gitlab/e2e/e2e.yml +++ b/.gitlab/e2e/e2e.yml @@ -412,8 +412,8 @@ new-e2e-installer: - deploy_rpm_testing-a7_x64 - deploy_suse_rpm_testing_arm64-a7 - deploy_suse_rpm_testing_x64-a7 - - qa_installer_oci - - qa_agent_oci + - deploy_installer_oci + - deploy_agent_oci variables: TARGETS: ./tests/installer/unix TEAM: fleet @@ -428,8 +428,8 @@ new-e2e-installer-windows: needs: - !reference [.needs_new_e2e_template] - deploy_windows_testing-a7 - - qa_installer_oci - - qa_agent_oci + - deploy_installer_oci + - deploy_agent_oci before_script: # CURRENT_AGENT_VERSION is used to verify the installed agent version # Must run before new_e2e_template changes the aws profile @@ -471,8 +471,8 @@ new-e2e-installer-ansible: - deploy_rpm_testing-a7_x64 - deploy_suse_rpm_testing_arm64-a7 - deploy_suse_rpm_testing_x64-a7 - - qa_installer_oci - - qa_agent_oci + - deploy_installer_oci + - deploy_agent_oci variables: TARGETS: ./tests/installer/unix TEAM: fleet @@ -663,8 +663,8 @@ generate-flakes-finder-pipeline: - deploy_suse_rpm_testing_arm64-a7 - deploy_suse_rpm_testing_x64-a7 - deploy_windows_testing-a7 - - qa_installer_oci - - qa_agent_oci + - deploy_installer_oci + - deploy_agent_oci - qa_cws_instrumentation - qa_dca - qa_dogstatsd diff --git a/.gitlab/notify/notify.yml b/.gitlab/notify/notify.yml index f40187465a50f..13131a7fecb4a 100644 --- a/.gitlab/notify/notify.yml +++ b/.gitlab/notify/notify.yml @@ -80,8 +80,8 @@ notify_github: script: - !reference [.setup_agent_github_app] # Python 3.12 changes default behavior how packages are installed. - # In particular, --break-system-packages command line option is - # required to use the old behavior or use a virtual env. https://github.com/actions/runner-images/issues/8615 + # In particular, --break-system-packages command line option is + # required to use the old behavior or use a virtual env. https://github.com/actions/runner-images/issues/8615 - python3 -m pip install -r tasks/libs/requirements-github.txt --break-system-packages - messagefile="$(mktemp)" - echo "Use this command from [test-infra-definitions](https://github.com/DataDog/test-infra-definitions) to manually test this PR changes on a VM:" >> "$messagefile" @@ -98,6 +98,7 @@ notify_gitlab_ci_changes: needs: [compute_gitlab_ci_config] tags: ["arch:amd64"] rules: + - !reference [.except_mergequeue] - changes: paths: - .gitlab-ci.yml @@ -105,8 +106,8 @@ notify_gitlab_ci_changes: compare_to: main # TODO: use a variable, when this is supported https://gitlab.com/gitlab-org/gitlab/-/issues/369916 script: # Python 3.12 changes default behavior how packages are installed. - # In particular, --break-system-packages command line option is - # required to use the old behavior or use a virtual env. https://github.com/actions/runner-images/issues/8615 + # In particular, --break-system-packages command line option is + # required to use the old behavior or use a virtual env. https://github.com/actions/runner-images/issues/8615 - python3 -m pip install -r tasks/libs/requirements-github.txt --break-system-packages - !reference [.setup_agent_github_app] - inv -e notify.gitlab-ci-diff --from-diff artifacts/diff.gitlab-ci.yml --pr-comment diff --git a/.gitlab/package_build/windows.yml b/.gitlab/package_build/windows.yml index ea458c9db77a7..88c93ac82c01c 100644 --- a/.gitlab/package_build/windows.yml +++ b/.gitlab/package_build/windows.yml @@ -36,7 +36,6 @@ -e BUNDLE_MIRROR__RUBYGEMS__ORG=${BUNDLE_MIRROR__RUBYGEMS__ORG} -e PIP_INDEX_URL=${PIP_INDEX_URL} -e API_KEY_ORG2=${API_KEY_ORG2} - -e OMNIBUS_GIT_CACHE_DIR=${Env:TEMP}/${CI_PIPELINE_ID}/omnibus-git-cache -e AGENT_FLAVOR=${AGENT_FLAVOR} registry.ddbuild.io/ci/datadog-agent-buildimages/windows_1809_${ARCH}${Env:DATADOG_AGENT_WINBUILDIMAGES_SUFFIX}:${Env:DATADOG_AGENT_WINBUILDIMAGES} powershell -C "c:\mnt\tasks\winbuildscripts\Build-AgentPackages.ps1 -BuildOutOfSource 1 -InstallDeps 1 -CheckGoVersion 1" diff --git a/CHANGELOG-DCA.rst b/CHANGELOG-DCA.rst index 5ed8fdc3430f3..569bda03c6a0d 100644 --- a/CHANGELOG-DCA.rst +++ b/CHANGELOG-DCA.rst @@ -2,6 +2,33 @@ Release Notes ============= +.. _Release Notes_7.60.0: + +7.60.0 +====== + +.. _Release Notes_7.60.0_Prelude: + +Prelude +------- + +Released on: 2024-12-16 +Pinned to datadog-agent v7.60.0: `CHANGELOG `_. + + +.. _Release Notes_7.60.0_Bug Fixes: + +Bug Fixes +--------- + +- Fixes bug where incorrect timestamp would be used for unbundled Kubernetes events. + +- Fixed an issue in the KSM check when it's configured with the option + ``pod_collection_mode`` set to ``node_kubelet``. Previously, the check could + fail to start if there was a timeout while contacting the API server. This + issue has now been resolved. + + .. _Release Notes_7.59.1: 7.59.1 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9dcb70ac5e1e1..ba9f97c930ee8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,138 @@ Release Notes ============= +.. _Release Notes_7.60.0: + +7.60.0 +====== + +.. _Release Notes_7.60.0_Prelude: + +Prelude +------- + +Release on: 2024-12-16 + +- Please refer to the `7.60.0 tag on integrations-core `_ for the list of changes on the Core Checks + + +.. _Release Notes_7.60.0_Upgrade Notes: + +Upgrade Notes +------------- + +- * Parameter ``peer_tags_aggregation`` (a.k.a. environment variable ``DD_APM_PEER_TAGS_AGGREGATION``) is now enabled by default. This means that aggregation of peer related tags (e.g., `peer.service`, `db.instance`, etc.) now happens in the Agent, which enables statistics for Inferred Entities. If you want to disable this feature, set `peer_tags_aggregation` to `false` in your Agent configuration. + + * Parameter ``compute_stats_by_span_kind`` (a.k.a. environment variable ``DD_APM_COMPUTE_STATS_BY_SPAN_KIND``) is now enabled by default. This means spans with an eligible `span.kind` will have stats computed. If disabled, only top-level and measured spans will have stats computed. If you want to disable this feature, set `compute_stats_by_span_kind` to `false` in your Agent configuration. + + Note: When using ``peer_tags_aggregation`` and ``compute_stats_by_span_kind``, a high cardinality of peer tags or APM resources can contribute to higher CPU and memory consumption. If enabling both causes the Agent to consume too many resources, try disabling `compute_stats_by_span_kind` first. + + It is recommended that you update your tracing libraries according to the instructions `here `_ and set ``DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED`` (or ``dd.trace.remove.integration-service-names.enabled``) to ``true``. + +- Upgraded JMXFetch to `0.49.5 `_ which adds support for ``UnloadedClassCount`` metric + and IBM J9 gc metrics. See `0.49.5 `_ for more details. + + +.. _Release Notes_7.60.0_New Features: + +New Features +------------ + +- `Inferred Service dependencies `_ are now Generally Available (exiting Beta) and enabled by default. Inferred Services of all kinds now have trace metrics and are available in dependency maps. `apm_config.peer_tags_aggregation` and `apm_config.compute_stats_by_span_kind` both now default to `true` unless explicitly set to `false`. + +- Add `check_tag_cardinality` parameter config check. + + By default `check_tag_cardinality` is not set which doesn't change the behavior of the checks. + Once it is set in pod annotaions, it overrides the cardinality value provided in the base agent configuration. + Example of usage: + ```yaml + ad.datadoghq.com/redis.checks: | + { + "redisdb": { + "check_tag_cardinality": "high", + "instances": [ + { + "host": "%%host%%", + "port": "6379" + } + ] + } + } + ``` + +- Added a new feature flag `enable_receive_resource_spans_v2` in DD_APM_FEATURES that gates a refactored implementation of ReceiveResourceSpans for OTLP. + + +.. _Release Notes_7.60.0_Enhancement Notes: + +Enhancement Notes +----------------- + +- Added information about where the Agent sourced BTF data for eBPF to the Agent flare. When applicable, this will appear in ``system-probe/ebpf_btf_loader.log``. + +- The Agent flare now returns NAT debug information from conntrack in the ``system-probe`` directory. + +- The ``flare`` subcommand includes a ``--provider-timeout`` option to set a timeout for each file collection (default is 10s), useful for unblocking slow flare creation. + +- This change reduces the number of DNS queries made by Network Traffic + based paths in Network Path. + A cache of reverse DNS lookups is used to reduce the number of DNS + queries. Additionally, reverse DNS lookups are now performed only + for private IPs and not for public IPs. + +- Agent flare now includes system-probe telemetry data via ``system-probe/system_probe_telemetry.log``. + +- The MSI installer uses 7zr.exe to decompress the embedded Python. + +- On Windows, the endpoint /windows_crash_detection/check has been modified to report crashes in + an asynchronous manner, to allow processing of large crash dumps without blocking or timing out. + The first check will return a busy status and continue to do so until the processing is completed. + + +.. _Release Notes_7.60.0_Deprecation Notes: + +Deprecation Notes +----------------- + +- Prebuilt eBPF for the network tracer system-probe module has been + deprecated in favor of CO-RE and runtime compilation variants on Linux + kernel versions 6+ and RHEL kernel versions 5.14+. To continue to use + the prebuilt eBPF network tracer, set + `system_probe_config.allow_prebuilt_fallback` in the + system-probe config file, or set the environment variable + `DD_ALLOW_PREBUILT_FALLBACK`, to `true` on these platforms. + +- The feature flag `service_monitoring_config.enable_http_stats_by_status_code` was deprecated and removed. + No impact on USM's behavior. + + +.. _Release Notes_7.60.0_Bug Fixes: + +Bug Fixes +--------- + +- Fixes an issue added in 7.50 that causes the Windows event log tailer to drop + events if it cannot open their publisher metadata. + +- Fix a bug in the config parser that broke ignored_ip_addresses from working in NDM Autodiscovery. + +- Fixes host tags with a configurable duration so the metric's context hash doesn't change, preventing the aggregator from mistaking it as a new metric. + +- Fix `could not parse voltage fields` error in Nvidia Jetson integration when tegrastats output contains mW units. + +- Fix building of Python extension containing native code. + +- [oracle] Fix broken activity sampling with an external Oracle client. + +- Fix nil pointer error on Oracle DBM query when the check's connection is lost before SELECT statement executes. + +- Fix a regression that caused the Agent to not be able to run if its + capabilities had been modified with the `setcap` command. + +- Fix bug wherein single line truncated logs ended with whitespace characters were not being tagged as truncated. + Fix issue with the truncation message occasionally causing subsequent logs to think they were truncated when they were not (single line logs only). + + .. _Release Notes_7.59.1: 7.59.1 diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 8c766a337eb1c..92e5c072e3c8e 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -596,12 +596,6 @@ core,github.com/aws/aws-sdk-go-v2/service/ebs/types,Apache-2.0,"Copyright 2014-2 core,github.com/aws/aws-sdk-go-v2/service/ec2,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." core,github.com/aws/aws-sdk-go-v2/service/ec2/internal/endpoints,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." core,github.com/aws/aws-sdk-go-v2/service/ec2/types,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." -core,github.com/aws/aws-sdk-go-v2/service/ecr,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." -core,github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." -core,github.com/aws/aws-sdk-go-v2/service/ecr/types,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." -core,github.com/aws/aws-sdk-go-v2/service/ecrpublic,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." -core,github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." -core,github.com/aws/aws-sdk-go-v2/service/ecrpublic/types,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." core,github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." core,github.com/aws/aws-sdk-go-v2/service/internal/presigned-url,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." core,github.com/aws/aws-sdk-go-v2/service/kms,Apache-2.0,"Copyright 2014-2015 Stripe, Inc. | Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved." @@ -692,11 +686,6 @@ core,github.com/aws/smithy-go/tracing,Apache-2.0,"Copyright Amazon.com, Inc. or core,github.com/aws/smithy-go/transport/http,Apache-2.0,"Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved" core,github.com/aws/smithy-go/transport/http/internal/io,Apache-2.0,"Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved" core,github.com/aws/smithy-go/waiter,Apache-2.0,"Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved" -core,github.com/awslabs/amazon-ecr-credential-helper/ecr-login,Apache-2.0,"Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved." -core,github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api,Apache-2.0,"Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved." -core,github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cache,Apache-2.0,"Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved." -core,github.com/awslabs/amazon-ecr-credential-helper/ecr-login/config,Apache-2.0,"Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved." -core,github.com/awslabs/amazon-ecr-credential-helper/ecr-login/version,Apache-2.0,"Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved." core,github.com/bahlo/generic-list-go,BSD-3-Clause,Copyright (c) 2009 The Go Authors. All rights reserved core,github.com/beevik/ntp,BSD-2-Clause,Al Cutter (AlCutter) | Andrey Smirnov (smira) | Anton Tolchanov (knyar) | Ask Bjørn Hansen (abh) | Brett Vickers (beevik) | Christopher Batey (chbatey) | Copyright © 2015-2023 Brett Vickers. All rights reserved | Leonid Evdokimov (darkk) | Meng Zhuo (mengzhuo) | Mikhail Salosin (AlphaB) | Silves-Xiang (silves-xiang) core,github.com/benbjohnson/clock,MIT,Copyright (c) 2014 Ben Johnson @@ -1220,8 +1209,6 @@ core,github.com/google/gopacket/afpacket,BSD-3-Clause,"Copyright (c) 2009-2011 A core,github.com/google/gopacket/layers,BSD-3-Clause,"Copyright (c) 2009-2011 Andreas Krennmair. All rights reserved. | Copyright (c) 2012 Google, Inc. All rights reserved." core,github.com/google/gopacket/pcap,BSD-3-Clause,"Copyright (c) 2009-2011 Andreas Krennmair. All rights reserved. | Copyright (c) 2012 Google, Inc. All rights reserved." core,github.com/google/gopacket/pcapgo,BSD-3-Clause,"Copyright (c) 2009-2011 Andreas Krennmair. All rights reserved. | Copyright (c) 2012 Google, Inc. All rights reserved." -core,github.com/google/licenseclassifier/v2,Apache-2.0,Copyright 2017 Google LLC All Rights Reserved. | Copyright 2020 Google LLC All Rights Reserved. -core,github.com/google/licenseclassifier/v2/assets,Apache-2.0,Copyright 2017 Google LLC All Rights Reserved. | Copyright 2020 Google LLC All Rights Reserved. core,github.com/google/pprof/profile,Apache-2.0,Andrew Hunter | Google Inc. | Hyoun Kyu Cho | Martin Spier | Raul Silvera | Taco de Wolff | Tipp Moseley core,github.com/google/s2a-go,Apache-2.0,Copyright (c) 2020 Google core,github.com/google/s2a-go/fallback,Apache-2.0,Copyright (c) 2020 Google @@ -2054,15 +2041,6 @@ core,github.com/secure-systems-lab/go-securesystemslib/dsse,MIT,Copyright (c) 20 core,github.com/secure-systems-lab/go-securesystemslib/signerverifier,MIT,Copyright (c) 2021 NYU Secure Systems Lab core,github.com/sergi/go-diff/diffmatchpatch,MIT,Copyright (c) 2012-2016 The go-diff Authors. All rights reserved | Danny Yoo | James Kolb | Jonathan Amsterdam | Markus Zimmermann | Matt Kovars | Osman Masood | Robert Carlsen | Rory Flynn | Sergi Mansilla | Shatrugna Sadhu | Shawn Smith | Stas Maksimov | Tor Arvid Lund | Zac Bergquist | Örjan Persson core,github.com/shibumi/go-pathspec,Apache-2.0,Copyright (c) 2012 The Go Authors. All rights reserved. -core,github.com/shirou/gopsutil/v3/common,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" -core,github.com/shirou/gopsutil/v3/cpu,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" -core,github.com/shirou/gopsutil/v3/disk,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" -core,github.com/shirou/gopsutil/v3/host,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" -core,github.com/shirou/gopsutil/v3/internal/common,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" -core,github.com/shirou/gopsutil/v3/load,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" -core,github.com/shirou/gopsutil/v3/mem,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" -core,github.com/shirou/gopsutil/v3/net,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" -core,github.com/shirou/gopsutil/v3/process,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" core,github.com/shirou/gopsutil/v4/common,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" core,github.com/shirou/gopsutil/v4/cpu,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" core,github.com/shirou/gopsutil/v4/disk,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" @@ -2073,7 +2051,6 @@ core,github.com/shirou/gopsutil/v4/mem,BSD-3-Clause,"Copyright (c) 2009 The Go A core,github.com/shirou/gopsutil/v4/net,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" core,github.com/shirou/gopsutil/v4/process,BSD-3-Clause,"Copyright (c) 2009 The Go Authors. All rights reserved | Copyright (c) 2014, WAKAYAMA Shirou" core,github.com/shirou/w32,BSD-3-Clause,Copyright (c) 2010-2012 The w32 Authors. All rights reserved. -core,github.com/shoenig/go-m1cpu,MPL-2.0,"copyright doctrines of fair use, fair dealing, or other" core,github.com/shopspring/decimal,MIT,"Copyright (c) 2013 Oguz Bilgic | Copyright (c) 2015 Spring, Inc" core,github.com/signalfx/sapm-proto/client,Apache-2.0,"Copyright 2019 Splunk, Inc." core,github.com/signalfx/sapm-proto/gen,Apache-2.0,"Copyright 2019 Splunk, Inc." diff --git a/chocolatey/datadog-agent-offline.nuspec b/chocolatey/datadog-agent/offline/datadog-agent-offline.nuspec similarity index 97% rename from chocolatey/datadog-agent-offline.nuspec rename to chocolatey/datadog-agent/offline/datadog-agent-offline.nuspec index d049625a0ef3b..aedf9555a1c51 100644 --- a/chocolatey/datadog-agent-offline.nuspec +++ b/chocolatey/datadog-agent/offline/datadog-agent-offline.nuspec @@ -26,6 +26,6 @@ For example, to set the API key you may run: $release_notes$ - + diff --git a/chocolatey/tools-offline/VERIFICATION.txt b/chocolatey/datadog-agent/offline/tools/VERIFICATION.txt similarity index 100% rename from chocolatey/tools-offline/VERIFICATION.txt rename to chocolatey/datadog-agent/offline/tools/VERIFICATION.txt diff --git a/chocolatey/tools-offline/chocolateyinstall.ps1 b/chocolatey/datadog-agent/offline/tools/chocolateyinstall.ps1 similarity index 100% rename from chocolatey/tools-offline/chocolateyinstall.ps1 rename to chocolatey/datadog-agent/offline/tools/chocolateyinstall.ps1 diff --git a/chocolatey/datadog-agent-online.nuspec b/chocolatey/datadog-agent/online/datadog-agent-online.nuspec similarity index 97% rename from chocolatey/datadog-agent-online.nuspec rename to chocolatey/datadog-agent/online/datadog-agent-online.nuspec index d3cf3133a1a98..73f96bfb83871 100644 --- a/chocolatey/datadog-agent-online.nuspec +++ b/chocolatey/datadog-agent/online/datadog-agent-online.nuspec @@ -26,6 +26,6 @@ For example, to set the API key you may run: $release_notes$ - + diff --git a/chocolatey/tools-online/VERIFICATION.txt b/chocolatey/datadog-agent/online/tools/VERIFICATION.txt similarity index 100% rename from chocolatey/tools-online/VERIFICATION.txt rename to chocolatey/datadog-agent/online/tools/VERIFICATION.txt diff --git a/chocolatey/tools-online/chocolateyinstall.ps1 b/chocolatey/datadog-agent/online/tools/chocolateyinstall.ps1 similarity index 100% rename from chocolatey/tools-online/chocolateyinstall.ps1 rename to chocolatey/datadog-agent/online/tools/chocolateyinstall.ps1 diff --git a/chocolatey/datadog-fips-agent/online/datadog-fips-agent-online.nuspec b/chocolatey/datadog-fips-agent/online/datadog-fips-agent-online.nuspec new file mode 100644 index 0000000000000..90b6de924c628 --- /dev/null +++ b/chocolatey/datadog-fips-agent/online/datadog-fips-agent-online.nuspec @@ -0,0 +1,31 @@ + + + + datadog-fips-agent + $version$ + https://github.com/DataDog/datadog-agent/tree/main/chocolatey + Datadog + Datadog FIPS Agent + Datadog + https://github.com/DataDog/datadog-agent + https://datadog-prod.imgix.net/img/dd_logo_70x75.png + $copyright$ + https://raw.githubusercontent.com/DataDog/datadog-agent/main/LICENSE + true + https://docs.datadoghq.com + datadog agent monitoring admin + The Datadog FIPS Agent for Microsoft Windows + The Datadog FIPS Agent faithfully collects events and metrics and brings them to Datadog on your behalf so that you can do something useful with your monitoring and performance data. + +## Package settings + +You may set [custom settings](https://docs.datadoghq.com/agent/basic_agent_usage/windows/?tab=commandline#installation) to the Agent when installing by using the [`--installer-arguments` option of `choco install`](https://chocolatey.org/docs/getting-started#overriding-default-install-directory-or-other-advanced-install-concepts). + +For example, to set the API key you may run: +`choco install -ia="APIKEY=""YOUR_DATADOG_API_KEY""" datadog-fips-agent` + $release_notes$ + + + + + diff --git a/chocolatey/datadog-fips-agent/online/tools/VERIFICATION.txt b/chocolatey/datadog-fips-agent/online/tools/VERIFICATION.txt new file mode 100644 index 0000000000000..b13ab096f9a76 --- /dev/null +++ b/chocolatey/datadog-fips-agent/online/tools/VERIFICATION.txt @@ -0,0 +1,5 @@ +VERIFICATION +Verification is intended to assist the Chocolatey moderators and community in verifying that this package's contents are trustworthy. + +This package is published by Datadog itself. +The binaries are identical to other package types for the Datadog FIPS Agent. diff --git a/chocolatey/datadog-fips-agent/online/tools/chocolateyinstall.ps1 b/chocolatey/datadog-fips-agent/online/tools/chocolateyinstall.ps1 new file mode 100644 index 0000000000000..d928fdf7bff78 --- /dev/null +++ b/chocolatey/datadog-fips-agent/online/tools/chocolateyinstall.ps1 @@ -0,0 +1,27 @@ +$ErrorActionPreference = 'Stop'; + +$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)" +$packageArgs = @{ + packageName = $env:ChocolateyPackageName + unzipLocation = $toolsDir + fileType = 'msi' + # Note: Url is replaced at build time with the full URL to the MSI + url64bit = $__url_from_ci__ + checksum64 = $__checksum_from_ci__ + checksumType = 'sha256' + softwareName = "Datadog FIPS Agent" + silentArgs = "/qn /norestart /l*v `"$($env:TEMP)\$($packageName).$($env:chocolateyPackageVersion).MsiInstall.log`"" + validExitCodes= @(0, 3010, 1641) +} +Install-ChocolateyPackage @packageArgs + +$installInfo = @" +--- +install_method: + tool: chocolatey + tool_version: chocolatey-$($env:CHOCOLATEY_VERSION) + installer_version: chocolatey_package-online +"@ + +$appDataDir = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Datadog\Datadog Agent").ConfigRoot +Out-File -FilePath $appDataDir\install_info -InputObject $installInfo diff --git a/cmd/agent/subcommands/flare/command.go b/cmd/agent/subcommands/flare/command.go index 1b4fb2d3bc1e3..a6da5391ae5d5 100644 --- a/cmd/agent/subcommands/flare/command.go +++ b/cmd/agent/subcommands/flare/command.go @@ -175,10 +175,18 @@ func readProfileData(seconds int) (flare.ProfileData, error) { type pprofGetter func(path string) ([]byte, error) - tcpGet := func(portConfig string) pprofGetter { - pprofURL := fmt.Sprintf("http://127.0.0.1:%d/debug/pprof", pkgconfigsetup.Datadog().GetInt(portConfig)) + tcpGet := func(portConfig string, onHTTPS bool) pprofGetter { + endpoint := url.URL{ + Scheme: "http", + Host: net.JoinHostPort("127.0.0.1", strconv.Itoa(pkgconfigsetup.Datadog().GetInt(portConfig))), + Path: "/debug/pprof", + } + if onHTTPS { + endpoint.Scheme = "https" + } + return func(path string) ([]byte, error) { - return util.DoGet(c, pprofURL+path, util.LeaveConnectionOpen) + return util.DoGet(c, endpoint.String()+path, util.LeaveConnectionOpen) } } @@ -228,15 +236,15 @@ func readProfileData(seconds int) (flare.ProfileData, error) { } agentCollectors := map[string]agentProfileCollector{ - "core": serviceProfileCollector(tcpGet("expvar_port"), seconds), - "security-agent": serviceProfileCollector(tcpGet("security_agent.expvar_port"), seconds), + "core": serviceProfileCollector(tcpGet("expvar_port", false), seconds), + "security-agent": serviceProfileCollector(tcpGet("security_agent.expvar_port", false), seconds), } if pkgconfigsetup.Datadog().GetBool("process_config.enabled") || pkgconfigsetup.Datadog().GetBool("process_config.container_collection.enabled") || pkgconfigsetup.Datadog().GetBool("process_config.process_collection.enabled") { - agentCollectors["process"] = serviceProfileCollector(tcpGet("process_config.expvar_port"), seconds) + agentCollectors["process"] = serviceProfileCollector(tcpGet("process_config.expvar_port", false), seconds) } if pkgconfigsetup.Datadog().GetBool("apm_config.enabled") { @@ -249,7 +257,7 @@ func readProfileData(seconds int) (flare.ProfileData, error) { traceCpusec = 4 } - agentCollectors["trace"] = serviceProfileCollector(tcpGet("apm_config.debug.port"), traceCpusec) + agentCollectors["trace"] = serviceProfileCollector(tcpGet("apm_config.debug.port", true), traceCpusec) } if pkgconfigsetup.SystemProbe().GetBool("system_probe_config.enabled") { diff --git a/cmd/agent/subcommands/flare/command_test.go b/cmd/agent/subcommands/flare/command_test.go index a27304e95b133..4c96cae079aa9 100644 --- a/cmd/agent/subcommands/flare/command_test.go +++ b/cmd/agent/subcommands/flare/command_test.go @@ -29,6 +29,7 @@ type commandTestSuite struct { suite.Suite sysprobeSocketPath string tcpServer *httptest.Server + tcpTLSServer *httptest.Server unixServer *httptest.Server systemProbeServer *httptest.Server } @@ -42,13 +43,17 @@ func (c *commandTestSuite) SetupSuite() { // This should be called by each test that requires them. func (c *commandTestSuite) startTestServers() { t := c.T() - c.tcpServer, c.unixServer, c.systemProbeServer = c.getPprofTestServer() + c.tcpServer, c.tcpTLSServer, c.unixServer, c.systemProbeServer = c.getPprofTestServer() t.Cleanup(func() { if c.tcpServer != nil { c.tcpServer.Close() c.tcpServer = nil } + if c.tcpTLSServer != nil { + c.tcpTLSServer.Close() + c.tcpTLSServer = nil + } if c.unixServer != nil { c.unixServer.Close() c.unixServer = nil @@ -82,12 +87,13 @@ func newMockHandler() http.HandlerFunc { }) } -func (c *commandTestSuite) getPprofTestServer() (tcpServer *httptest.Server, unixServer *httptest.Server, sysProbeServer *httptest.Server) { +func (c *commandTestSuite) getPprofTestServer() (tcpServer *httptest.Server, tcpTLSServer *httptest.Server, unixServer *httptest.Server, sysProbeServer *httptest.Server) { var err error t := c.T() handler := newMockHandler() tcpServer = httptest.NewServer(handler) + tcpTLSServer = httptest.NewTLSServer(handler) if runtime.GOOS == "linux" { unixServer = httptest.NewUnstartedServer(handler) unixServer.Listener, err = net.Listen("unix", c.sysprobeSocketPath) @@ -101,7 +107,7 @@ func (c *commandTestSuite) getPprofTestServer() (tcpServer *httptest.Server, uni sysProbeServer.Start() } - return tcpServer, unixServer, sysProbeServer + return tcpServer, tcpTLSServer, unixServer, sysProbeServer } func TestCommandTestSuite(t *testing.T) { @@ -116,10 +122,14 @@ func (c *commandTestSuite) TestReadProfileData() { require.NoError(t, err) port := u.Port() + u, err = url.Parse(c.tcpTLSServer.URL) + require.NoError(t, err) + httpsPort := u.Port() + mockConfig := configmock.New(t) mockConfig.SetWithoutSource("expvar_port", port) mockConfig.SetWithoutSource("apm_config.enabled", true) - mockConfig.SetWithoutSource("apm_config.debug.port", port) + mockConfig.SetWithoutSource("apm_config.debug.port", httpsPort) mockConfig.SetWithoutSource("apm_config.receiver_timeout", "10") mockConfig.SetWithoutSource("process_config.expvar_port", port) mockConfig.SetWithoutSource("security_agent.expvar_port", port) diff --git a/cmd/agent/subcommands/run/command.go b/cmd/agent/subcommands/run/command.go index 9c126f014aab2..76775693251e4 100644 --- a/cmd/agent/subcommands/run/command.go +++ b/cmd/agent/subcommands/run/command.go @@ -146,8 +146,8 @@ import ( jmxStatus "github.com/DataDog/datadog-agent/pkg/status/jmx" systemprobeStatus "github.com/DataDog/datadog-agent/pkg/status/systemprobe" pkgTelemetry "github.com/DataDog/datadog-agent/pkg/telemetry" - "github.com/DataDog/datadog-agent/pkg/util" pkgcommon "github.com/DataDog/datadog-agent/pkg/util/common" + "github.com/DataDog/datadog-agent/pkg/util/coredump" "github.com/DataDog/datadog-agent/pkg/util/defaultpaths" "github.com/DataDog/datadog-agent/pkg/util/flavor" "github.com/DataDog/datadog-agent/pkg/util/fxutil" @@ -512,7 +512,7 @@ func startAgent( log.Infof("Starting Datadog Agent v%v", version.AgentVersion) } - if err := util.SetupCoreDump(pkgconfigsetup.Datadog()); err != nil { + if err := coredump.Setup(pkgconfigsetup.Datadog()); err != nil { log.Warnf("Can't setup core dumps: %v, core dumps might not be available after a crash", err) } diff --git a/cmd/agent/subcommands/secret/command.go b/cmd/agent/subcommands/secret/command.go index e24f95ca6d693..d8b2a7048114f 100644 --- a/cmd/agent/subcommands/secret/command.go +++ b/cmd/agent/subcommands/secret/command.go @@ -101,7 +101,7 @@ func traceAgentSecretRefresh(conf config.Component) ([]byte, error) { c := apiutil.GetClient(false) c.Timeout = conf.GetDuration("server_timeout") * time.Second - url := fmt.Sprintf("http://127.0.0.1:%d/secret/refresh", port) + url := fmt.Sprintf("https://127.0.0.1:%d/secret/refresh", port) res, err := apiutil.DoGet(c, url, apiutil.CloseConnection) if err != nil { return nil, fmt.Errorf("could not contact trace-agent: %s", err) diff --git a/cmd/cluster-agent/api/server.go b/cmd/cluster-agent/api/server.go index 37efad4d900dd..c4f5c0534633a 100644 --- a/cmd/cluster-agent/api/server.go +++ b/cmd/cluster-agent/api/server.go @@ -12,6 +12,7 @@ package api import ( "context" + "crypto/subtle" "crypto/tls" "crypto/x509" "encoding/pem" @@ -116,7 +117,7 @@ func StartServer(ctx context.Context, w workloadmeta.Component, taggerComp tagge logWriter, _ := pkglogsetup.NewTLSHandshakeErrorWriter(4, log.WarnLvl) authInterceptor := grpcutil.AuthInterceptor(func(token string) (interface{}, error) { - if token != util.GetDCAAuthToken() { + if subtle.ConstantTimeCompare([]byte(token), []byte(util.GetDCAAuthToken())) == 0 { return struct{}{}, errors.New("Invalid session token") } diff --git a/cmd/cluster-agent/subcommands/start/command.go b/cmd/cluster-agent/subcommands/start/command.go index f43ae03615401..aea5e4207f57c 100644 --- a/cmd/cluster-agent/subcommands/start/command.go +++ b/cmd/cluster-agent/subcommands/start/command.go @@ -81,7 +81,7 @@ import ( hostnameStatus "github.com/DataDog/datadog-agent/pkg/status/clusteragent/hostname" endpointsStatus "github.com/DataDog/datadog-agent/pkg/status/endpoints" "github.com/DataDog/datadog-agent/pkg/status/health" - "github.com/DataDog/datadog-agent/pkg/util" + "github.com/DataDog/datadog-agent/pkg/util/coredump" "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/DataDog/datadog-agent/pkg/util/hostname" "github.com/DataDog/datadog-agent/pkg/util/kubernetes/apiserver" @@ -241,7 +241,7 @@ func start(log log.Component, // Starting Cluster Agent sequence // Initialization order is important for multiple reasons, see comments - if err := util.SetupCoreDump(config); err != nil { + if err := coredump.Setup(config); err != nil { pkglog.Warnf("Can't setup core dumps: %v, core dumps might not be available after a crash", err) } diff --git a/cmd/dogstatsd/subcommands/start/command.go b/cmd/dogstatsd/subcommands/start/command.go index f61ae13db837d..b6e6a63361ae8 100644 --- a/cmd/dogstatsd/subcommands/start/command.go +++ b/cmd/dogstatsd/subcommands/start/command.go @@ -57,7 +57,7 @@ import ( compressionfx "github.com/DataDog/datadog-agent/comp/serializer/compression/fx" "github.com/DataDog/datadog-agent/pkg/serializer" "github.com/DataDog/datadog-agent/pkg/status/health" - "github.com/DataDog/datadog-agent/pkg/util" + "github.com/DataDog/datadog-agent/pkg/util/coredump" "github.com/DataDog/datadog-agent/pkg/util/fxutil" pkglog "github.com/DataDog/datadog-agent/pkg/util/log" pkglogsetup "github.com/DataDog/datadog-agent/pkg/util/log/setup" @@ -235,7 +235,7 @@ func RunDogstatsd(_ context.Context, cliParams *CLIParams, config config.Compone } }() - if err := util.SetupCoreDump(config); err != nil { + if err := coredump.Setup(config); err != nil { log.Warnf("Can't setup core dumps: %v, core dumps might not be available after a crash", err) } diff --git a/cmd/installer/subcommands/daemon/status.tmpl b/cmd/installer/subcommands/daemon/status.tmpl index 045b819d53764..02481dea5c50d 100644 --- a/cmd/installer/subcommands/daemon/status.tmpl +++ b/cmd/installer/subcommands/daemon/status.tmpl @@ -1,12 +1,12 @@ Datadog Installer v{{ htmlSafe .Version }} {{ range $name, $package := .Packages }} {{ boldText $name }} - State: {{ if $package.Experiment -}}{{ yellowText "Upgrading" }}{{- else if $package.Stable -}}{{ greenText "OK" }}{{- else -}}{{ redText "no stable version" }}{{- end }} + State: {{ if $package.Experiment -}}{{ yellowText "Upgrading" }}{{- else if $package.Stable -}}{{ greenText "OK" }}{{- else -}}config only{{- end }} Installed versions: {{- if $package.Stable }} {{ greenText "●" }} stable: v{{ htmlSafe $package.Stable }} {{- else }} - {{ redText "●" }} stable: none + ● stable: none {{- end }} {{- if $package.Experiment }} {{ yellowText "●" }} experiment: v{{ htmlSafe $package.Experiment }} @@ -23,9 +23,9 @@ Datadog Installer v{{ htmlSafe .Version }} Remote configuration client state: StableVersion: {{ $remoteConfig.StableVersion }} ExperimentVersion: {{ $remoteConfig.ExperimentVersion }} - StableConfigVersion: {{ $remoteConfig.StableConfigVersion }} - ExperimentConfigVersion: {{ $remoteConfig.ExperimentConfigVersion }} - RemoteConfigVersion: {{ $remoteConfig.RemoteConfigVersion }} + StableConfigVersion: {{ if $remoteConfig.StableConfigState }}{{ $remoteConfig.StableConfigState.Version }}{{ else }}{{ "" }}{{ end }} + ExperimentConfigVersion: {{ if $remoteConfig.ExperimentConfigState }}{{ $remoteConfig.ExperimentConfigState.Version }}{{ else }}{{ "" }}{{ end }} + RemoteConfigVersion: {{ if $remoteConfig.RemoteConfigState }}{{ $remoteConfig.RemoteConfigState.Version }}{{ else }}{{ "" }}{{ end }} Task: {{- if $remoteConfig.Task }} Id: {{ $remoteConfig.Task.Id }} diff --git a/cmd/otel-agent/config/agent_config_test.go b/cmd/otel-agent/config/agent_config_test.go index 2d08cfb4ac58f..01567d48d7ffe 100644 --- a/cmd/otel-agent/config/agent_config_test.go +++ b/cmd/otel-agent/config/agent_config_test.go @@ -78,7 +78,7 @@ func (suite *ConfigTestSuite) TestAgentConfigDefaults() { assert.Equal(t, 6, c.Get("logs_config.compression_level")) assert.Equal(t, "https://trace.agent.datadoghq.com", c.Get("apm_config.apm_dd_url")) assert.Equal(t, false, c.Get("apm_config.receiver_enabled")) - assert.Equal(t, true, c.Get("otlp_config.traces.span_name_as_resource_name")) + assert.Equal(t, false, c.Get("otlp_config.traces.span_name_as_resource_name")) assert.Equal(t, []string{"enable_receive_resource_spans_v2", "enable_operation_and_resource_name_logic_v2", "enable_otlp_compute_top_level_by_span_kind"}, c.Get("apm_config.features")) } @@ -104,7 +104,7 @@ func (suite *ConfigTestSuite) TestAgentConfigWithDatadogYamlDefaults() { assert.Equal(t, 6, c.Get("logs_config.compression_level")) assert.Equal(t, "https://trace.agent.datadoghq.com", c.Get("apm_config.apm_dd_url")) assert.Equal(t, false, c.Get("apm_config.receiver_enabled")) - assert.Equal(t, true, c.Get("otlp_config.traces.span_name_as_resource_name")) + assert.Equal(t, false, c.Get("otlp_config.traces.span_name_as_resource_name")) assert.Equal(t, []string{"enable_receive_resource_spans_v2", "enable_operation_and_resource_name_logic_v2", "enable_otlp_compute_top_level_by_span_kind"}, c.Get("apm_config.features")) // log_level from datadog.yaml takes precedence -> more verbose diff --git a/cmd/process-agent/command/main_common.go b/cmd/process-agent/command/main_common.go index 188c9684fd30b..dcb9287e74f04 100644 --- a/cmd/process-agent/command/main_common.go +++ b/cmd/process-agent/command/main_common.go @@ -61,7 +61,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/process/metadata/workloadmeta/collector" "github.com/DataDog/datadog-agent/pkg/process/util" proccontainers "github.com/DataDog/datadog-agent/pkg/process/util/containers" - ddutil "github.com/DataDog/datadog-agent/pkg/util" + "github.com/DataDog/datadog-agent/pkg/util/coredump" "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/DataDog/datadog-agent/pkg/util/fxutil/logging" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -296,7 +296,7 @@ type miscDeps struct { // Todo: (Components) WorkloadMeta, remoteTagger // Todo: move metadata/workloadmeta/collector to workloadmeta func initMisc(deps miscDeps) error { - if err := ddutil.SetupCoreDump(deps.Config); err != nil { + if err := coredump.Setup(deps.Config); err != nil { deps.Logger.Warnf("Can't setup core dumps: %v, core dumps might not be available after a crash", err) } diff --git a/cmd/process-agent/subcommands/status/status.go b/cmd/process-agent/subcommands/status/status.go index 2660ee8fb71b4..8826c7547fb61 100644 --- a/cmd/process-agent/subcommands/status/status.go +++ b/cmd/process-agent/subcommands/status/status.go @@ -28,8 +28,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/util/fxutil" ) -var httpClient = apiutil.GetClient(false) - const ( notRunning = ` ============= @@ -111,6 +109,7 @@ func writeError(log log.Component, w io.Writer, e error) { } func fetchStatus(statusURL string) ([]byte, error) { + httpClient := apiutil.GetClient(false) body, err := apiutil.DoGet(httpClient, statusURL, apiutil.LeaveConnectionOpen) if err != nil { return nil, status.NewConnectionError(err) diff --git a/cmd/security-agent/api/server.go b/cmd/security-agent/api/server.go index e776628e5ccd4..307a4e4c6cd43 100644 --- a/cmd/security-agent/api/server.go +++ b/cmd/security-agent/api/server.go @@ -12,9 +12,6 @@ package api import ( "crypto/tls" - "crypto/x509" - "encoding/pem" - "fmt" stdLog "log" "net" "net/http" @@ -23,10 +20,10 @@ import ( "github.com/gorilla/mux" "github.com/DataDog/datadog-agent/cmd/security-agent/api/agent" + "github.com/DataDog/datadog-agent/comp/api/authtoken" "github.com/DataDog/datadog-agent/comp/core/settings" "github.com/DataDog/datadog-agent/comp/core/status" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" - "github.com/DataDog/datadog-agent/pkg/api/security" "github.com/DataDog/datadog-agent/pkg/api/util" pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -35,19 +32,21 @@ import ( // Server implements security agent API server type Server struct { - listener net.Listener - agent *agent.Agent + listener net.Listener + agent *agent.Agent + tlsConfig *tls.Config } // NewServer creates a new Server instance -func NewServer(statusComponent status.Component, settings settings.Component, wmeta workloadmeta.Component) (*Server, error) { +func NewServer(statusComponent status.Component, settings settings.Component, wmeta workloadmeta.Component, at authtoken.Component) (*Server, error) { listener, err := newListener() if err != nil { return nil, err } return &Server{ - listener: listener, - agent: agent.NewAgent(statusComponent, settings, wmeta), + listener: listener, + agent: agent.NewAgent(statusComponent, settings, wmeta), + tlsConfig: at.GetTLSServerConfig(), }, nil } @@ -62,43 +61,16 @@ func (s *Server) Start() error { // Validate token for every request r.Use(validateToken) - err := util.CreateAndSetAuthToken(pkgconfigsetup.Datadog()) - if err != nil { - return err - } - - hosts := []string{"127.0.0.1", "localhost"} - _, rootCertPEM, rootKey, err := security.GenerateRootCert(hosts, 2048) - if err != nil { - return fmt.Errorf("unable to start TLS server") - } - - // PEM encode the private key - rootKeyPEM := pem.EncodeToMemory(&pem.Block{ - Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(rootKey), - }) - - // Create a TLS cert using the private key and certificate - rootTLSCert, err := tls.X509KeyPair(rootCertPEM, rootKeyPEM) - if err != nil { - return fmt.Errorf("invalid key pair: %v", err) - } - - tlsConfig := tls.Config{ - Certificates: []tls.Certificate{rootTLSCert}, - MinVersion: tls.VersionTLS13, - } - // Use a stack depth of 4 on top of the default one to get a relevant filename in the stdlib logWriter, _ := pkglogsetup.NewLogWriter(4, log.ErrorLvl) srv := &http.Server{ Handler: r, ErrorLog: stdLog.New(logWriter, "Error from the agent http API server: ", 0), // log errors to seelog, - TLSConfig: &tlsConfig, + TLSConfig: s.tlsConfig, WriteTimeout: pkgconfigsetup.Datadog().GetDuration("server_timeout") * time.Second, } - tlsListener := tls.NewListener(s.listener, &tlsConfig) + tlsListener := tls.NewListener(s.listener, s.tlsConfig) go srv.Serve(tlsListener) //nolint:errcheck return nil diff --git a/cmd/security-agent/main_windows.go b/cmd/security-agent/main_windows.go index b81223e6aebc1..a729e7a2003f0 100644 --- a/cmd/security-agent/main_windows.go +++ b/cmd/security-agent/main_windows.go @@ -25,6 +25,7 @@ import ( "github.com/DataDog/datadog-agent/cmd/security-agent/subcommands/start" "github.com/DataDog/datadog-agent/comp/agent/autoexit" "github.com/DataDog/datadog-agent/comp/agent/autoexit/autoexitimpl" + "github.com/DataDog/datadog-agent/comp/api/authtoken" "github.com/DataDog/datadog-agent/comp/api/authtoken/fetchonlyimpl" "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/core/config" @@ -91,10 +92,11 @@ func (s *service) Run(svcctx context.Context) error { params := &cliParams{} err := fxutil.OneShot( func(log log.Component, config config.Component, _ secrets.Component, _ statsd.Component, _ sysprobeconfig.Component, - telemetry telemetry.Component, _ workloadmeta.Component, _ *cliParams, statusComponent status.Component, _ autoexit.Component, settings settings.Component, wmeta workloadmeta.Component) error { + telemetry telemetry.Component, _ workloadmeta.Component, _ *cliParams, statusComponent status.Component, _ autoexit.Component, + settings settings.Component, wmeta workloadmeta.Component, at authtoken.Component) error { defer start.StopAgent(log) - err := start.RunAgent(log, config, telemetry, statusComponent, settings, wmeta) + err := start.RunAgent(log, config, telemetry, statusComponent, settings, wmeta, at) if err != nil { if errors.Is(err, start.ErrAllComponentsDisabled) { // If all components are disabled, we should exit cleanly diff --git a/cmd/security-agent/subcommands/runtime/activity_dump.go b/cmd/security-agent/subcommands/runtime/activity_dump.go index 514cdda1bc612..0f15351d72e02 100644 --- a/cmd/security-agent/subcommands/runtime/activity_dump.go +++ b/cmd/security-agent/subcommands/runtime/activity_dump.go @@ -12,6 +12,7 @@ import ( "encoding/json" "fmt" "os" + "time" "github.com/spf13/cobra" "go.uber.org/fx" @@ -37,6 +38,7 @@ type activityDumpCliParams struct { name string containerID string + cgroupID string file string file2 string timeout string @@ -113,7 +115,13 @@ func stopCommands(globalParams *command.GlobalParams) []*cobra.Command { &cliParams.containerID, "container-id", "", - "an containerID can be used to filter the activity dump.", + "a containerID can be used to filter the activity dump.", + ) + activityDumpStopCmd.Flags().StringVar( + &cliParams.cgroupID, + "cgroup-id", + "", + "a cgroup ID can be used to filter the activity dump.", ) return []*cobra.Command{activityDumpStopCmd} @@ -157,10 +165,16 @@ func generateDumpCommands(globalParams *command.GlobalParams) []*cobra.Command { "", "a container identifier can be used to filter the activity dump from a specific container.", ) + activityDumpGenerateDumpCmd.Flags().StringVar( + &cliParams.cgroupID, + "cgroup-id", + "", + "a cgroup identifier can be used to filter the activity dump from a specific cgroup.", + ) activityDumpGenerateDumpCmd.Flags().StringVar( &cliParams.timeout, "timeout", - "1m", + "", "timeout for the activity dump", ) activityDumpGenerateDumpCmd.Flags().BoolVar( @@ -172,7 +186,7 @@ func generateDumpCommands(globalParams *command.GlobalParams) []*cobra.Command { activityDumpGenerateDumpCmd.Flags().StringVar( &cliParams.localStorageDirectory, "output", - "/tmp/activity_dumps/", + "", "local storage output directory", ) activityDumpGenerateDumpCmd.Flags().BoolVar( @@ -459,8 +473,15 @@ func generateActivityDump(_ log.Component, _ config.Component, _ secrets.Compone return err } + if activityDumpArgs.timeout != "" { + if _, err = time.ParseDuration(activityDumpArgs.timeout); err != nil { + return err + } + } + output, err := client.GenerateActivityDump(&api.ActivityDumpParams{ ContainerID: activityDumpArgs.containerID, + CGroupID: activityDumpArgs.cgroupID, Timeout: activityDumpArgs.timeout, DifferentiateArgs: activityDumpArgs.differentiateArgs, Storage: storage, @@ -609,7 +630,7 @@ func stopActivityDump(_ log.Component, _ config.Component, _ secrets.Component, } defer client.Close() - output, err := client.StopActivityDump(activityDumpArgs.name, activityDumpArgs.containerID) + output, err := client.StopActivityDump(activityDumpArgs.name, activityDumpArgs.containerID, activityDumpArgs.cgroupID) if err != nil { return fmt.Errorf("unable to send request to system-probe: %w", err) } diff --git a/cmd/security-agent/subcommands/runtime/command_linux.go b/cmd/security-agent/subcommands/runtime/command_linux.go index 4c5a90d3167cd..a813dc82b0385 100644 --- a/cmd/security-agent/subcommands/runtime/command_linux.go +++ b/cmd/security-agent/subcommands/runtime/command_linux.go @@ -46,6 +46,9 @@ func printSecurityActivityDumpMessage(prefix string, msg *api.ActivityDumpMessag if len(msg.GetMetadata().GetContainerID()) > 0 { fmt.Printf("%s container ID: %s\n", prefix, msg.GetMetadata().GetContainerID()) } + if len(msg.GetMetadata().GetCGroupID()) > 0 { + fmt.Printf("%s cgroup ID: %s\n", prefix, msg.GetMetadata().GetCGroupID()) + } if len(msg.GetTags()) > 0 { fmt.Printf("%s tags: %s\n", prefix, strings.Join(msg.GetTags(), ", ")) } diff --git a/cmd/security-agent/subcommands/start/command.go b/cmd/security-agent/subcommands/start/command.go index 8386100c0031b..2a3dd883dcd84 100644 --- a/cmd/security-agent/subcommands/start/command.go +++ b/cmd/security-agent/subcommands/start/command.go @@ -29,6 +29,7 @@ import ( "github.com/DataDog/datadog-agent/cmd/security-agent/subcommands/runtime" "github.com/DataDog/datadog-agent/comp/agent/autoexit" "github.com/DataDog/datadog-agent/comp/agent/autoexit/autoexitimpl" + "github.com/DataDog/datadog-agent/comp/api/authtoken" "github.com/DataDog/datadog-agent/comp/api/authtoken/fetchonlyimpl" "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/core/config" @@ -63,7 +64,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/agent" "github.com/DataDog/datadog-agent/pkg/security/utils" "github.com/DataDog/datadog-agent/pkg/status/health" - "github.com/DataDog/datadog-agent/pkg/util" + "github.com/DataDog/datadog-agent/pkg/util/coredump" "github.com/DataDog/datadog-agent/pkg/util/fxutil" "github.com/DataDog/datadog-agent/pkg/util/optional" "github.com/DataDog/datadog-agent/pkg/util/profiling" @@ -201,10 +202,10 @@ func Commands(globalParams *command.GlobalParams) []*cobra.Command { // TODO(components): note how workloadmeta is passed anonymously, it is still required as it is used // as a global. This should eventually be fixed and all workloadmeta interactions should be via the // injected instance. -func start(log log.Component, config config.Component, _ secrets.Component, _ statsd.Component, _ sysprobeconfig.Component, telemetry telemetry.Component, statusComponent status.Component, _ pid.Component, _ autoexit.Component, settings settings.Component, wmeta workloadmeta.Component) error { +func start(log log.Component, config config.Component, _ secrets.Component, _ statsd.Component, _ sysprobeconfig.Component, telemetry telemetry.Component, statusComponent status.Component, _ pid.Component, _ autoexit.Component, settings settings.Component, wmeta workloadmeta.Component, at authtoken.Component) error { defer StopAgent(log) - err := RunAgent(log, config, telemetry, statusComponent, settings, wmeta) + err := RunAgent(log, config, telemetry, statusComponent, settings, wmeta, at) if errors.Is(err, ErrAllComponentsDisabled) || errors.Is(err, errNoAPIKeyConfigured) { return nil } @@ -256,8 +257,8 @@ var ErrAllComponentsDisabled = errors.New("all security-agent component are disa var errNoAPIKeyConfigured = errors.New("no API key configured") // RunAgent initialized resources and starts API server -func RunAgent(log log.Component, config config.Component, telemetry telemetry.Component, statusComponent status.Component, settings settings.Component, wmeta workloadmeta.Component) (err error) { - if err := util.SetupCoreDump(config); err != nil { +func RunAgent(log log.Component, config config.Component, telemetry telemetry.Component, statusComponent status.Component, settings settings.Component, wmeta workloadmeta.Component, at authtoken.Component) (err error) { + if err := coredump.Setup(config); err != nil { log.Warnf("Can't setup core dumps: %v, core dumps might not be available after a crash", err) } @@ -299,7 +300,7 @@ func RunAgent(log log.Component, config config.Component, telemetry telemetry.Co } }() - srv, err = api.NewServer(statusComponent, settings, wmeta) + srv, err = api.NewServer(statusComponent, settings, wmeta, at) if err != nil { return log.Errorf("Error while creating api server, exiting: %v", err) } diff --git a/cmd/system-probe/subcommands/run/command.go b/cmd/system-probe/subcommands/run/command.go index cd35036946e88..659f7e2fe0f52 100644 --- a/cmd/system-probe/subcommands/run/command.go +++ b/cmd/system-probe/subcommands/run/command.go @@ -61,7 +61,7 @@ import ( ebpftelemetry "github.com/DataDog/datadog-agent/pkg/ebpf/telemetry" processstatsd "github.com/DataDog/datadog-agent/pkg/process/statsd" ddruntime "github.com/DataDog/datadog-agent/pkg/runtime" - "github.com/DataDog/datadog-agent/pkg/util" + "github.com/DataDog/datadog-agent/pkg/util/coredump" "github.com/DataDog/datadog-agent/pkg/util/fxutil" pkglog "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/DataDog/datadog-agent/pkg/util/optional" @@ -333,7 +333,7 @@ func startSystemProbe(log log.Component, statsd compstatsd.Component, telemetry return ErrNotEnabled } - if err := util.SetupCoreDump(sysprobeconfig); err != nil { + if err := coredump.Setup(sysprobeconfig); err != nil { log.Warnf("cannot setup core dumps: %s, core dumps might not be available after a crash", err) } diff --git a/cmd/system-probe/subcommands/runtime/activity_dump.go b/cmd/system-probe/subcommands/runtime/activity_dump.go index 72096d1160bbd..e00d027c94d7b 100644 --- a/cmd/system-probe/subcommands/runtime/activity_dump.go +++ b/cmd/system-probe/subcommands/runtime/activity_dump.go @@ -34,6 +34,7 @@ type activityDumpCliParams struct { name string containerID string + cgroupID string file string file2 string timeout string @@ -109,7 +110,12 @@ func stopCommands(globalParams *command.GlobalParams) []*cobra.Command { "", "an containerID can be used to filter the activity dump.", ) - + activityDumpStopCmd.Flags().StringVar( + &cliParams.cgroupID, + "cgroup-id", + "", + "a cgroup ID can be used to filter the activity dump.", + ) return []*cobra.Command{activityDumpStopCmd} } @@ -151,6 +157,12 @@ func generateDumpCommands(globalParams *command.GlobalParams) []*cobra.Command { "", "a container identifier can be used to filter the activity dump from a specific container.", ) + activityDumpGenerateDumpCmd.Flags().StringVar( + &cliParams.cgroupID, + "cgroup-id", + "", + "a cgroup identifier can be used to filter the activity dump from a specific cgroup.", + ) activityDumpGenerateDumpCmd.Flags().StringVar( &cliParams.timeout, "timeout", @@ -449,6 +461,7 @@ func generateActivityDump(_ log.Component, _ config.Component, _ secrets.Compone output, err := client.GenerateActivityDump(&api.ActivityDumpParams{ ContainerID: activityDumpArgs.containerID, + CGroupID: activityDumpArgs.cgroupID, Timeout: activityDumpArgs.timeout, DifferentiateArgs: activityDumpArgs.differentiateArgs, Storage: storage, @@ -573,7 +586,7 @@ func stopActivityDump(_ log.Component, _ config.Component, _ secrets.Component, } defer client.Close() - output, err := client.StopActivityDump(activityDumpArgs.name, activityDumpArgs.containerID) + output, err := client.StopActivityDump(activityDumpArgs.name, activityDumpArgs.containerID, activityDumpArgs.cgroupID) if err != nil { return fmt.Errorf("unable to send request to system-probe: %w", err) } diff --git a/cmd/system-probe/subcommands/runtime/command_linux.go b/cmd/system-probe/subcommands/runtime/command_linux.go index 51d2a8c92dec7..1980ac0fbfb23 100644 --- a/cmd/system-probe/subcommands/runtime/command_linux.go +++ b/cmd/system-probe/subcommands/runtime/command_linux.go @@ -42,6 +42,9 @@ func printSecurityActivityDumpMessage(prefix string, msg *api.ActivityDumpMessag if len(msg.GetMetadata().GetContainerID()) > 0 { fmt.Printf("%s container ID: %s\n", prefix, msg.GetMetadata().GetContainerID()) } + if len(msg.GetMetadata().GetCGroupID()) > 0 { + fmt.Printf("%s cgroup ID: %s\n", prefix, msg.GetMetadata().GetCGroupID()) + } if len(msg.GetTags()) > 0 { fmt.Printf("%s tags: %s\n", prefix, strings.Join(msg.GetTags(), ", ")) } diff --git a/comp/api/api/apiimpl/api_test.go b/comp/api/api/apiimpl/api_test.go index d92e8f1e4fa48..b248dc9531330 100644 --- a/comp/api/api/apiimpl/api_test.go +++ b/comp/api/api/apiimpl/api_test.go @@ -20,7 +20,7 @@ import ( "github.com/DataDog/datadog-agent/comp/aggregator/demultiplexer/demultiplexerimpl" "github.com/DataDog/datadog-agent/comp/api/api/apiimpl/observability" api "github.com/DataDog/datadog-agent/comp/api/api/def" - "github.com/DataDog/datadog-agent/comp/api/authtoken/fetchonlyimpl" + "github.com/DataDog/datadog-agent/comp/api/authtoken/createandfetchimpl" "github.com/DataDog/datadog-agent/comp/collector/collector" "github.com/DataDog/datadog-agent/comp/core/autodiscovery" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/autodiscoveryimpl" @@ -76,7 +76,7 @@ func getTestAPIServer(t *testing.T, params config.MockParams) testdeps { demultiplexerimpl.MockModule(), fx.Supply(optional.NewNoneOption[rcservice.Component]()), fx.Supply(optional.NewNoneOption[rcservicemrf.Component]()), - fetchonlyimpl.MockModule(), + createandfetchimpl.Module(), fx.Supply(context.Background()), taggermock.Module(), fx.Provide(func(mock taggermock.Mock) tagger.Component { @@ -166,7 +166,6 @@ func TestStartBothServersWithObservability(t *testing.T) { req, err := http.NewRequest(http.MethodGet, url, nil) require.NoError(t, err) - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", authTokenValue)) resp, err := util.GetClient(false).Do(req) require.NoError(t, err) defer resp.Body.Close() diff --git a/comp/api/api/apiimpl/grpc.go b/comp/api/api/apiimpl/grpc.go index 5f88cdb722163..6272a7f00fe05 100644 --- a/comp/api/api/apiimpl/grpc.go +++ b/comp/api/api/apiimpl/grpc.go @@ -74,6 +74,12 @@ func (s *serverSecure) TaggerStreamEntities(req *pb.StreamTagsRequest, srv pb.Ag return s.taggerServer.TaggerStreamEntities(req, srv) } +// TaggerGenerateContainerIDFromOriginInfo generates a container ID from the Origin Info. +// This function takes an Origin Info but only uses the ExternalData part of it, this is done for backward compatibility. +func (s *serverSecure) TaggerGenerateContainerIDFromOriginInfo(ctx context.Context, req *pb.GenerateContainerIDFromOriginInfoRequest) (*pb.GenerateContainerIDFromOriginInfoResponse, error) { + return s.taggerServer.TaggerGenerateContainerIDFromOriginInfo(ctx, req) +} + func (s *serverSecure) TaggerFetchEntity(ctx context.Context, req *pb.FetchEntityRequest) (*pb.FetchEntityResponse, error) { return s.taggerServer.TaggerFetchEntity(ctx, req) } diff --git a/comp/api/api/apiimpl/security.go b/comp/api/api/apiimpl/security.go index 4587871aecec3..4b8b17d2ba33d 100644 --- a/comp/api/api/apiimpl/security.go +++ b/comp/api/api/apiimpl/security.go @@ -6,16 +6,10 @@ package apiimpl import ( - "crypto/tls" - "crypto/x509" - "encoding/pem" + "crypto/subtle" "errors" - "fmt" "net/http" - "runtime" - "strings" - "github.com/DataDog/datadog-agent/pkg/api/security" "github.com/DataDog/datadog-agent/pkg/api/util" "github.com/DataDog/datadog-agent/pkg/util/log" ) @@ -34,7 +28,7 @@ func validateToken(next http.Handler) http.Handler { // parseToken parses the token and validate it for our gRPC API, it returns an empty // struct and an error or nil func parseToken(token string) (interface{}, error) { - if token != util.GetAuthToken() { + if subtle.ConstantTimeCompare([]byte(token), []byte(util.GetAuthToken())) == 0 { return struct{}{}, errors.New("Invalid session token") } @@ -43,44 +37,3 @@ func parseToken(token string) (interface{}, error) { // type. return struct{}{}, nil } - -func buildSelfSignedKeyPair(additionalHostIdentities ...string) ([]byte, []byte) { - hosts := []string{"127.0.0.1", "localhost", "::1"} - hosts = append(hosts, additionalHostIdentities...) - _, rootCertPEM, rootKey, err := security.GenerateRootCert(hosts, 2048) - if err != nil { - return nil, nil - } - - // PEM encode the private key - rootKeyPEM := pem.EncodeToMemory(&pem.Block{ - Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(rootKey), - }) - - // Create and return TLS private cert and key - return rootCertPEM, rootKeyPEM -} - -func initializeTLS(additionalHostIdentities ...string) (*tls.Certificate, *x509.CertPool, error) { - // print the caller to identify what is calling this function - if _, file, line, ok := runtime.Caller(1); ok { - log.Infof("[%s:%d] Initializing TLS certificates for hosts %v", file, line, strings.Join(additionalHostIdentities, ", ")) - } - - cert, key := buildSelfSignedKeyPair(additionalHostIdentities...) - if cert == nil { - return nil, nil, errors.New("unable to generate certificate") - } - pair, err := tls.X509KeyPair(cert, key) - if err != nil { - return nil, nil, fmt.Errorf("unable to generate TLS key pair: %v", err) - } - - tlsCertPool := x509.NewCertPool() - ok := tlsCertPool.AppendCertsFromPEM(cert) - if !ok { - return nil, nil, fmt.Errorf("unable to add new certificate to pool") - } - - return &pair, tlsCertPool, nil -} diff --git a/comp/api/api/apiimpl/server.go b/comp/api/api/apiimpl/server.go index 762a67b8a4a63..6def35781eb1a 100644 --- a/comp/api/api/apiimpl/server.go +++ b/comp/api/api/apiimpl/server.go @@ -11,6 +11,7 @@ import ( stdLog "log" "net" "net/http" + "strconv" "github.com/DataDog/datadog-agent/comp/api/api/apiimpl/observability" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -47,34 +48,11 @@ func (server *apiServer) startServers() error { return fmt.Errorf("unable to get IPC address and port: %v", err) } - additionalHostIdentities := []string{apiAddr} - - ipcServerHost, ipcServerHostPort, ipcServerEnabled := getIPCServerAddressPort() - if ipcServerEnabled { - additionalHostIdentities = append(additionalHostIdentities, ipcServerHost) - } - - tlsKeyPair, tlsCertPool, err := initializeTLS(additionalHostIdentities...) - if err != nil { - return fmt.Errorf("unable to initialize TLS: %v", err) - } - - // tls.Config is written to when serving, so it has to be cloned for each server - tlsConfig := func() *tls.Config { - return &tls.Config{ - Certificates: []tls.Certificate{*tlsKeyPair}, - NextProtos: []string{"h2"}, - MinVersion: tls.VersionTLS12, - } - } - tmf := observability.NewTelemetryMiddlewareFactory(server.telemetry) // start the CMD server if err := server.startCMDServer( apiAddr, - tlsConfig(), - tlsCertPool, tmf, server.cfg, ); err != nil { @@ -82,8 +60,11 @@ func (server *apiServer) startServers() error { } // start the IPC server - if ipcServerEnabled { - if err := server.startIPCServer(ipcServerHostPort, tlsConfig(), tmf); err != nil { + if ipcServerPort := server.cfg.GetInt("agent_ipc.port"); ipcServerPort > 0 { + ipcServerHost := server.cfg.GetString("agent_ipc.host") + ipcServerHostPort := net.JoinHostPort(ipcServerHost, strconv.Itoa(ipcServerPort)) + + if err := server.startIPCServer(ipcServerHostPort, tmf); err != nil { // if we fail to start the IPC server, we should stop the CMD server server.stopServers() return fmt.Errorf("unable to start IPC API server: %v", err) diff --git a/comp/api/api/apiimpl/server_cmd.go b/comp/api/api/apiimpl/server_cmd.go index 2b806aa8726e3..2eca0fe7abd09 100644 --- a/comp/api/api/apiimpl/server_cmd.go +++ b/comp/api/api/apiimpl/server_cmd.go @@ -7,8 +7,6 @@ package apiimpl import ( "context" - "crypto/tls" - "crypto/x509" "fmt" "net/http" "time" @@ -35,8 +33,6 @@ const cmdServerShortName string = "CMD" func (server *apiServer) startCMDServer( cmdAddr string, - tlsConfig *tls.Config, - tlsCertPool *x509.CertPool, tmf observability.TelemetryMiddlewareFactory, cfg config.Component, ) (err error) { @@ -54,7 +50,7 @@ func (server *apiServer) startCMDServer( maxMessageSize := cfg.GetInt("cluster_agent.cluster_tagger.grpc_max_message_size") opts := []grpc.ServerOption{ - grpc.Creds(credentials.NewClientTLSFromCert(tlsCertPool, cmdAddr)), + grpc.Creds(credentials.NewTLS(server.authToken.GetTLSServerConfig())), grpc.StreamInterceptor(grpc_auth.StreamServerInterceptor(authInterceptor)), grpc.UnaryInterceptor(grpc_auth.UnaryServerInterceptor(authInterceptor)), grpc.MaxRecvMsgSize(maxMessageSize), @@ -79,11 +75,7 @@ func (server *apiServer) startCMDServer( autodiscovery: server.autoConfig, }) - dcreds := credentials.NewTLS(&tls.Config{ - ServerName: cmdAddr, - RootCAs: tlsCertPool, - }) - dopts := []grpc.DialOption{grpc.WithTransportCredentials(dcreds)} + dopts := []grpc.DialOption{grpc.WithTransportCredentials(credentials.NewTLS(server.authToken.GetTLSClientConfig()))} // starting grpc gateway ctx := context.Background() @@ -133,7 +125,7 @@ func (server *apiServer) startCMDServer( srv := grpcutil.NewMuxedGRPCServer( cmdAddr, - tlsConfig, + server.authToken.GetTLSServerConfig(), s, grpcutil.TimeoutHandlerFunc(cmdMuxHandler, time.Duration(pkgconfigsetup.Datadog().GetInt64("server_timeout"))*time.Second), ) diff --git a/comp/api/api/apiimpl/server_ipc.go b/comp/api/api/apiimpl/server_ipc.go index 10e17509f75e3..634ec1810f35a 100644 --- a/comp/api/api/apiimpl/server_ipc.go +++ b/comp/api/api/apiimpl/server_ipc.go @@ -6,7 +6,6 @@ package apiimpl import ( - "crypto/tls" "net/http" "time" @@ -18,7 +17,7 @@ import ( const ipcServerName string = "IPC API Server" const ipcServerShortName string = "IPC" -func (server *apiServer) startIPCServer(ipcServerAddr string, tlsConfig *tls.Config, tmf observability.TelemetryMiddlewareFactory) (err error) { +func (server *apiServer) startIPCServer(ipcServerAddr string, tmf observability.TelemetryMiddlewareFactory) (err error) { server.ipcListener, err = getListener(ipcServerAddr) if err != nil { return err @@ -39,7 +38,7 @@ func (server *apiServer) startIPCServer(ipcServerAddr string, tlsConfig *tls.Con ipcServer := &http.Server{ Addr: ipcServerAddr, Handler: http.TimeoutHandler(ipcMuxHandler, time.Duration(pkgconfigsetup.Datadog().GetInt64("server_timeout"))*time.Second, "timeout"), - TLSConfig: tlsConfig, + TLSConfig: server.authToken.GetTLSServerConfig(), } startServer(server.ipcListener, ipcServer, ipcServerName) diff --git a/comp/api/authtoken/go.mod b/comp/api/authtoken/go.mod index ca4e617286f9e..24081f4824780 100644 --- a/comp/api/authtoken/go.mod +++ b/comp/api/authtoken/go.mod @@ -84,7 +84,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/comp/api/authtoken/go.sum b/comp/api/authtoken/go.sum index 9694f5d5e2355..dd16364891695 100644 --- a/comp/api/authtoken/go.sum +++ b/comp/api/authtoken/go.sum @@ -87,8 +87,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/core/config/go.mod b/comp/core/config/go.mod index a8fc87fffecf0..00be19b3b9ba7 100644 --- a/comp/core/config/go.mod +++ b/comp/core/config/go.mod @@ -75,7 +75,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/comp/core/config/go.sum b/comp/core/config/go.sum index 49f42d5d3e0a6..323c4fa804e83 100644 --- a/comp/core/config/go.sum +++ b/comp/core/config/go.sum @@ -88,8 +88,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/core/log/impl-trace/go.mod b/comp/core/log/impl-trace/go.mod index d78d19fde7f68..309b259ad3616 100644 --- a/comp/core/log/impl-trace/go.mod +++ b/comp/core/log/impl-trace/go.mod @@ -84,7 +84,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/comp/core/log/impl-trace/go.sum b/comp/core/log/impl-trace/go.sum index 9694f5d5e2355..dd16364891695 100644 --- a/comp/core/log/impl-trace/go.sum +++ b/comp/core/log/impl-trace/go.sum @@ -87,8 +87,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/core/log/impl/go.mod b/comp/core/log/impl/go.mod index 0d68073c13084..12d048a84bd4d 100644 --- a/comp/core/log/impl/go.mod +++ b/comp/core/log/impl/go.mod @@ -74,7 +74,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/comp/core/log/impl/go.sum b/comp/core/log/impl/go.sum index 9694f5d5e2355..dd16364891695 100644 --- a/comp/core/log/impl/go.sum +++ b/comp/core/log/impl/go.sum @@ -87,8 +87,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/core/log/mock/go.sum b/comp/core/log/mock/go.sum index 2ad11aee593c1..4b0aad4f95926 100644 --- a/comp/core/log/mock/go.sum +++ b/comp/core/log/mock/go.sum @@ -80,8 +80,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 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= diff --git a/comp/core/status/statusimpl/go.mod b/comp/core/status/statusimpl/go.mod index 9487310619057..c121259bfa141 100644 --- a/comp/core/status/statusimpl/go.mod +++ b/comp/core/status/statusimpl/go.mod @@ -88,7 +88,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/comp/core/status/statusimpl/go.sum b/comp/core/status/statusimpl/go.sum index fafe0837efa7e..73fea28e04146 100644 --- a/comp/core/status/statusimpl/go.sum +++ b/comp/core/status/statusimpl/go.sum @@ -93,8 +93,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/core/tagger/def/component.go b/comp/core/tagger/def/component.go index c580325c3bf81..619196f41de95 100644 --- a/comp/core/tagger/def/component.go +++ b/comp/core/tagger/def/component.go @@ -9,6 +9,7 @@ package tagger import ( "context" + "github.com/DataDog/datadog-agent/comp/core/tagger/origindetection" "github.com/DataDog/datadog-agent/comp/core/tagger/telemetry" "github.com/DataDog/datadog-agent/comp/core/tagger/types" taggertypes "github.com/DataDog/datadog-agent/pkg/tagger/types" @@ -37,6 +38,7 @@ type Component interface { // integrations using the tagger LegacyTag(entity string, cardinality types.TagCardinality) ([]string, error) Tag(entityID types.EntityID, cardinality types.TagCardinality) ([]string, error) + GenerateContainerIDFromOriginInfo(originInfo origindetection.OriginInfo) (string, error) AccumulateTagsFor(entityID types.EntityID, cardinality types.TagCardinality, tb tagset.TagsAccumulator) error Standard(entityID types.EntityID) ([]string, error) List() types.TaggerListResponse diff --git a/comp/core/tagger/impl-noop/tagger.go b/comp/core/tagger/impl-noop/tagger.go index 811a60e905923..986e113df2c1e 100644 --- a/comp/core/tagger/impl-noop/tagger.go +++ b/comp/core/tagger/impl-noop/tagger.go @@ -17,6 +17,7 @@ import ( "context" tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def" + "github.com/DataDog/datadog-agent/comp/core/tagger/origindetection" "github.com/DataDog/datadog-agent/comp/core/tagger/telemetry" "github.com/DataDog/datadog-agent/comp/core/tagger/types" taggertypes "github.com/DataDog/datadog-agent/pkg/tagger/types" @@ -49,6 +50,12 @@ func (n *noopTagger) LegacyTag(string, types.TagCardinality) ([]string, error) { return nil, nil } +// GenerateContainerIDFromOriginInfo generates a container ID from Origin Info. +// This is a no-op for the noop tagger +func (n *noopTagger) GenerateContainerIDFromOriginInfo(origindetection.OriginInfo) (string, error) { + return "", nil +} + func (n *noopTagger) AccumulateTagsFor(types.EntityID, types.TagCardinality, tagset.TagsAccumulator) error { return nil } diff --git a/comp/core/tagger/impl-remote/remote.go b/comp/core/tagger/impl-remote/remote.go index b1a77165f18a9..b602facbb824b 100644 --- a/comp/core/tagger/impl-remote/remote.go +++ b/comp/core/tagger/impl-remote/remote.go @@ -27,6 +27,7 @@ import ( "github.com/DataDog/datadog-agent/comp/core/config" log "github.com/DataDog/datadog-agent/comp/core/log/def" tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def" + "github.com/DataDog/datadog-agent/comp/core/tagger/origindetection" "github.com/DataDog/datadog-agent/comp/core/tagger/telemetry" "github.com/DataDog/datadog-agent/comp/core/tagger/types" "github.com/DataDog/datadog-agent/comp/core/tagger/utils" @@ -47,6 +48,8 @@ const ( var errTaggerStreamNotStarted = errors.New("tagger stream not started") +var errTaggerFailedGenerateContainerIDFromOriginInfo = errors.New("tagger failed to generate container ID from origin info") + // Requires defines the dependencies for the remote tagger. type Requires struct { compdef.In @@ -75,6 +78,7 @@ type remoteTagger struct { log log.Component conn *grpc.ClientConn + token string client pb.AgentSecureClient stream pb.AgentSecure_TaggerStreamEntitiesClient @@ -82,6 +86,9 @@ type remoteTagger struct { streamCancel context.CancelFunc filter *types.Filter + queryCtx context.Context + queryCancel context.CancelFunc + ctx context.Context cancel context.CancelFunc @@ -250,6 +257,79 @@ func (t *remoteTagger) LegacyTag(entity string, cardinality types.TagCardinality return t.Tag(entityID, cardinality) } +// GenerateContainerIDFromOriginInfo returns a container ID for the given Origin Info. +// This function currently only uses the External Data from the Origin Info to generate the container ID. +func (t *remoteTagger) GenerateContainerIDFromOriginInfo(originInfo origindetection.OriginInfo) (string, error) { + fail := true + defer func() { + if fail { + t.telemetryStore.OriginInfoRequests.Inc("failed") + } else { + t.telemetryStore.OriginInfoRequests.Inc("success") + } + }() + + expBackoff := backoff.NewExponentialBackOff() + expBackoff.InitialInterval = 500 * time.Millisecond + expBackoff.MaxInterval = 1 * time.Second + expBackoff.MaxElapsedTime = 15 * time.Second + + var containerID string + + err := backoff.Retry(func() error { + select { + case <-t.ctx.Done(): + return &backoff.PermanentError{Err: errTaggerFailedGenerateContainerIDFromOriginInfo} + default: + } + + // Fetch the auth token + if t.token == "" { + var authError error + t.token, authError = t.options.TokenFetcher() + if authError != nil { + _ = t.log.Errorf("unable to fetch auth token, will possibly retry: %s", authError) + return authError + } + } + + // Create the context with the auth token + t.queryCtx, t.queryCancel = context.WithCancel( + metadata.NewOutgoingContext(t.ctx, metadata.MD{ + "authorization": []string{fmt.Sprintf("Bearer %s", t.token)}, + }), + ) + + // Call the gRPC method to get the container ID from the origin info + containerIDResponse, err := t.client.TaggerGenerateContainerIDFromOriginInfo(t.queryCtx, &pb.GenerateContainerIDFromOriginInfoRequest{ + ExternalData: &pb.GenerateContainerIDFromOriginInfoRequest_ExternalData{ + Init: &originInfo.ExternalData.Init, + ContainerName: &originInfo.ExternalData.ContainerName, + PodUID: &originInfo.ExternalData.PodUID, + }, + }) + if err != nil { + _ = t.log.Errorf("unable to generate container ID from origin info, will retry: %s", err) + return err + } + + if containerIDResponse == nil { + _ = t.log.Warnf("unable to generate container ID from origin info, will retry: %s", err) + return errors.New("containerIDResponse is nil") + } + containerID = containerIDResponse.ContainerID + + fail = false + t.log.Debugf("Container ID generated successfully from origin info %+v: %s", originInfo, containerID) + return nil + }, expBackoff) + + if err != nil { + return "", err + } + return containerID, nil +} + // AccumulateTagsFor returns tags for a given entity at the desired cardinality. func (t *remoteTagger) AccumulateTagsFor(entityID types.EntityID, cardinality types.TagCardinality, tb tagset.TagsAccumulator) error { tags, err := t.Tag(entityID, cardinality) diff --git a/comp/core/tagger/impl/local_tagger.go b/comp/core/tagger/impl/local_tagger.go index ac2259342eb25..85c8741c52b02 100644 --- a/comp/core/tagger/impl/local_tagger.go +++ b/comp/core/tagger/impl/local_tagger.go @@ -9,16 +9,20 @@ import ( "context" "fmt" "sync" + "time" "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/comp/core/tagger/collectors" tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def" + "github.com/DataDog/datadog-agent/comp/core/tagger/origindetection" "github.com/DataDog/datadog-agent/comp/core/tagger/tagstore" "github.com/DataDog/datadog-agent/comp/core/tagger/telemetry" "github.com/DataDog/datadog-agent/comp/core/tagger/types" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" taggertypes "github.com/DataDog/datadog-agent/pkg/tagger/types" "github.com/DataDog/datadog-agent/pkg/tagset" + "github.com/DataDog/datadog-agent/pkg/util/containers/metrics" + "github.com/DataDog/datadog-agent/pkg/util/optional" ) // Tagger is the entry class for entity tagging. It hold the tagger collector, @@ -99,6 +103,12 @@ func (t *localTagger) Tag(entityID types.EntityID, cardinality types.TagCardinal return tags.Copy(), nil } +// GenerateContainerIDFromOriginInfo generates a container ID from Origin Info. +func (t *localTagger) GenerateContainerIDFromOriginInfo(originInfo origindetection.OriginInfo) (string, error) { + metaCollector := metrics.GetProvider(optional.NewOption(t.workloadStore)).GetMetaCollector() + return metaCollector.ContainerIDForPodUIDAndContName(originInfo.ExternalData.PodUID, originInfo.ExternalData.ContainerName, originInfo.ExternalData.Init, time.Second) +} + // LegacyTag has the same behaviour as the Tag method, but it receives the entity id as a string and parses it. // If possible, avoid using this function, and use the Tag method instead. // This function exists in order not to break backward compatibility with rtloader and python diff --git a/comp/core/tagger/impl/replay_tagger.go b/comp/core/tagger/impl/replay_tagger.go index ddc9851a898db..6f012e9c9d680 100644 --- a/comp/core/tagger/impl/replay_tagger.go +++ b/comp/core/tagger/impl/replay_tagger.go @@ -11,6 +11,7 @@ import ( "time" tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def" + "github.com/DataDog/datadog-agent/comp/core/tagger/origindetection" "github.com/DataDog/datadog-agent/comp/core/tagger/tagstore" "github.com/DataDog/datadog-agent/comp/core/tagger/telemetry" "github.com/DataDog/datadog-agent/comp/core/tagger/types" @@ -77,6 +78,12 @@ func (t *replayTagger) LegacyTag(entity string, cardinality types.TagCardinality return t.Tag(entityID, cardinality) } +// GenerateContainerIDFromOriginInfo generates a container ID from Origin Info. +// This is a no-op for the replay tagger +func (t *replayTagger) GenerateContainerIDFromOriginInfo(origindetection.OriginInfo) (string, error) { + return "", nil +} + // AccumulateTagsFor returns tags for a given entity at the desired cardinality. func (t *replayTagger) AccumulateTagsFor(entityID types.EntityID, cardinality types.TagCardinality, tb tagset.TagsAccumulator) error { tags := t.store.LookupHashed(entityID, cardinality) diff --git a/comp/core/tagger/impl/tagger.go b/comp/core/tagger/impl/tagger.go index 1ef1a137d6a34..7023106b1c118 100644 --- a/comp/core/tagger/impl/tagger.go +++ b/comp/core/tagger/impl/tagger.go @@ -27,6 +27,7 @@ import ( log "github.com/DataDog/datadog-agent/comp/core/log/def" tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def" taggermock "github.com/DataDog/datadog-agent/comp/core/tagger/mock" + "github.com/DataDog/datadog-agent/comp/core/tagger/origindetection" "github.com/DataDog/datadog-agent/comp/core/tagger/telemetry" "github.com/DataDog/datadog-agent/comp/core/tagger/types" "github.com/DataDog/datadog-agent/comp/core/tagger/utils" @@ -538,7 +539,12 @@ func (t *TaggerWrapper) EnrichTags(tb tagset.TagsAccumulator, originInfo taggert } } -// generateContainerIDFromExternalData generates a container ID from the external data +// GenerateContainerIDFromOriginInfo generates a container ID from Origin Info. +func (t *TaggerWrapper) GenerateContainerIDFromOriginInfo(originInfo origindetection.OriginInfo) (string, error) { + return t.defaultTagger.GenerateContainerIDFromOriginInfo(originInfo) +} + +// generateContainerIDFromExternalData generates a container ID from the External Data. func (t *TaggerWrapper) generateContainerIDFromExternalData(e externalData, metricsProvider provider.ContainerIDForPodUIDAndContNameRetriever) (string, error) { return metricsProvider.ContainerIDForPodUIDAndContName(e.podUID, e.containerName, e.init, time.Second) } diff --git a/comp/core/tagger/mock/fake_tagger.go b/comp/core/tagger/mock/fake_tagger.go index b4ff66a65d2c6..8a609d052c766 100644 --- a/comp/core/tagger/mock/fake_tagger.go +++ b/comp/core/tagger/mock/fake_tagger.go @@ -10,6 +10,7 @@ import ( "strconv" tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def" + "github.com/DataDog/datadog-agent/comp/core/tagger/origindetection" "github.com/DataDog/datadog-agent/comp/core/tagger/tagstore" "github.com/DataDog/datadog-agent/comp/core/tagger/telemetry" "github.com/DataDog/datadog-agent/comp/core/tagger/types" @@ -118,6 +119,11 @@ func (f *FakeTagger) LegacyTag(entity string, cardinality types.TagCardinality) return f.Tag(entityID, cardinality) } +// GenerateContainerIDFromOriginInfo fake implementation +func (f *FakeTagger) GenerateContainerIDFromOriginInfo(origindetection.OriginInfo) (string, error) { + return "", nil +} + // GlobalTags fake implementation func (f *FakeTagger) GlobalTags(cardinality types.TagCardinality) ([]string, error) { return f.Tag(types.GetGlobalEntityID(), cardinality) diff --git a/comp/core/tagger/origindetection/go.mod b/comp/core/tagger/origindetection/go.mod new file mode 100644 index 0000000000000..10e53c86ea39d --- /dev/null +++ b/comp/core/tagger/origindetection/go.mod @@ -0,0 +1,14 @@ +module github.com/DataDog/datadog-agent/comp/core/tagger/origindetection + +go 1.22.0 + +require github.com/stretchr/testify v1.10.0 + +require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/comp/core/tagger/origindetection/go.sum b/comp/core/tagger/origindetection/go.sum new file mode 100644 index 0000000000000..cec386e1e2769 --- /dev/null +++ b/comp/core/tagger/origindetection/go.sum @@ -0,0 +1,23 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +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/kr/pretty v0.2.1/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/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/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +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/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/comp/core/tagger/origindetection/origindetection.go b/comp/core/tagger/origindetection/origindetection.go new file mode 100644 index 0000000000000..712792c54f298 --- /dev/null +++ b/comp/core/tagger/origindetection/origindetection.go @@ -0,0 +1,84 @@ +// 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. + +// TODO: A lot of the code in this file is currently duplicated in taggertypes. +// We will need to move all the code in taggertype to this file and remove the taggertypes package. + +// Package origindetection contains the types and functions used for Origin Detection. +package origindetection + +import ( + "strconv" + "strings" +) + +// ProductOrigin is the origin of the product that sent the entity. +type ProductOrigin int + +const ( + // ProductOriginDogStatsDLegacy is the ProductOrigin for DogStatsD in Legacy mode. + // TODO: remove this when dogstatsd_origin_detection_unified is enabled by default + ProductOriginDogStatsDLegacy ProductOrigin = iota + // ProductOriginDogStatsD is the ProductOrigin for DogStatsD. + ProductOriginDogStatsD ProductOrigin = iota + // ProductOriginAPM is the ProductOrigin for APM. + ProductOriginAPM ProductOrigin = iota + + // External Data Prefixes + // These prefixes are used to build the External Data Environment Variable. + + // ExternalDataInitPrefix is the prefix for the Init flag in the External Data. + ExternalDataInitPrefix = "it-" + // ExternalDataContainerNamePrefix is the prefix for the Container Name in the External Data. + ExternalDataContainerNamePrefix = "cn-" + // ExternalDataPodUIDPrefix is the prefix for the Pod UID in the External Data. + ExternalDataPodUIDPrefix = "pu-" +) + +// OriginInfo contains the Origin Detection information. +type OriginInfo struct { + LocalData LocalData // LocalData is the local data list. + ExternalData ExternalData // ExternalData is the external data list. + Cardinality string // Cardinality is the cardinality of the resolved origin. + ProductOrigin ProductOrigin // ProductOrigin is the product that sent the origin information. +} + +// LocalData that is generated by the client and sent to the Agent. +type LocalData struct { + ProcessID uint32 // ProcessID of the container process on the host. + ContainerID string // ContainerID sent from the client. + Inode uint64 // Inode is the Cgroup inode of the container. + PodUID string // PodUID of the pod sent from the client. +} + +// ExternalData generated by the Admission Controller and sent to the Agent. +type ExternalData struct { + Init bool // Init is true if the container is an init container. + ContainerName string // ContainerName is the name of the container as seen by the Admission Controller. + PodUID string // PodUID is the UID of the pod as seen by the Admission Controller. +} + +// GenerateContainerIDFromExternalData generates a container ID from the external data. +type GenerateContainerIDFromExternalData func(externalData ExternalData) (string, error) + +// ParseExternalData parses the external data string into an ExternalData struct. +func ParseExternalData(externalEnv string) (ExternalData, error) { + if externalEnv == "" { + return ExternalData{}, nil + } + var externalData ExternalData + var parsingError error + for _, item := range strings.Split(externalEnv, ",") { + switch { + case strings.HasPrefix(item, ExternalDataInitPrefix): + externalData.Init, parsingError = strconv.ParseBool(item[len(ExternalDataInitPrefix):]) + case strings.HasPrefix(item, ExternalDataContainerNamePrefix): + externalData.ContainerName = item[len(ExternalDataContainerNamePrefix):] + case strings.HasPrefix(item, ExternalDataPodUIDPrefix): + externalData.PodUID = item[len(ExternalDataPodUIDPrefix):] + } + } + return externalData, parsingError +} diff --git a/comp/core/tagger/origindetection/origindetection_test.go b/comp/core/tagger/origindetection/origindetection_test.go new file mode 100644 index 0000000000000..a873093f6191b --- /dev/null +++ b/comp/core/tagger/origindetection/origindetection_test.go @@ -0,0 +1,81 @@ +// 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 origindetection contains the types and functions used for Origin Detection. +package origindetection + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestParseExternalData(t *testing.T) { + tests := []struct { + name string + externalEnv string + expectedData ExternalData + expectedError bool + }{ + { + name: "Empty external data", + externalEnv: "", + expectedData: ExternalData{ + Init: false, + ContainerName: "", + PodUID: "", + }, + expectedError: false, + }, + { + name: "Valid external data with Init", + externalEnv: "it-true,cn-container-name,pu-12345678-90ab-cdef-1234-567890abcdef", + expectedData: ExternalData{ + Init: true, + ContainerName: "container-name", + PodUID: "12345678-90ab-cdef-1234-567890abcdef", + }, + expectedError: false, + }, + { + name: "Invalid Init value", + externalEnv: "it-invalid,cn-container-name,pu-12345678-90ab-cdef-1234-567890abcdef", + expectedData: ExternalData{}, + expectedError: true, + }, + { + name: "Partial external data", + externalEnv: "cn-container-name", + expectedData: ExternalData{ + Init: false, + ContainerName: "container-name", + PodUID: "", + }, + expectedError: false, + }, + { + name: "Unrecognized prefix", + externalEnv: "unknown-prefix", + expectedData: ExternalData{ + Init: false, + ContainerName: "", + PodUID: "", + }, + expectedError: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + result, err := ParseExternalData(tc.externalEnv) + + if tc.expectedError { + assert.Error(t, err) + } else { + assert.Equal(t, tc.expectedData, result) + } + }) + } +} diff --git a/comp/core/tagger/server/server.go b/comp/core/tagger/server/server.go index 5e323c43c7ee2..34a719f32c440 100644 --- a/comp/core/tagger/server/server.go +++ b/comp/core/tagger/server/server.go @@ -17,6 +17,7 @@ import ( "github.com/google/uuid" tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def" + "github.com/DataDog/datadog-agent/comp/core/tagger/origindetection" "github.com/DataDog/datadog-agent/comp/core/tagger/proto" "github.com/DataDog/datadog-agent/comp/core/tagger/types" pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/core" @@ -165,3 +166,22 @@ func (s *Server) TaggerFetchEntity(_ context.Context, in *pb.FetchEntityRequest) Tags: tags, }, nil } + +// TaggerGenerateContainerIDFromOriginInfo request the generation of a container ID from external data from the Tagger. +// This function takes an Origin Info but only uses the ExternalData part of it, this is done for backward compatibility. +func (s *Server) TaggerGenerateContainerIDFromOriginInfo(_ context.Context, in *pb.GenerateContainerIDFromOriginInfoRequest) (*pb.GenerateContainerIDFromOriginInfoResponse, error) { + generatedContainerID, err := s.taggerComponent.GenerateContainerIDFromOriginInfo(origindetection.OriginInfo{ + ExternalData: origindetection.ExternalData{ + Init: *in.ExternalData.Init, + ContainerName: *in.ExternalData.ContainerName, + PodUID: *in.ExternalData.PodUID, + }, + }) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "%s", err) + } + + return &pb.GenerateContainerIDFromOriginInfoResponse{ + ContainerID: generatedContainerID, + }, nil +} diff --git a/comp/core/tagger/telemetry/telemetry.go b/comp/core/tagger/telemetry/telemetry.go index 8b50202dd2e99..97c7153d9c052 100644 --- a/comp/core/tagger/telemetry/telemetry.go +++ b/comp/core/tagger/telemetry/telemetry.go @@ -61,6 +61,10 @@ type Store struct { // notification with a group of events. Receives telemetry.Counter + // OriginInfoRequests tracks the number of requests to the Tagger + // to generate a container ID from Origin Info. + OriginInfoRequests telemetry.Counter + LowCardinalityQueries CardinalityTelemetry OrchestratorCardinalityQueries CardinalityTelemetry HighCardinalityQueries CardinalityTelemetry @@ -131,6 +135,12 @@ func NewStore(telemetryComp telemetry.Component) *Store { []string{}, "Number of of times the tagger has received a notification with a group of events", telemetry.Options{NoDoubleUnderscoreSep: true}), + // OriginInfoRequests tracks the number of requests to the tagger + // to generate a container ID from origin info. + OriginInfoRequests: telemetryComp.NewCounterWithOpts(subsystem, "origin_info_requests", + []string{"status"}, "Number of requests to the tagger to generate a container ID from origin info.", + telemetry.Options{NoDoubleUnderscoreSep: true}), + LowCardinalityQueries: newCardinalityTelemetry(queries, types.LowCardinalityString), OrchestratorCardinalityQueries: newCardinalityTelemetry(queries, types.OrchestratorCardinalityString), HighCardinalityQueries: newCardinalityTelemetry(queries, types.HighCardinalityString), diff --git a/comp/forwarder/defaultforwarder/go.mod b/comp/forwarder/defaultforwarder/go.mod index a0891b10fda75..97eb61b033263 100644 --- a/comp/forwarder/defaultforwarder/go.mod +++ b/comp/forwarder/defaultforwarder/go.mod @@ -113,7 +113,7 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/comp/forwarder/defaultforwarder/go.sum b/comp/forwarder/defaultforwarder/go.sum index 2e4c8055f6ab0..735da3a7badda 100644 --- a/comp/forwarder/defaultforwarder/go.sum +++ b/comp/forwarder/defaultforwarder/go.sum @@ -97,8 +97,8 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/forwarder/orchestrator/orchestratorinterface/go.mod b/comp/forwarder/orchestrator/orchestratorinterface/go.mod index 3022f485e02a3..7c55fcf139cf0 100644 --- a/comp/forwarder/orchestrator/orchestratorinterface/go.mod +++ b/comp/forwarder/orchestrator/orchestratorinterface/go.mod @@ -117,7 +117,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/comp/forwarder/orchestrator/orchestratorinterface/go.sum b/comp/forwarder/orchestrator/orchestratorinterface/go.sum index 68e574e5c8151..c23eb9a608463 100644 --- a/comp/forwarder/orchestrator/orchestratorinterface/go.sum +++ b/comp/forwarder/orchestrator/orchestratorinterface/go.sum @@ -100,8 +100,8 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/haagent/helpers/helpers.go b/comp/haagent/helpers/helpers.go new file mode 100644 index 0000000000000..4b5e755e04936 --- /dev/null +++ b/comp/haagent/helpers/helpers.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 2024-present Datadog, Inc. + +// Package haagenthelpers provides helpers for haagent component +package haagenthelpers + +import ( + "github.com/DataDog/datadog-agent/pkg/config/model" +) + +// IsEnabled returns true if HA Agent is enabled +func IsEnabled(agentConfig model.Reader) bool { + return agentConfig.GetBool("ha_agent.enabled") +} + +// GetGroup returns HA Agent group +func GetGroup(agentConfig model.Reader) string { + return agentConfig.GetString("ha_agent.group") +} + +// GetHaAgentTags returns HA Agent related tags +func GetHaAgentTags(agentConfig model.Reader) []string { + return []string{"agent_group:" + GetGroup(agentConfig)} +} diff --git a/comp/haagent/helpers/helpers_test.go b/comp/haagent/helpers/helpers_test.go new file mode 100644 index 0000000000000..987ab6a5cccf4 --- /dev/null +++ b/comp/haagent/helpers/helpers_test.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 haagenthelpers + +import ( + "testing" + + "github.com/DataDog/datadog-agent/comp/core/config" + "github.com/stretchr/testify/assert" +) + +func TestIsEnabled(t *testing.T) { + cfg := config.NewMock(t) + assert.False(t, IsEnabled(cfg)) + + cfg.SetWithoutSource("ha_agent.enabled", true) + assert.True(t, IsEnabled(cfg)) +} + +func TestGetGroup(t *testing.T) { + cfg := config.NewMock(t) + cfg.SetWithoutSource("ha_agent.group", "my-group") + assert.Equal(t, "my-group", GetGroup(cfg)) +} + +func TestGetHaAgentTags(t *testing.T) { + cfg := config.NewMock(t) + cfg.SetWithoutSource("ha_agent.group", "my-group") + assert.Equal(t, []string{"agent_group:my-group"}, GetHaAgentTags(cfg)) +} diff --git a/comp/haagent/impl/config.go b/comp/haagent/impl/config.go index 2a6c4e20a8d12..ea9f54d9f16ea 100644 --- a/comp/haagent/impl/config.go +++ b/comp/haagent/impl/config.go @@ -7,6 +7,7 @@ package haagentimpl import ( "github.com/DataDog/datadog-agent/comp/core/config" + helpers "github.com/DataDog/datadog-agent/comp/haagent/helpers" ) // validHaIntegrations represent the list of integrations that will be considered as @@ -30,7 +31,7 @@ type haAgentConfigs struct { func newHaAgentConfigs(agentConfig config.Component) *haAgentConfigs { return &haAgentConfigs{ - enabled: agentConfig.GetBool("ha_agent.enabled"), - group: agentConfig.GetString("ha_agent.group"), + enabled: helpers.IsEnabled(agentConfig), + group: helpers.GetGroup(agentConfig), } } diff --git a/comp/logs/agent/config/go.mod b/comp/logs/agent/config/go.mod index 5e99aa77604f0..1ae81a7be7da6 100644 --- a/comp/logs/agent/config/go.mod +++ b/comp/logs/agent/config/go.mod @@ -76,7 +76,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/comp/logs/agent/config/go.sum b/comp/logs/agent/config/go.sum index 9694f5d5e2355..dd16364891695 100644 --- a/comp/logs/agent/config/go.sum +++ b/comp/logs/agent/config/go.sum @@ -87,8 +87,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/metadata/host/hostimpl/hosttags/tags.go b/comp/metadata/host/hostimpl/hosttags/tags.go index 01cfff7c0810f..92d610d49e079 100644 --- a/comp/metadata/host/hostimpl/hosttags/tags.go +++ b/comp/metadata/host/hostimpl/hosttags/tags.go @@ -12,6 +12,7 @@ import ( "strings" "time" + haagenthelpers "github.com/DataDog/datadog-agent/comp/haagent/helpers" "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/config/model" configUtils "github.com/DataDog/datadog-agent/pkg/config/utils" @@ -133,8 +134,8 @@ func Get(ctx context.Context, cached bool, conf model.Reader) *Tags { hostTags = appendToHostTags(hostTags, clusterNameTags) } - if conf.GetBool("ha_agent.enabled") { - hostTags = appendToHostTags(hostTags, []string{"agent_group:" + conf.GetString("ha_agent.group")}) + if haagenthelpers.IsEnabled(conf) { + hostTags = appendToHostTags(hostTags, haagenthelpers.GetHaAgentTags(conf)) } gceTags := []string{} diff --git a/comp/otelcol/converter/README.md b/comp/otelcol/converter/README.md index 31c0c53f7176b..ad8c831ada147 100644 --- a/comp/otelcol/converter/README.md +++ b/comp/otelcol/converter/README.md @@ -1,8 +1,6 @@ # Converter Component -The converter: -- Enhances the user provided configuration -- Provides an API which returns the provided and enhanced configurations +The converter enhances the user provided configuration. ## Autoconfigure logic @@ -32,12 +30,6 @@ If `api_key` is unset, set to an empty string or set to a secret, the converter The converter will automatically set `datadogconnector` config `trace.span_name_as_resource_name` to true in any datadog connectors in your configuration. -## Provided and enhanced config - -`GetProvidedConf` and `GetEnhancedConf` return the string representation of the user provided and autoconfigured conf respectively. Currently, these APIs have two limitations: -- They do not redact sensitive data -- They do not provide the effective config (including defaults...etc) - ## Opting out of converter It is possible to opt out of the converter by setting env var `DD_OTELCOLLECTOR_CONVERTER_ENABLED` or agent config `otelcollector.converter.enabled` to `false` (`true` by default). Please note that by doing so, you are removing functionality including flare collection from otel-agent, health metrics from collector, or infra level tagging on your telemetry data. If you want to opt out of some components, you can disable all and add the components that you require manually: diff --git a/comp/otelcol/converter/impl/go.mod b/comp/otelcol/converter/impl/go.mod index b3bae2ce5b62b..ec9c75f1a3c68 100644 --- a/comp/otelcol/converter/impl/go.mod +++ b/comp/otelcol/converter/impl/go.mod @@ -86,7 +86,7 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/knadh/koanf/maps v0.1.1 // indirect diff --git a/comp/otelcol/converter/impl/go.sum b/comp/otelcol/converter/impl/go.sum index a98a26b75f480..4239a8ba70c9d 100644 --- a/comp/otelcol/converter/impl/go.sum +++ b/comp/otelcol/converter/impl/go.sum @@ -89,8 +89,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/otelcol/ddflareextension/README.md b/comp/otelcol/ddflareextension/README.md index 13f5902877c4e..c54027041c70f 100644 --- a/comp/otelcol/ddflareextension/README.md +++ b/comp/otelcol/ddflareextension/README.md @@ -32,7 +32,7 @@ The port is the location in which the otel-agent will expose the data required t The flare will collect both the provided collector config and the enhanced config (enhanced via [converter](../converter/README.md)). -The provided collector configs can be found in `otel/otel-flare/customer.cfg` and the enhanced config can be found in `otel/otel-flare/customer.cfg`. +The provided collector configs can be found in `otel/otel-flare/customer.cfg` and the enhanced config can be found in `otel/otel-flare/runtime.cfg`. ### Environment variables diff --git a/comp/otelcol/ddflareextension/impl/go.mod b/comp/otelcol/ddflareextension/impl/go.mod index 633e70723c7b1..7af5d796d92fb 100644 --- a/comp/otelcol/ddflareextension/impl/go.mod +++ b/comp/otelcol/ddflareextension/impl/go.mod @@ -263,7 +263,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/system/socket v0.59.0 // indirect github.com/DataDog/datadog-agent/pkg/util/winutil v0.59.1 // indirect github.com/DataDog/datadog-api-client-go/v2 v2.33.0 // indirect - github.com/DataDog/datadog-go/v5 v5.5.0 // indirect + github.com/DataDog/datadog-go/v5 v5.6.0 // indirect github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 // indirect github.com/DataDog/go-sqllexer v0.0.17 // indirect github.com/DataDog/go-tuf v1.1.0-0.5.2 // indirect @@ -358,7 +358,7 @@ require ( github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/hashicorp/nomad/api v0.0.0-20240717122358-3d93bd3778f3 // indirect github.com/hashicorp/serf v0.10.1 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/hetznercloud/hcloud-go/v2 v2.10.2 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/imdario/mergo v0.3.16 // indirect diff --git a/comp/otelcol/ddflareextension/impl/go.sum b/comp/otelcol/ddflareextension/impl/go.sum index 86b5c591f955c..d4f8e67e79da5 100644 --- a/comp/otelcol/ddflareextension/impl/go.sum +++ b/comp/otelcol/ddflareextension/impl/go.sum @@ -66,8 +66,8 @@ github.com/DataDog/datadog-agent/comp/core/log v0.56.2/go.mod h1:ivJ/RMZjTNkoPPN github.com/DataDog/datadog-api-client-go/v2 v2.33.0 h1:OI6kDnJeQmkjfGzxmP0XUQUxMD4tp6oAPXnnJ4VpgUM= github.com/DataDog/datadog-api-client-go/v2 v2.33.0/go.mod h1:d3tOEgUd2kfsr9uuHQdY+nXrWp4uikgTgVCPdKNK30U= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -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/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= 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.17 h1:u47fJAVg/+5DA74ZW3w0Qu+3qXHd3GtnA8ZBYixdPrM= @@ -443,8 +443,8 @@ github.com/hashicorp/nomad/api v0.0.0-20240717122358-3d93bd3778f3 h1:fgVfQ4AC1av github.com/hashicorp/nomad/api v0.0.0-20240717122358-3d93bd3778f3/go.mod h1:svtxn6QnrQ69P23VvIWMR34tg3vmwLz4UdUzm1dSCgE= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/hetznercloud/hcloud-go/v2 v2.10.2 h1:9gyTUPhfNbfbS40Spgij5mV5k37bOZgt8iHKCbfGs5I= github.com/hetznercloud/hcloud-go/v2 v2.10.2/go.mod h1:xQ+8KhIS62W0D78Dpi57jsufWh844gUw1az5OUvaeq8= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= diff --git a/comp/otelcol/ddflareextension/impl/testdata/simple-dd/config-enhanced-result.yaml b/comp/otelcol/ddflareextension/impl/testdata/simple-dd/config-enhanced-result.yaml index 5914d58d690a1..055f7c67144eb 100644 --- a/comp/otelcol/ddflareextension/impl/testdata/simple-dd/config-enhanced-result.yaml +++ b/comp/otelcol/ddflareextension/impl/testdata/simple-dd/config-enhanced-result.yaml @@ -88,7 +88,7 @@ exporters: peer_service_aggregation: false peer_tags: [] peer_tags_aggregation: false - span_name_as_resource_name: true + span_name_as_resource_name: false span_name_remappings: {} trace_buffer: 0 write_buffer_size: 0 diff --git a/comp/otelcol/ddflareextension/impl/testdata/simple-dd/config-provided-result.yaml b/comp/otelcol/ddflareextension/impl/testdata/simple-dd/config-provided-result.yaml index 807d80682416a..d0b9a8b4b3aa8 100644 --- a/comp/otelcol/ddflareextension/impl/testdata/simple-dd/config-provided-result.yaml +++ b/comp/otelcol/ddflareextension/impl/testdata/simple-dd/config-provided-result.yaml @@ -88,7 +88,7 @@ exporters: peer_service_aggregation: false peer_tags: [] peer_tags_aggregation: false - span_name_as_resource_name: true + span_name_as_resource_name: false span_name_remappings: {} trace_buffer: 0 write_buffer_size: 0 diff --git a/comp/otelcol/logsagentpipeline/go.mod b/comp/otelcol/logsagentpipeline/go.mod index fd1925f5a1a1d..2a575bf145e7e 100644 --- a/comp/otelcol/logsagentpipeline/go.mod +++ b/comp/otelcol/logsagentpipeline/go.mod @@ -121,7 +121,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/comp/otelcol/logsagentpipeline/go.sum b/comp/otelcol/logsagentpipeline/go.sum index 9061e9b89a5c6..b0f7d9ee40dfd 100644 --- a/comp/otelcol/logsagentpipeline/go.sum +++ b/comp/otelcol/logsagentpipeline/go.sum @@ -99,8 +99,8 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.mod b/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.mod index 6bce0b3c962d4..711aa095cc468 100644 --- a/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.mod +++ b/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.mod @@ -136,7 +136,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum b/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum index 9061e9b89a5c6..b0f7d9ee40dfd 100644 --- a/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum +++ b/comp/otelcol/logsagentpipeline/logsagentpipelineimpl/go.sum @@ -99,8 +99,8 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/otelcol/otlp/components/exporter/datadogexporter/factory.go b/comp/otelcol/otlp/components/exporter/datadogexporter/factory.go index 35cb0957daada..b32933f255ba3 100644 --- a/comp/otelcol/otlp/components/exporter/datadogexporter/factory.go +++ b/comp/otelcol/otlp/components/exporter/datadogexporter/factory.go @@ -119,7 +119,6 @@ func NewFactory( func CreateDefaultConfig() component.Config { ddcfg := datadogconfig.CreateDefaultConfig().(*datadogconfig.Config) ddcfg.Traces.TracesConfig.ComputeTopLevelBySpanKind = true - ddcfg.Traces.TracesConfig.SpanNameAsResourceName = true ddcfg.Logs.Endpoint = "https://agent-http-intake.logs.datadoghq.com" ddcfg.HostMetadata.Enabled = false return ddcfg diff --git a/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod b/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod index 7ce89b2ee2d53..c3e28a412d2e6 100644 --- a/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod +++ b/comp/otelcol/otlp/components/exporter/datadogexporter/go.mod @@ -102,7 +102,7 @@ require ( github.com/DataDog/datadog-agent/pkg/proto v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/serializer v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/trace v0.56.0-rc.3 - github.com/DataDog/datadog-go/v5 v5.5.0 + github.com/DataDog/datadog-go/v5 v5.6.0 github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.22.0 github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/metrics v0.22.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/datadog v0.115.0 @@ -239,7 +239,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect diff --git a/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum b/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum index 1f0bcec425283..e9c507fbafa8a 100644 --- a/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum +++ b/comp/otelcol/otlp/components/exporter/datadogexporter/go.sum @@ -4,8 +4,8 @@ github.com/DataDog/agent-payload/v5 v5.0.138 h1:Wg7hmWuoLC/o0X3zZ+uGcfRHPyaytlju github.com/DataDog/agent-payload/v5 v5.0.138/go.mod h1:lxh9lb5xYrBXjblpIWYUi4deJqVbkIfkjwesi5nskDc= github.com/DataDog/datadog-api-client-go/v2 v2.33.0 h1:OI6kDnJeQmkjfGzxmP0XUQUxMD4tp6oAPXnnJ4VpgUM= github.com/DataDog/datadog-api-client-go/v2 v2.33.0/go.mod h1:d3tOEgUd2kfsr9uuHQdY+nXrWp4uikgTgVCPdKNK30U= -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/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= 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.17 h1:u47fJAVg/+5DA74ZW3w0Qu+3qXHd3GtnA8ZBYixdPrM= @@ -175,8 +175,8 @@ github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod index 23ddd3225d779..80cffa6a338c5 100644 --- a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod +++ b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.mod @@ -110,7 +110,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum index 85a19bf8e57b5..c50808e9a40cd 100644 --- a/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum +++ b/comp/otelcol/otlp/components/exporter/logsagentexporter/go.sum @@ -121,8 +121,8 @@ github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod b/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod index 3ed3c5a02c175..1f8b9e2be8d1d 100644 --- a/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod +++ b/comp/otelcol/otlp/components/exporter/serializerexporter/go.mod @@ -161,7 +161,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect diff --git a/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum b/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum index b0e60957170e6..a33f1cc34269d 100644 --- a/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum +++ b/comp/otelcol/otlp/components/exporter/serializerexporter/go.sum @@ -139,8 +139,8 @@ github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/otelcol/otlp/components/metricsclient/go.mod b/comp/otelcol/otlp/components/metricsclient/go.mod index 953a7c7a017cd..9f3e33feb8bf7 100644 --- a/comp/otelcol/otlp/components/metricsclient/go.mod +++ b/comp/otelcol/otlp/components/metricsclient/go.mod @@ -6,7 +6,7 @@ replace github.com/DataDog/datadog-agent/pkg/trace => ../../../../../pkg/trace require ( github.com/DataDog/datadog-agent/pkg/trace v0.56.0-rc.3 - github.com/DataDog/datadog-go/v5 v5.5.0 + github.com/DataDog/datadog-go/v5 v5.6.0 github.com/stretchr/testify v1.10.0 go.opentelemetry.io/otel v1.32.0 go.opentelemetry.io/otel/metric v1.32.0 diff --git a/comp/otelcol/otlp/components/metricsclient/go.sum b/comp/otelcol/otlp/components/metricsclient/go.sum index d3cbee6f76083..08cca2d402cd6 100644 --- a/comp/otelcol/otlp/components/metricsclient/go.sum +++ b/comp/otelcol/otlp/components/metricsclient/go.sum @@ -1,5 +1,5 @@ -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/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= diff --git a/comp/otelcol/otlp/components/statsprocessor/go.mod b/comp/otelcol/otlp/components/statsprocessor/go.mod index 8a0a6409f886f..05eb43fdf4629 100644 --- a/comp/otelcol/otlp/components/statsprocessor/go.mod +++ b/comp/otelcol/otlp/components/statsprocessor/go.mod @@ -22,7 +22,7 @@ require ( github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/proto v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/trace v0.56.0-rc.3 - github.com/DataDog/datadog-go/v5 v5.5.0 + github.com/DataDog/datadog-go/v5 v5.6.0 github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.22.0 github.com/stretchr/testify v1.10.0 go.opentelemetry.io/collector/component/componenttest v0.115.0 diff --git a/comp/otelcol/otlp/components/statsprocessor/go.sum b/comp/otelcol/otlp/components/statsprocessor/go.sum index 13b6ed7206fcd..25a9e6fccac3c 100644 --- a/comp/otelcol/otlp/components/statsprocessor/go.sum +++ b/comp/otelcol/otlp/components/statsprocessor/go.sum @@ -1,5 +1,5 @@ -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/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= github.com/DataDog/go-sqllexer v0.0.17 h1:u47fJAVg/+5DA74ZW3w0Qu+3qXHd3GtnA8ZBYixdPrM= github.com/DataDog/go-sqllexer v0.0.17/go.mod h1:KwkYhpFEVIq+BfobkTC1vfqm4gTi65skV/DpDBXtexc= github.com/DataDog/go-tuf v1.1.0-0.5.2 h1:4CagiIekonLSfL8GMHRHcHudo1fQnxELS9g4tiAupQ4= diff --git a/comp/otelcol/otlp/testutil/go.mod b/comp/otelcol/otlp/testutil/go.mod index 58832aca7482e..d51e4d63d2b36 100644 --- a/comp/otelcol/otlp/testutil/go.mod +++ b/comp/otelcol/otlp/testutil/go.mod @@ -72,7 +72,7 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/comp/otelcol/otlp/testutil/go.sum b/comp/otelcol/otlp/testutil/go.sum index 22f79264c82e8..0778f221b9bca 100644 --- a/comp/otelcol/otlp/testutil/go.sum +++ b/comp/otelcol/otlp/testutil/go.sum @@ -98,8 +98,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/process/apiserver/apiserver.go b/comp/process/apiserver/apiserver.go index c216b2a93fef4..24bbe6353d06f 100644 --- a/comp/process/apiserver/apiserver.go +++ b/comp/process/apiserver/apiserver.go @@ -15,6 +15,7 @@ import ( "go.uber.org/fx" "github.com/DataDog/datadog-agent/cmd/process-agent/api" + "github.com/DataDog/datadog-agent/comp/api/authtoken" log "github.com/DataDog/datadog-agent/comp/core/log/def" pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" ) @@ -32,6 +33,8 @@ type dependencies struct { Log log.Component + At authtoken.Component + APIServerDeps api.APIServerDeps } @@ -54,6 +57,7 @@ func newApiServer(deps dependencies) Component { ReadTimeout: timeout, WriteTimeout: timeout, IdleTimeout: timeout, + TLSConfig: deps.At.GetTLSServerConfig(), }, } diff --git a/comp/process/apiserver/apiserver_test.go b/comp/process/apiserver/apiserver_test.go index c9b0f4b96e92d..a0d94db4db4c2 100644 --- a/comp/process/apiserver/apiserver_test.go +++ b/comp/process/apiserver/apiserver_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/fx" + "github.com/DataDog/datadog-agent/comp/api/authtoken/fetchonlyimpl" "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/core/settings/settingsimpl" "github.com/DataDog/datadog-agent/comp/core/status" @@ -39,6 +40,7 @@ func TestLifecycle(t *testing.T) { }), statusimpl.Module(), settingsimpl.MockModule(), + fetchonlyimpl.MockModule(), )) assert.Eventually(t, func() bool { diff --git a/comp/process/bundle_test.go b/comp/process/bundle_test.go index 591dce9f63cfb..9fb4131e013c0 100644 --- a/comp/process/bundle_test.go +++ b/comp/process/bundle_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/fx" + "github.com/DataDog/datadog-agent/comp/api/authtoken/fetchonlyimpl" "github.com/DataDog/datadog-agent/comp/core" configComp "github.com/DataDog/datadog-agent/comp/core/config" log "github.com/DataDog/datadog-agent/comp/core/log/def" @@ -60,6 +61,7 @@ func TestBundleDependencies(t *testing.T) { rdnsquerier.MockModule(), npcollectorimpl.MockModule(), statsd.MockModule(), + fetchonlyimpl.MockModule(), ) } diff --git a/comp/serializer/compression/go.mod b/comp/serializer/compression/go.mod index a46ee59b26ae6..f1c59cd40d645 100644 --- a/comp/serializer/compression/go.mod +++ b/comp/serializer/compression/go.mod @@ -71,7 +71,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/comp/serializer/compression/go.sum b/comp/serializer/compression/go.sum index a3f8c86e6fc2e..3b405d22ebcc8 100644 --- a/comp/serializer/compression/go.sum +++ b/comp/serializer/compression/go.sum @@ -89,8 +89,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/comp/snmptraps/listener/listenerimpl/listener.go b/comp/snmptraps/listener/listenerimpl/listener.go index 7571896edc30d..ab3d5c3aa3dea 100644 --- a/comp/snmptraps/listener/listenerimpl/listener.go +++ b/comp/snmptraps/listener/listenerimpl/listener.go @@ -8,6 +8,7 @@ package listenerimpl import ( "context" + "crypto/subtle" "errors" "fmt" "net" @@ -167,7 +168,8 @@ func validatePacket(p *gosnmp.SnmpPacket, c *config.TrapsConfig) error { // At least one of the known community strings must match. for _, community := range c.CommunityStrings { - if community == p.Community { + // Simple string equality check, but in constant time to avoid timing attacks + if subtle.ConstantTimeCompare([]byte(community), []byte(p.Community)) == 1 { return nil } } diff --git a/comp/trace/agent/impl/agent.go b/comp/trace/agent/impl/agent.go index b3d783288ceb6..de9237dedeea5 100644 --- a/comp/trace/agent/impl/agent.go +++ b/comp/trace/agent/impl/agent.go @@ -24,6 +24,7 @@ import ( "go.opentelemetry.io/collector/pdata/ptrace" "go.uber.org/fx" + "github.com/DataDog/datadog-agent/comp/api/authtoken" "github.com/DataDog/datadog-agent/comp/core/secrets" tagger "github.com/DataDog/datadog-agent/comp/core/tagger/def" "github.com/DataDog/datadog-agent/comp/dogstatsd/statsd" @@ -68,6 +69,7 @@ type dependencies struct { Statsd statsd.Component Tagger tagger.Component Compressor compression.Component + At authtoken.Component } var _ traceagent.Component = (*component)(nil) @@ -93,6 +95,7 @@ type component struct { params *Params tagger tagger.Component telemetryCollector telemetry.TelemetryCollector + at authtoken.Component wg *sync.WaitGroup } @@ -115,6 +118,7 @@ func NewAgent(deps dependencies) (traceagent.Component, error) { params: deps.Params, telemetryCollector: deps.TelemetryCollector, tagger: deps.Tagger, + at: deps.At, wg: &sync.WaitGroup{}, } statsdCl, err := setupMetrics(deps.Statsd, c.config, c.telemetryCollector) diff --git a/comp/trace/agent/impl/run.go b/comp/trace/agent/impl/run.go index df25106b78755..f40b36e29ae7f 100644 --- a/comp/trace/agent/impl/run.go +++ b/comp/trace/agent/impl/run.go @@ -23,7 +23,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/trace/info" "github.com/DataDog/datadog-agent/pkg/trace/telemetry" "github.com/DataDog/datadog-agent/pkg/trace/watchdog" - "github.com/DataDog/datadog-agent/pkg/util" + "github.com/DataDog/datadog-agent/pkg/util/coredump" "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/DataDog/datadog-agent/pkg/util/profiling" "github.com/DataDog/datadog-agent/pkg/version" @@ -41,7 +41,7 @@ func runAgentSidekicks(ag component) error { defer watchdog.LogOnPanic(ag.Statsd) - if err := util.SetupCoreDump(pkgconfigsetup.Datadog()); err != nil { + if err := coredump.Setup(pkgconfigsetup.Datadog()); err != nil { log.Warnf("Can't setup core dumps: %v, core dumps might not be available after a crash", err) } @@ -98,6 +98,9 @@ func runAgentSidekicks(ag component) error { })) } + // Configure the Trace Agent Debug server to use the IPC certificate + ag.Agent.DebugServer.SetTLSConfig(ag.at.GetTLSServerConfig()) + log.Infof("Trace agent running on host %s", tracecfg.Hostname) if pcfg := profilingConfig(tracecfg); pcfg != nil { if err := profiling.Start(*pcfg); err != nil { diff --git a/comp/trace/bundle_test.go b/comp/trace/bundle_test.go index e9874a4b40077..692e7c255f473 100644 --- a/comp/trace/bundle_test.go +++ b/comp/trace/bundle_test.go @@ -13,6 +13,8 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/fx" + "github.com/DataDog/datadog-agent/comp/api/authtoken/createandfetchimpl" + "github.com/DataDog/datadog-agent/comp/api/authtoken/fetchonlyimpl" "github.com/DataDog/datadog-agent/comp/core" coreconfig "github.com/DataDog/datadog-agent/comp/core/config" log "github.com/DataDog/datadog-agent/comp/core/log/def" @@ -45,6 +47,7 @@ func TestBundleDependencies(t *testing.T) { zstdfx.Module(), taggerfx.Module(tagger.Params{}), fx.Supply(&traceagentimpl.Params{}), + createandfetchimpl.Module(), ) } @@ -75,6 +78,7 @@ func TestMockBundleDependencies(t *testing.T) { fx.Invoke(func(_ traceagent.Component) {}), MockBundle(), taggerfx.Module(tagger.Params{}), + fetchonlyimpl.MockModule(), )) require.NotNil(t, cfg.Object()) diff --git a/comp/trace/status/statusimpl/status.go b/comp/trace/status/statusimpl/status.go index e476ee0281d7a..00a8730b87da8 100644 --- a/comp/trace/status/statusimpl/status.go +++ b/comp/trace/status/statusimpl/status.go @@ -95,7 +95,7 @@ func (s statusProvider) populateStatus() map[string]interface{} { port := s.Config.GetInt("apm_config.debug.port") c := client() - url := fmt.Sprintf("http://localhost:%d/debug/vars", port) + url := fmt.Sprintf("https://localhost:%d/debug/vars", port) resp, err := apiutil.DoGet(c, url, apiutil.CloseConnection) if err != nil { return map[string]interface{}{ diff --git a/go.mod b/go.mod index a01741a7d419f..30981dbec9ce2 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ replace ( github.com/DataDog/datadog-agent/comp/core/secrets => ./comp/core/secrets github.com/DataDog/datadog-agent/comp/core/status => ./comp/core/status github.com/DataDog/datadog-agent/comp/core/status/statusimpl => ./comp/core/status/statusimpl + github.com/DataDog/datadog-agent/comp/core/tagger/origindetection => ./comp/core/tagger/origindetection github.com/DataDog/datadog-agent/comp/core/tagger/tags => ./comp/core/tagger/tags github.com/DataDog/datadog-agent/comp/core/tagger/types => ./comp/core/tagger/types github.com/DataDog/datadog-agent/comp/core/tagger/utils => ./comp/core/tagger/utils @@ -157,8 +158,8 @@ require ( github.com/DataDog/datadog-agent/pkg/util/log v0.59.1 github.com/DataDog/datadog-agent/pkg/util/pointer v0.59.0 github.com/DataDog/datadog-agent/pkg/util/scrubber v0.59.1 - github.com/DataDog/datadog-go/v5 v5.5.0 - github.com/DataDog/datadog-operator v0.7.1-0.20241024104907-734366f3c0d1 + github.com/DataDog/datadog-go/v5 v5.6.0 + github.com/DataDog/datadog-operator v1.11.0-rc.2 github.com/DataDog/ebpf-manager v0.7.4 github.com/DataDog/gopsutil v1.2.2 github.com/DataDog/nikos v1.12.8 @@ -197,7 +198,7 @@ require ( github.com/cri-o/ocicni v0.4.3 github.com/cyphar/filepath-securejoin v0.3.4 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc - github.com/docker/docker v27.3.1+incompatible + github.com/docker/docker v27.4.0+incompatible github.com/docker/go-connections v0.5.0 github.com/dustin/go-humanize v1.0.1 github.com/elastic/go-libaudit/v2 v2.5.0 @@ -227,7 +228,7 @@ require ( github.com/hashicorp/consul/api v1.30.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru/v2 v2.0.7 - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb github.com/iceber/iouring-go v0.0.0-20230403020409-002cfd2e2a90 github.com/imdario/mergo v0.3.16 github.com/invopop/jsonschema v0.12.0 @@ -262,7 +263,6 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/samber/lo v1.47.0 github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da - github.com/shirou/gopsutil/v3 v3.24.5 github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 github.com/sirupsen/logrus v1.9.3 github.com/skydive-project/go-debouncer v1.0.0 @@ -323,9 +323,9 @@ require ( gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 gopkg.in/zorkian/go-datadog-api.v2 v2.30.0 - k8s.io/api v0.31.3 + k8s.io/api v0.31.4 k8s.io/apiextensions-apiserver v0.31.2 - k8s.io/apimachinery v0.31.3 + k8s.io/apimachinery v0.31.4 k8s.io/apiserver v0.31.2 // indirect k8s.io/autoscaler/vertical-pod-autoscaler v0.13.0 k8s.io/client-go v0.31.3 @@ -375,19 +375,19 @@ require ( github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect - github.com/aws/aws-sdk-go-v2 v1.32.5 - github.com/aws/aws-sdk-go-v2/config v1.28.5 - github.com/aws/aws-sdk-go-v2/credentials v1.17.46 - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 // indirect + github.com/aws/aws-sdk-go-v2 v1.32.6 + github.com/aws/aws-sdk-go-v2/config v1.28.6 + github.com/aws/aws-sdk-go-v2/credentials v1.17.47 + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect github.com/aws/aws-sdk-go-v2/service/ebs v1.27.0 // indirect github.com/aws/aws-sdk-go-v2/service/ec2 v1.190.0 - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 // indirect github.com/aws/smithy-go v1.22.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 // indirect @@ -403,7 +403,7 @@ require ( github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect github.com/dgryski/go-jump v0.0.0-20211018200510-ba001c3ffce0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/docker/cli v27.1.1+incompatible // indirect + github.com/docker/cli v27.4.0+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.1 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect @@ -426,7 +426,6 @@ require ( github.com/godbus/dbus/v5 v5.1.0 github.com/golang/glog v1.2.2 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/licenseclassifier/v2 v2.0.0 // indirect github.com/google/uuid v1.6.0 github.com/google/wire v0.6.0 // indirect github.com/googleapis/gax-go/v2 v2.13.0 // indirect @@ -655,6 +654,7 @@ require ( github.com/DataDog/datadog-agent/comp/core/secrets v0.59.0 github.com/DataDog/datadog-agent/comp/core/status v0.59.0-rc.6 github.com/DataDog/datadog-agent/comp/core/status/statusimpl v0.56.0-rc.3 + github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.0.0-00010101000000-000000000000 github.com/DataDog/datadog-agent/comp/core/tagger/tags v0.0.0-00010101000000-000000000000 github.com/DataDog/datadog-agent/comp/core/tagger/types v0.59.0 github.com/DataDog/datadog-agent/comp/core/telemetry v0.59.0 @@ -741,7 +741,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/kms v1.37.6 github.com/aws/aws-sdk-go-v2/service/rds v1.90.0 github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.6 - github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20240409155312-26d1ea377073 github.com/cloudfoundry-community/go-cfclient/v2 v2.0.1-0.20230503155151-3d15366c5820 github.com/containerd/cgroups/v3 v3.0.4 github.com/containerd/typeurl/v2 v2.2.3 @@ -813,15 +812,15 @@ require ( github.com/Showmax/go-fqdn v1.0.0 // indirect github.com/VividCortex/ewma v1.2.0 // indirect github.com/agext/levenshtein v1.2.3 // indirect + github.com/alecthomas/assert/v2 v2.6.0 // indirect github.com/alecthomas/participle/v2 v2.1.1 // indirect + github.com/alecthomas/repr v0.4.0 // indirect github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect github.com/antchfx/xmlquery v1.4.2 // indirect github.com/antchfx/xpath v1.3.2 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/apache/thrift v0.21.0 // indirect github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 // indirect - github.com/aws/aws-sdk-go-v2/service/ecr v1.36.2 // indirect - github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.0 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/bitnami/go-version v0.0.0-20231130084017-bb00604d650c // indirect @@ -975,7 +974,6 @@ require ( github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect github.com/scaleway/scaleway-sdk-go v1.0.0-beta.29 // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/signalfx/sapm-proto v0.17.0 // indirect github.com/sigstore/rekor v1.2.2 // indirect github.com/skeema/knownhosts v1.2.2 // indirect @@ -1064,7 +1062,7 @@ replace github.com/vishvananda/netlink => github.com/DataDog/netlink v1.0.1-0.20 // Pull in replacements needed by upstream Trivy replace ( // Maps to Trivy fork https://github.com/DataDog/trivy/commits/use-fs-main-dd/ - github.com/aquasecurity/trivy => github.com/DataDog/trivy v0.0.0-20241126101205-8517f9b946f4 + github.com/aquasecurity/trivy => github.com/DataDog/trivy v0.0.0-20241216135157-95e0e96002ee github.com/saracen/walker => github.com/DataDog/walker v0.0.0-20230418153152-7f29bb2dc950 // testcontainers-go has a bug with versions v0.25.0 and v0.26.0 // ref: https://github.com/testcontainers/testcontainers-go/issues/1782 diff --git a/go.sum b/go.sum index 99aabf21db82e..26375333ef0cf 100644 --- a/go.sum +++ b/go.sum @@ -128,10 +128,10 @@ github.com/DataDog/datadog-agent/comp/core/log v0.56.2/go.mod h1:ivJ/RMZjTNkoPPN github.com/DataDog/datadog-api-client-go/v2 v2.33.0 h1:OI6kDnJeQmkjfGzxmP0XUQUxMD4tp6oAPXnnJ4VpgUM= github.com/DataDog/datadog-api-client-go/v2 v2.33.0/go.mod h1:d3tOEgUd2kfsr9uuHQdY+nXrWp4uikgTgVCPdKNK30U= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -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/datadog-operator v0.7.1-0.20241024104907-734366f3c0d1 h1:17MXCuo1IacLeVzdmwV+92ANVrXkquObm0yxjen1eJ0= -github.com/DataDog/datadog-operator v0.7.1-0.20241024104907-734366f3c0d1/go.mod h1:5Xp66c0HGadP85lOQtb6oVuSvuL5ZSSowQM58hNtTi8= +github.com/DataDog/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= +github.com/DataDog/datadog-operator v1.11.0-rc.2 h1:4tMZlxbYE0WEpRYAhoqEe8nLP67C/PDq7utJJcD8RM8= +github.com/DataDog/datadog-operator v1.11.0-rc.2/go.mod h1:mD+3PWR0wOSVJGaXjkpzsYEK/7PhqjOipx2usgfsxM0= 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/dd-trace-go/v2 v2.0.0-beta.11 h1:6vwU//TjBIghQKMgIP9UyIRhN/LWS1y8tYzvRnu8JZw= @@ -174,8 +174,8 @@ github.com/DataDog/opentelemetry-mapping-go/pkg/quantile v0.22.0 h1:63SzQz9Ab8XJ github.com/DataDog/opentelemetry-mapping-go/pkg/quantile v0.22.0/go.mod h1:E/PY/aQ6S/N5hBPHXZRGmovs5b1BSi4RHGNcB4yP/Z0= github.com/DataDog/sketches-go v1.4.6 h1:acd5fb+QdUzGrosfNLwrIhqyrbMORpvBy7mE+vHlT3I= github.com/DataDog/sketches-go v1.4.6/go.mod h1:7Y8GN8Jf66DLyDhc94zuWA3uHEt/7ttt8jHOBWWrSOg= -github.com/DataDog/trivy v0.0.0-20241126101205-8517f9b946f4 h1:UVL5oU/8o0JhEv8Js6qxJgiqeV+PzPw/aldojyexS/U= -github.com/DataDog/trivy v0.0.0-20241126101205-8517f9b946f4/go.mod h1:hLiUAm3v175M5jWbq34TdGmX6mvHIJY7FMuZ3wBugtw= +github.com/DataDog/trivy v0.0.0-20241216135157-95e0e96002ee h1:taj22FDHhWs9QkVJypOYMhdgJTnTb5y4SHiW7YcJJms= +github.com/DataDog/trivy v0.0.0-20241216135157-95e0e96002ee/go.mod h1:hv4bqUzcHXSfVft8E9DUlu9d+szHrxYSh+WykZU70Dk= github.com/DataDog/viper v1.14.0 h1:dIjTe/uJiah+QFqFZ+MXeqgmUvWhg37l37ZxFWxr3is= github.com/DataDog/viper v1.14.0/go.mod h1:wDdUVJ2SHaMaPrCZrlRCObwkubsX8j5sme3LaR/SGTc= github.com/DataDog/walker v0.0.0-20230418153152-7f29bb2dc950 h1:2imDajw3V85w1iqHsuXN+hUBZQVF+r9eME8tsPq/HpA= @@ -241,16 +241,16 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agnivade/levenshtein v1.2.0 h1:U9L4IOT0Y3i0TIlUIDJ7rVUziKi/zPbrJGaFrtYH3SY= github.com/agnivade/levenshtein v1.2.0/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= -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/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= +github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/jsonschema v0.0.0-20210918223802-a1d3f4b43d7b/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60= github.com/alecthomas/participle v0.7.1 h1:2bN7reTw//5f0cugJcTOnY/NYZcWQOaajW+BwZB5xWs= github.com/alecthomas/participle v0.7.1/go.mod h1:HfdmEuwvr12HXQN44HPWXR0lHmVolVYe4dyL6lQ3duY= 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.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= -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/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= +github.com/alecthomas/repr v0.4.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= @@ -321,24 +321,24 @@ github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2z github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= -github.com/aws/aws-sdk-go-v2 v1.32.5 h1:U8vdWJuY7ruAkzaOdD7guwJjD06YSKmnKCJs7s3IkIo= -github.com/aws/aws-sdk-go-v2 v1.32.5/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4= +github.com/aws/aws-sdk-go-v2 v1.32.6/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14/go.mod h1:9NCTOURS8OpxvoAVHq79LK81/zC78hfRWFn+aL0SPcY= github.com/aws/aws-sdk-go-v2/config v1.19.0/go.mod h1:ZwDUgFnQgsazQTnWfeLWk5GjeqTQTL8lMkoE1UXzxdE= -github.com/aws/aws-sdk-go-v2/config v1.28.5 h1:Za41twdCXbuyyWv9LndXxZZv3QhTG1DinqlFsSuvtI0= -github.com/aws/aws-sdk-go-v2/config v1.28.5/go.mod h1:4VsPbHP8JdcdUDmbTVgNL/8w9SqOkM5jyY8ljIxLO3o= +github.com/aws/aws-sdk-go-v2/config v1.28.6 h1:D89IKtGrs/I3QXOLNTH93NJYtDhm8SYa9Q5CsPShmyo= +github.com/aws/aws-sdk-go-v2/config v1.28.6/go.mod h1:GDzxJ5wyyFSCoLkS+UhGB0dArhb9mI+Co4dHtoTxbko= github.com/aws/aws-sdk-go-v2/credentials v1.13.43/go.mod h1:zWJBz1Yf1ZtX5NGax9ZdNjhhI4rgjfgsyk6vTY1yfVg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.46 h1:AU7RcriIo2lXjUfHFnFKYsLCwgbz1E7Mm95ieIRDNUg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.46/go.mod h1:1FmYyLGL08KQXQ6mcTlifyFXfJVCNJTVGuQP4m0d/UA= +github.com/aws/aws-sdk-go-v2/credentials v1.17.47 h1:48bA+3/fCdi2yAwVt+3COvmatZ6jUDNkDTIsqDiMUdw= +github.com/aws/aws-sdk-go-v2/credentials v1.17.47/go.mod h1:+KdckOejLW3Ks3b0E3b5rHsr2f9yuORBum0WPnE5o5w= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13/go.mod h1:f/Ib/qYjhV2/qdsf79H3QP/eRE4AkVyEf6sk7XfZ1tg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 h1:sDSXIrlsFSFJtWKLQS4PUWRvrT580rrnuLydJrCQ/yA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20/go.mod h1:WZ/c+w0ofps+/OUqMwWgnfrgzZH1DZO1RIkktICsqnY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 h1:AmoU1pziydclFT/xRV+xXE/Vb8fttJCLRPv8oAkprc0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21/go.mod h1:AjUdLYe4Tgs6kpH4Bv7uMZo7pottoyHMn4eTcIcneaY= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 h1:4usbeaes3yJnCFC7kfeyhkdkPtoRYPa/hTmCqMpKpLI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24/go.mod h1:5CI1JemjVwde8m2WG3cz23qHKPOxbpkq0HaoreEgLIY= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 h1:N1zsICrQglfzaBnrfM0Ys00860C+QFwu6u/5+LomP+o= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24/go.mod h1:dCn9HbJ8+K31i8IQ8EWmWj0EiIk0+vKiHNMxTTYveAg= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= @@ -347,17 +347,13 @@ github.com/aws/aws-sdk-go-v2/service/ebs v1.27.0 h1:4zuGQITyy9O+GlSGcs+aUz3+Smlv github.com/aws/aws-sdk-go-v2/service/ebs v1.27.0/go.mod h1:T0t6q7wBD2P11xwVcc6GvwmuDT3i6ZJgZ+13ziQUUnA= github.com/aws/aws-sdk-go-v2/service/ec2 v1.190.0 h1:k97fGog9Tl0woxTiSIHN14Qs5ehqK6GXejUwkhJYyL0= github.com/aws/aws-sdk-go-v2/service/ec2 v1.190.0/go.mod h1:mzj8EEjIHSN2oZRXiw1Dd+uB4HZTl7hC8nBzX9IZMWw= -github.com/aws/aws-sdk-go-v2/service/ecr v1.36.2 h1:VDQaVwGOokbd3VUbHF+wupiffdrbAZPdQnr5XZMJqrs= -github.com/aws/aws-sdk-go-v2/service/ecr v1.36.2/go.mod h1:lvUlMghKYmSxSfv0vU7pdU/8jSY+s0zpG8xXhaGKCw0= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.0 h1:k4ykVLeoO2JohTC7BIfIqWYvmf8HcirbWHf8Zn0SPpI= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.0/go.mod h1:vJMqaxbvogPsWZYEInEwK82EBwCfc7cnE/5BEqnvTYI= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.15/go.mod h1:26SQUPcTNgV1Tapwdt4a1rOsYRsnBsJHLMPoxK2b0d8= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38/go.mod h1:epIZoRSSbRIwLPJU5F+OldHhwZPBdpDeQkRdCeY3+00= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 h1:wtpJ4zcwrSbwhECWQoI/g6WM9zqCcSpHDJIWSbMLOu4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5/go.mod h1:qu/W9HXQbbQ4+1+JcZp0ZNPV31ym537ZJN+fiS7Ti8E= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 h1:50+XsN70RS7dwJ2CkVNXzj7U2L1HKP8nqTd3XWEXBN4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6/go.mod h1:WqgLmwY7so32kG01zD8CPTJWVWM+TzJoOVHwTg4aPug= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6/go.mod h1:lnc2taBsR9nTlz9meD+lhFZZ9EWY712QHrRflWpTcOA= github.com/aws/aws-sdk-go-v2/service/kms v1.37.6 h1:CZImQdb1QbU9sGgJ9IswhVkxAcjkkD1eQTMA1KHWk+E= github.com/aws/aws-sdk-go-v2/service/kms v1.37.6/go.mod h1:YJDdlK0zsyxVBxGU48AR/Mi8DMrGdc1E3Yij4fNrONA= @@ -367,19 +363,17 @@ github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2/go.mod h1:Zjfqt7KhQK+PO1bbOsFNzK github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.6 h1:1KDMKvOKNrpD667ORbZ/+4OgvUoaok1gg/MLzrHF9fw= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.6/go.mod h1:DmtyfCfONhOyVAJ6ZMTrDSFIeyCBlEO93Qkfhxwbxu0= github.com/aws/aws-sdk-go-v2/service/sso v1.15.2/go.mod h1:gsL4keucRCgW+xA85ALBpRFfdSLH4kHOVSnLMSuBECo= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 h1:3zu537oLmsPfDMyjnUS2g+F2vITgy5pB74tHI+JBNoM= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.6/go.mod h1:WJSZH2ZvepM6t6jwu4w/Z45Eoi75lPN7DcydSRtJg6Y= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 h1:rLnYAfXQ3YAccocshIH5mzNNwZBkBo+bP6EhIxak6Hw= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.7/go.mod h1:ZHtuQJ6t9A/+YDuxOLnbryAmITtr8UysSny3qcyvJTc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3/go.mod h1:a7bHA82fyUXOm+ZSWKU6PIoBxrjSprdLoM8xPYvzYVg= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 h1:K0OQAsDywb0ltlFrZm0JHPY3yZp/S9OaoLU33S7vPS8= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5/go.mod h1:ORITg+fyuMoeiQFiVGoqB3OydVTLkClw/ljbblMq6Cc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 h1:JnhTZR3PiYDNKlXy50/pNeix9aGMo6lLpXwJ1mw8MD4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6/go.mod h1:URronUEGfXZN1VpdktPSD1EkAL9mfrV+2F4sjH38qOY= github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 h1:6SZUVRQNvExYlMLbHdlKB48x0fLbc2iVROyaNEwBHbU= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.1/go.mod h1:GqWyYCwLXnlUB1lOAXQyNSPqPLQJvmo8J0DWBzp9mtg= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 h1:s4074ZO1Hk8qv65GqNXqDjmkf4HSQqJukaLuuW0TpDA= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.2/go.mod h1:mVggCnIWoM09jP71Wh+ea7+5gAp53q+49wDFs1SW5z8= github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20240409155312-26d1ea377073 h1:9XtHL16FtbSDAedz9AnboTDqfKacYqc5BmwtUxzwwD8= -github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20240409155312-26d1ea377073/go.mod h1:2nlYPkG0rFrODp6R875pk/kOnB8Ivj3+onhzk2mO57g= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps= @@ -552,12 +546,12 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr 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 v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= -github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.4.0+incompatible h1:/nJzWkcI1MDMN+U+px/YXnQWJqnu4J+QKGTfD6ptiTc= +github.com/docker/cli v27.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= -github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.4.0+incompatible h1:I9z7sQ5qyzO0BfAb9IMOawRkAGxhYsidKiTMcm0DU+A= +github.com/docker/docker v27.4.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo= github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= @@ -848,8 +842,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/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/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= @@ -977,8 +969,8 @@ github.com/hashicorp/nomad/api v0.0.0-20240717122358-3d93bd3778f3 h1:fgVfQ4AC1av github.com/hashicorp/nomad/api v0.0.0-20240717122358-3d93bd3778f3/go.mod h1:svtxn6QnrQ69P23VvIWMR34tg3vmwLz4UdUzm1dSCgE= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/hetznercloud/hcloud-go/v2 v2.10.2 h1:9gyTUPhfNbfbS40Spgij5mV5k37bOZgt8iHKCbfGs5I= github.com/hetznercloud/hcloud-go/v2 v2.10.2/go.mod h1:xQ+8KhIS62W0D78Dpi57jsufWh844gUw1az5OUvaeq8= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= @@ -1612,7 +1604,6 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= @@ -2666,13 +2657,13 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.5.1 h1:4bH5o3b5ZULQ4UrBmP+63W9r7qIkqJClEA9ko5YKx+I= honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= -k8s.io/api v0.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8= -k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE= +k8s.io/api v0.31.4 h1:I2QNzitPVsPeLQvexMEsj945QumYraqv9m74isPDKhM= +k8s.io/api v0.31.4/go.mod h1:d+7vgXLvmcdT1BCo79VEgJxHHryww3V5np2OYTr6jdw= k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0= k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM= k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= -k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4= -k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/apimachinery v0.31.4 h1:8xjE2C4CzhYVm9DGf60yohpNUh5AEBnPxCryPBECmlM= +k8s.io/apimachinery v0.31.4/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/apiserver v0.31.2 h1:VUzOEUGRCDi6kX1OyQ801m4A7AUPglpsmGvdsekmcI4= k8s.io/apiserver v0.31.2/go.mod h1:o3nKZR7lPlJqkU5I3Ove+Zx3JuoFjQobGX1Gctw6XuE= k8s.io/autoscaler/vertical-pod-autoscaler v0.13.0 h1:pH6AsxeBZcyX6KBqcnl7SPIJqbN1d59RrEBuIE6Rq6c= diff --git a/go.work b/go.work index 880b236237204..c7c6ebf27d3ff 100644 --- a/go.work +++ b/go.work @@ -17,6 +17,7 @@ use ( comp/core/secrets comp/core/status comp/core/status/statusimpl + comp/core/tagger/origindetection comp/core/tagger/tags comp/core/tagger/types comp/core/tagger/utils diff --git a/internal/tools/go.mod b/internal/tools/go.mod index e2a60b08d8971..79be9ca61a043 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -32,7 +32,7 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect github.com/ProtonMail/go-crypto v1.1.0-alpha.0 // indirect - github.com/alecthomas/assert/v2 v2.3.0 // indirect + github.com/alecthomas/assert/v2 v2.6.0 // indirect github.com/alecthomas/go-check-sumtype v0.1.4 // indirect github.com/alexkohler/nakedret/v2 v2.0.4 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect diff --git a/internal/tools/go.sum b/internal/tools/go.sum index f5f1fb317b59a..2bf7f8b759bd6 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -38,12 +38,12 @@ github.com/aclements/go-gg v0.0.0-20170118225347-6dbb4e4fefb0/go.mod h1:55qNq4vc github.com/aclements/go-moremath v0.0.0-20161014184102-0ff62e0875ff/go.mod h1:idZL3yvz4kzx1dsBOAC+oYv6L92P1oFEhUXUB1A/lwQ= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -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/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= +github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/go-check-sumtype v0.1.4 h1:WCvlB3l5Vq5dZQTFmodqL2g68uHiSwwlWcT5a2FGK0c= github.com/alecthomas/go-check-sumtype v0.1.4/go.mod h1:WyYPfhfkdhyrdaligV6svFopZV8Lqdzn5pyVBaV6jhQ= -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/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= +github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alexkohler/nakedret/v2 v2.0.4 h1:yZuKmjqGi0pSmjGpOC016LtPJysIL0WEUiaXW5SUnNg= github.com/alexkohler/nakedret/v2 v2.0.4/go.mod h1:bF5i0zF2Wo2o4X4USt9ntUWve6JbFv02Ff4vlkmS/VU= github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= diff --git a/modules.yml b/modules.yml index f9550b4b82943..291db46bc53cc 100644 --- a/modules.yml +++ b/modules.yml @@ -35,6 +35,7 @@ modules: comp/core/status: used_by_otel: true comp/core/status/statusimpl: default + comp/core/tagger/origindetection: default comp/core/tagger/tags: used_by_otel: true comp/core/tagger/types: diff --git a/omnibus/config/software/openscap.rb b/omnibus/config/software/openscap.rb index e97250467e2a2..3e8e08d71990d 100644 --- a/omnibus/config/software/openscap.rb +++ b/omnibus/config/software/openscap.rb @@ -4,12 +4,12 @@ # Copyright 2016-present Datadog, Inc. name 'openscap' -default_version '1.3.10' +default_version '1.4.0' license "LGPL-3.0-or-later" license_file "COPYING" -version("1.3.10") { source sha256: "0d023ff3fbdec617768ea5977fd3bb6702dfef4ae595da9a5bbc6ecc6ac9e575" } +version("1.4.0") { source sha256: "b64f3709f0e072262708212d56897c419abdd2dc618273a363bc0497c6b4ba0b" } ship_source_offer true diff --git a/omnibus/config/software/python3.rb b/omnibus/config/software/python3.rb index 7f8fd8e8f4219..2fe37a032fc24 100644 --- a/omnibus/config/software/python3.rb +++ b/omnibus/config/software/python3.rb @@ -54,10 +54,12 @@ # Don't forward CC and CXX to python extensions Makefile, it's quite unlikely that any non default # compiler we use would end up being available in the system/docker image used by customers - if linux_target? + if linux_target? && ENV["CC"] command "sed -i \"s/^CC=[[:space:]]*${CC}/CC=gcc/\" #{install_dir}/embedded/lib/python#{major}.#{minor}/config-3.12-*-linux-gnu/Makefile", :env => env - command "sed -i \"s/^CXX=[[:space:]]*${CXX}/CC=g++/\" #{install_dir}/embedded/lib/python#{major}.#{minor}/config-3.12-*-linux-gnu/Makefile", :env => env command "sed -i \"s/${CC}/gcc/g\" #{install_dir}/embedded/lib/python#{major}.#{minor}/_sysconfigdata__linux_*-linux-gnu.py", :env => env + end + if linux_target? && ENV["CXX"] + command "sed -i \"s/^CXX=[[:space:]]*${CXX}/CC=g++/\" #{install_dir}/embedded/lib/python#{major}.#{minor}/config-3.12-*-linux-gnu/Makefile", :env => env command "sed -i \"s/${CXX}/g++/g\" #{install_dir}/embedded/lib/python#{major}.#{minor}/_sysconfigdata__linux_*-linux-gnu.py", :env => env end delete "#{install_dir}/embedded/lib/python#{major}.#{minor}/test" @@ -79,7 +81,6 @@ license "Python-2.0" command "XCOPY /YEHIR *.* \"#{windows_safe_path(python_3_embedded)}\"" - command "copy /y \"#{windows_safe_path(vcrt140_root)}\\*.dll\" \"#{windows_safe_path(python_3_embedded)}\"" # Install pip python = "#{windows_safe_path(python_3_embedded)}\\python.exe" diff --git a/omnibus/config/software/vc_redist_14.rb b/omnibus/config/software/vc_redist_14.rb index ecc8067943f96..226a1145bb993 100644 --- a/omnibus/config/software/vc_redist_14.rb +++ b/omnibus/config/software/vc_redist_14.rb @@ -23,5 +23,5 @@ else source_msm = "Microsoft_VC141_CRT_x64.msm" end - command "powershell -C \"#{windows_safe_path(script_root)} -file #{source_msm} -targetDir .\\expanded\"" + command "powershell -C \"#{windows_safe_path(script_root)} -file #{source_msm} -targetDir \"#{windows_safe_path(python_3_embedded)}\"\"" end diff --git a/pkg/api/go.mod b/pkg/api/go.mod index c3499a2fb94c2..ab50796cf7a58 100644 --- a/pkg/api/go.mod +++ b/pkg/api/go.mod @@ -76,7 +76,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/pkg/api/go.sum b/pkg/api/go.sum index 9694f5d5e2355..dd16364891695 100644 --- a/pkg/api/go.sum +++ b/pkg/api/go.sum @@ -87,8 +87,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/clusteragent/admission/controllers/webhook/config.go b/pkg/clusteragent/admission/controllers/webhook/config.go index 90cec93a8d8db..4f5e549434557 100644 --- a/pkg/clusteragent/admission/controllers/webhook/config.go +++ b/pkg/clusteragent/admission/controllers/webhook/config.go @@ -13,7 +13,7 @@ import ( "fmt" "strings" - pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" + "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/pkg/util/kubernetes/apiserver/common" ) @@ -36,21 +36,21 @@ type Config struct { } // NewConfig creates a webhook controller configuration -func NewConfig(admissionV1Enabled, namespaceSelectorEnabled, matchConditionsSupported bool) Config { +func NewConfig(admissionV1Enabled, namespaceSelectorEnabled, matchConditionsSupported bool, datadogConfig config.Component) Config { return Config{ - webhookName: pkgconfigsetup.Datadog().GetString("admission_controller.webhook_name"), - secretName: pkgconfigsetup.Datadog().GetString("admission_controller.certificate.secret_name"), - validationEnabled: pkgconfigsetup.Datadog().GetBool("admission_controller.validation.enabled"), - mutationEnabled: pkgconfigsetup.Datadog().GetBool("admission_controller.mutation.enabled"), + webhookName: datadogConfig.GetString("admission_controller.webhook_name"), + secretName: datadogConfig.GetString("admission_controller.certificate.secret_name"), + validationEnabled: datadogConfig.GetBool("admission_controller.validation.enabled"), + mutationEnabled: datadogConfig.GetBool("admission_controller.mutation.enabled"), namespace: common.GetResourcesNamespace(), admissionV1Enabled: admissionV1Enabled, namespaceSelectorEnabled: namespaceSelectorEnabled, matchConditionsSupported: matchConditionsSupported, - svcName: pkgconfigsetup.Datadog().GetString("admission_controller.service_name"), + svcName: datadogConfig.GetString("admission_controller.service_name"), svcPort: int32(443), - timeout: pkgconfigsetup.Datadog().GetInt32("admission_controller.timeout_seconds"), - failurePolicy: pkgconfigsetup.Datadog().GetString("admission_controller.failure_policy"), - reinvocationPolicy: pkgconfigsetup.Datadog().GetString("admission_controller.reinvocation_policy"), + timeout: datadogConfig.GetInt32("admission_controller.timeout_seconds"), + failurePolicy: datadogConfig.GetString("admission_controller.failure_policy"), + reinvocationPolicy: datadogConfig.GetString("admission_controller.reinvocation_policy"), } } diff --git a/pkg/clusteragent/admission/controllers/webhook/controller_base.go b/pkg/clusteragent/admission/controllers/webhook/controller_base.go index 79114dac7397f..5505337ba5838 100644 --- a/pkg/clusteragent/admission/controllers/webhook/controller_base.go +++ b/pkg/clusteragent/admission/controllers/webhook/controller_base.go @@ -35,7 +35,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/clusteragent/admission/mutate/tagsfromlabels" "github.com/DataDog/datadog-agent/pkg/clusteragent/admission/validate/kubernetesadmissionevents" "github.com/DataDog/datadog-agent/pkg/clusteragent/autoscaling/workload" - pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" "github.com/DataDog/datadog-agent/pkg/util/log" ) @@ -125,7 +124,7 @@ func (c *controllerBase) generateWebhooks(wmeta workloadmeta.Component, pa workl configWebhook.NewWebhook(wmeta, injectionFilter, datadogConfig), tagsfromlabels.NewWebhook(wmeta, datadogConfig, injectionFilter), agentsidecar.NewWebhook(datadogConfig), - autoscaling.NewWebhook(pa), + autoscaling.NewWebhook(pa, datadogConfig), } webhooks = append(webhooks, mutatingWebhooks...) @@ -137,7 +136,7 @@ func (c *controllerBase) generateWebhooks(wmeta workloadmeta.Component, pa workl log.Errorf("failed to register APM Instrumentation webhook: %v", err) } - isCWSInstrumentationEnabled := pkgconfigsetup.Datadog().GetBool("admission_controller.cws_instrumentation.enabled") + isCWSInstrumentationEnabled := datadogConfig.GetBool("admission_controller.cws_instrumentation.enabled") if isCWSInstrumentationEnabled { cws, err := cwsinstrumentation.NewCWSInstrumentation(wmeta, datadogConfig) if err == nil { diff --git a/pkg/clusteragent/admission/controllers/webhook/controller_base_test.go b/pkg/clusteragent/admission/controllers/webhook/controller_base_test.go index c202f1ab38f25..d5612b96c74e0 100644 --- a/pkg/clusteragent/admission/controllers/webhook/controller_base_test.go +++ b/pkg/clusteragent/admission/controllers/webhook/controller_base_test.go @@ -36,7 +36,7 @@ func TestNewController(t *testing.T) { factory.Admissionregistration(), func() bool { return true }, make(chan struct{}), - v1Cfg, + getV1Cfg(t), wmeta, nil, datadogConfig, @@ -53,7 +53,7 @@ func TestNewController(t *testing.T) { factory.Admissionregistration(), func() bool { return true }, make(chan struct{}), - v1beta1Cfg, + getV1beta1Cfg(t), wmeta, nil, datadogConfig, diff --git a/pkg/clusteragent/admission/controllers/webhook/controller_v1_test.go b/pkg/clusteragent/admission/controllers/webhook/controller_v1_test.go index aa2a3efc4e68e..6a52255c42e29 100644 --- a/pkg/clusteragent/admission/controllers/webhook/controller_v1_test.go +++ b/pkg/clusteragent/admission/controllers/webhook/controller_v1_test.go @@ -41,10 +41,11 @@ const ( tick = 50 * time.Millisecond ) -var v1Cfg = NewConfig(true, false, false) +func getV1Cfg(t *testing.T) Config { return NewConfig(true, false, false, configComp.NewMock(t)) } func TestSecretNotFoundV1(t *testing.T) { f := newFixtureV1(t) + v1Cfg := getV1Cfg(t) stopCh := make(chan struct{}) defer close(stopCh) @@ -63,6 +64,7 @@ func TestSecretNotFoundV1(t *testing.T) { func TestCreateWebhookV1(t *testing.T) { f := newFixtureV1(t) + v1Cfg := getV1Cfg(t) data, err := certificate.GenerateSecretData(time.Now(), time.Now().Add(365*24*time.Hour), []string{"my.svc.dns"}) if err != nil { @@ -97,6 +99,7 @@ func TestCreateWebhookV1(t *testing.T) { func TestUpdateOutdatedWebhookV1(t *testing.T) { f := newFixtureV1(t) + v1Cfg := getV1Cfg(t) data, err := certificate.GenerateSecretData(time.Now(), time.Now().Add(365*24*time.Hour), []string{"my.svc.dns"}) if err != nil { @@ -166,7 +169,7 @@ func TestAdmissionControllerFailureModeV1(t *testing.T) { for _, value := range []string{"Ignore", "ignore", "BadVal", ""} { mockConfig.SetWithoutSource("admission_controller.failure_policy", value) - c.config = NewConfig(true, false, false) + c.config = NewConfig(true, false, false, mockConfig) validatingWebhookSkeleton := c.getValidatingWebhookSkeleton("foo", "/bar", []admiv1.OperationType{admiv1.Create}, map[string][]string{"": {"pods"}}, nil, nil, nil) assert.Equal(t, admiv1.Ignore, *validatingWebhookSkeleton.FailurePolicy) @@ -176,7 +179,7 @@ func TestAdmissionControllerFailureModeV1(t *testing.T) { for _, value := range []string{"Fail", "fail"} { mockConfig.SetWithoutSource("admission_controller.failure_policy", value) - c.config = NewConfig(true, false, false) + c.config = NewConfig(true, false, false, mockConfig) validatingWebhookSkeleton := c.getValidatingWebhookSkeleton("foo", "/bar", []admiv1.OperationType{admiv1.Create}, map[string][]string{"": {"pods"}}, nil, nil, nil) assert.Equal(t, admiv1.Fail, *validatingWebhookSkeleton.FailurePolicy) @@ -192,7 +195,7 @@ func TestAdmissionControllerReinvocationPolicyV1(t *testing.T) { for _, value := range []string{"IfNeeded", "ifneeded", "Never", "never", "wrong", ""} { mockConfig.SetWithoutSource("admission_controller.reinvocationpolicy", value) - c.config = NewConfig(true, false, false) + c.config = NewConfig(true, false, false, mockConfig) mutatingWebhookSkeleton := c.getMutatingWebhookSkeleton("foo", "/bar", []admiv1.OperationType{admiv1.Create}, map[string][]string{"": {"pods"}}, nil, nil, nil) assert.Equal(t, admiv1.IfNeededReinvocationPolicy, *mutatingWebhookSkeleton.ReinvocationPolicy) @@ -241,7 +244,7 @@ func TestGenerateTemplatesV1(t *testing.T) { tests := []struct { name string setupConfig func(model.Config) - configFunc func() Config + configFunc func(model.Config) Config want func() []admiv1.MutatingWebhook }{ { @@ -253,7 +256,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhook := webhook("datadog.webhook.agent.config", "/injectconfig", &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ @@ -276,7 +279,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhook := webhook("datadog.webhook.agent.config", "/injectconfig", &metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -295,7 +298,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhook := webhook("datadog.webhook.standard.tags", "/injecttags", &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ @@ -318,7 +321,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhook := webhook("datadog.webhook.standard.tags", "/injecttags", &metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -337,7 +340,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", true) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhook := webhook("datadog.webhook.lib.injection", "/injectlib", &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ @@ -360,7 +363,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", true) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhook := webhook("datadog.webhook.lib.injection", "/injectlib", &metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -378,7 +381,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhookConfig := webhook("datadog.webhook.agent.config", "/injectconfig", &metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -402,7 +405,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhookConfig := webhook("datadog.webhook.agent.config", "/injectconfig", &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ @@ -435,7 +438,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.namespace_selector_fallback", true) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhookConfig := webhook("datadog.webhook.agent.config", "/injectconfig", nil, &metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -461,7 +464,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.inject_tags.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhook := webhook( "datadog.webhook.agent.config", @@ -511,7 +514,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { webhook := webhook( "datadog.webhook.agent.config", @@ -559,7 +562,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.mutate_unlabelled", true) mockConfig.SetWithoutSource("cluster_agent.service_account_name", "datadog-cluster-agent") }, - configFunc: func() Config { return NewConfig(true, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.cws.pod.instrumentation", @@ -602,7 +605,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.mutate_unlabelled", false) mockConfig.SetWithoutSource("cluster_agent.service_account_name", "datadog-cluster-agent") }, - configFunc: func() Config { return NewConfig(true, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, false, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.cws.pod.instrumentation", @@ -641,7 +644,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.mutate_unlabelled", true) mockConfig.SetWithoutSource("cluster_agent.service_account_name", "datadog-cluster-agent") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.cws.pod.instrumentation", @@ -684,7 +687,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.mutate_unlabelled", false) mockConfig.SetWithoutSource("cluster_agent.service_account_name", "datadog-cluster-agent") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.cws.pod.instrumentation", @@ -726,7 +729,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "misconfigured") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { return []admiv1.MutatingWebhook{} }, @@ -746,7 +749,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.agent.sidecar", @@ -779,7 +782,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { return []admiv1.MutatingWebhook{} }, @@ -799,7 +802,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { return []admiv1.MutatingWebhook{} }, @@ -819,7 +822,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[{\"NamespaceSelector\": {\"MatchLabels\": {\"labelKey\": \"labelVal\"}}}]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.agent.sidecar", @@ -850,7 +853,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[{\"ObjectSelector\": {\"MatchLabels\": {\"labelKey\": \"labelVal\"}}}]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { return []admiv1.MutatingWebhook{} }, @@ -870,7 +873,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[{\"ObjectSelector\": {\"MatchLabels\": {\"labelKey\": \"labelVal\"}}}]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.agent.sidecar", @@ -899,7 +902,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[{\"ObjectSelector\": {\"MatchLabels\": {\"labelKey1\": \"labelVal1\"}}, \"NamespaceSelector\": {\"MatchLabels\": {\"labelKey2\": \"labelVal2\"}}}]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.agent.sidecar", @@ -928,7 +931,7 @@ func TestGenerateTemplatesV1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[{\"NamespaceSelector\": {\"MatchLabels\":{\"labelKey1\": \"labelVal1\"}}} , {\"ObjectSelector\": {\"MatchLabels\": {\"labelKey2\": \"labelVal2\"}}}]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1.MutatingWebhook { return []admiv1.MutatingWebhook{} }, @@ -947,7 +950,7 @@ func TestGenerateTemplatesV1(t *testing.T) { tt.setupConfig(mockConfig) c := &ControllerV1{} - c.config = tt.configFunc() + c.config = tt.configFunc(mockConfig) c.webhooks = c.generateWebhooks(wmeta, nil, mockConfig, nil) c.generateTemplates() @@ -1051,7 +1054,7 @@ func TestGetValidatingWebhookSkeletonV1(t *testing.T) { } c := &ControllerV1{} - c.config = NewConfig(false, tt.namespaceSelector, false) + c.config = NewConfig(false, tt.namespaceSelector, false, mockConfig) nsSelector, objSelector := common.DefaultLabelSelectors(tt.namespaceSelector) @@ -1157,7 +1160,7 @@ func TestGetMutatingWebhookSkeletonV1(t *testing.T) { } c := &ControllerV1{} - c.config = NewConfig(false, tt.namespaceSelector, false) + c.config = NewConfig(false, tt.namespaceSelector, false, mockConfig) nsSelector, objSelector := common.DefaultLabelSelectors(tt.namespaceSelector) @@ -1188,7 +1191,7 @@ func (f *fixtureV1) createController() (*ControllerV1, informers.SharedInformerF factory.Admissionregistration().V1().MutatingWebhookConfigurations(), func() bool { return true }, make(chan struct{}), - v1Cfg, + getV1Cfg(f.t), wmeta, nil, datadogConfig, diff --git a/pkg/clusteragent/admission/controllers/webhook/controller_v1beta1_test.go b/pkg/clusteragent/admission/controllers/webhook/controller_v1beta1_test.go index bd5daf906a2fb..62fa7713cd809 100644 --- a/pkg/clusteragent/admission/controllers/webhook/controller_v1beta1_test.go +++ b/pkg/clusteragent/admission/controllers/webhook/controller_v1beta1_test.go @@ -36,10 +36,11 @@ import ( "github.com/DataDog/datadog-agent/pkg/util/kubernetes/certificate" ) -var v1beta1Cfg = NewConfig(false, false, false) +func getV1beta1Cfg(t *testing.T) Config { return NewConfig(false, false, false, configComp.NewMock(t)) } func TestSecretNotFoundV1beta1(t *testing.T) { f := newFixtureV1beta1(t) + v1beta1Cfg := getV1beta1Cfg(t) stopCh := make(chan struct{}) defer close(stopCh) @@ -58,6 +59,7 @@ func TestSecretNotFoundV1beta1(t *testing.T) { func TestCreateWebhookV1beta1(t *testing.T) { f := newFixtureV1beta1(t) + v1beta1Cfg := getV1beta1Cfg(t) data, err := certificate.GenerateSecretData(time.Now(), time.Now().Add(365*24*time.Hour), []string{"my.svc.dns"}) if err != nil { @@ -92,6 +94,8 @@ func TestCreateWebhookV1beta1(t *testing.T) { func TestUpdateOutdatedWebhookV1beta1(t *testing.T) { f := newFixtureV1beta1(t) + v1Cfg := getV1Cfg(t) + v1beta1Cfg := getV1beta1Cfg(t) data, err := certificate.GenerateSecretData(time.Now(), time.Now().Add(365*24*time.Hour), []string{"my.svc.dns"}) if err != nil { @@ -161,7 +165,7 @@ func TestAdmissionControllerFailureModeV1beta1(t *testing.T) { for _, value := range []string{"Ignore", "ignore", "BadVal", ""} { mockConfig.SetWithoutSource("admission_controller.failure_policy", value) - c.config = NewConfig(true, false, false) + c.config = NewConfig(true, false, false, mockConfig) validatingWebhookSkeleton := c.getValidatingWebhookSkeleton("foo", "/bar", []admiv1beta1.OperationType{admiv1beta1.Create}, map[string][]string{"": {"pods"}}, nil, nil, nil) assert.Equal(t, admiv1beta1.Ignore, *validatingWebhookSkeleton.FailurePolicy) @@ -171,7 +175,7 @@ func TestAdmissionControllerFailureModeV1beta1(t *testing.T) { for _, value := range []string{"Fail", "fail"} { mockConfig.SetWithoutSource("admission_controller.failure_policy", value) - c.config = NewConfig(true, false, false) + c.config = NewConfig(true, false, false, mockConfig) validatingWebhookSkeleton := c.getValidatingWebhookSkeleton("foo", "/bar", []admiv1beta1.OperationType{admiv1beta1.Create}, map[string][]string{"": {"pods"}}, nil, nil, nil) assert.Equal(t, admiv1beta1.Fail, *validatingWebhookSkeleton.FailurePolicy) @@ -187,7 +191,7 @@ func TestAdmissionControllerReinvocationPolicyV1beta1(t *testing.T) { for _, value := range []string{"IfNeeded", "ifneeded", "Never", "never", "wrong", ""} { mockConfig.SetWithoutSource("admission_controller.reinvocationpolicy", value) - c.config = NewConfig(true, false, false) + c.config = NewConfig(true, false, false, mockConfig) mutatingWebhookSkeleton := c.getMutatingWebhookSkeleton("foo", "/bar", []admiv1beta1.OperationType{admiv1beta1.Create}, map[string][]string{"": {"pods"}}, nil, nil, nil) assert.Equal(t, admiv1beta1.IfNeededReinvocationPolicy, *mutatingWebhookSkeleton.ReinvocationPolicy) @@ -236,7 +240,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { tests := []struct { name string setupConfig func(model.Config) - configFunc func() Config + configFunc func(model.Config) Config want func() []admiv1beta1.MutatingWebhook }{ { @@ -248,7 +252,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhook := webhook("datadog.webhook.agent.config", "/injectconfig", &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ @@ -271,7 +275,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhook := webhook("datadog.webhook.agent.config", "/injectconfig", &metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -290,7 +294,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhook := webhook("datadog.webhook.standard.tags", "/injecttags", &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ @@ -313,7 +317,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhook := webhook("datadog.webhook.standard.tags", "/injecttags", &metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -332,7 +336,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", true) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhook := webhook("datadog.webhook.lib.injection", "/injectlib", &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ @@ -355,7 +359,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", true) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhook := webhook("datadog.webhook.lib.injection", "/injectlib", &metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -373,7 +377,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhookConfig := webhook("datadog.webhook.agent.config", "/injectconfig", &metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -397,7 +401,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhookConfig := webhook("datadog.webhook.agent.config", "/injectconfig", &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ @@ -430,7 +434,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhookConfig := webhook("datadog.webhook.agent.config", "/injectconfig", nil, &metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -456,7 +460,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhook := webhook( "datadog.webhook.agent.config", @@ -505,7 +509,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.auto_instrumentation.enabled", false) mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.enabled", false) }, - configFunc: func() Config { return NewConfig(false, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { webhook := webhook( "datadog.webhook.agent.config", @@ -552,7 +556,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.mutate_unlabelled", true) mockConfig.SetWithoutSource("cluster_agent.service_account_name", "datadog-cluster-agent") }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.cws.pod.instrumentation", @@ -595,7 +599,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.mutate_unlabelled", false) mockConfig.SetWithoutSource("cluster_agent.service_account_name", "datadog-cluster-agent") }, - configFunc: func() Config { return NewConfig(false, false, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, false, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.cws.pod.instrumentation", @@ -634,7 +638,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.mutate_unlabelled", true) mockConfig.SetWithoutSource("cluster_agent.service_account_name", "datadog-cluster-agent") }, - configFunc: func() Config { return NewConfig(false, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.cws.pod.instrumentation", @@ -677,7 +681,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.cws_instrumentation.mutate_unlabelled", false) mockConfig.SetWithoutSource("cluster_agent.service_account_name", "datadog-cluster-agent") }, - configFunc: func() Config { return NewConfig(false, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(false, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.cws.pod.instrumentation", @@ -719,7 +723,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "misconfigured") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { return []admiv1beta1.MutatingWebhook{} }, @@ -739,7 +743,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.agent.sidecar", @@ -772,7 +776,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { return []admiv1beta1.MutatingWebhook{} }, @@ -792,7 +796,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { return []admiv1beta1.MutatingWebhook{} }, @@ -812,7 +816,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[{\"NamespaceSelector\": {\"MatchLabels\": {\"labelKey\": \"labelVal\"}}}]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.agent.sidecar", @@ -843,7 +847,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[{\"ObjectSelector\": {\"MatchLabels\": {\"labelKey\": \"labelVal\"}}}]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { return []admiv1beta1.MutatingWebhook{} }, @@ -863,7 +867,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[{\"ObjectSelector\": {\"MatchLabels\": {\"labelKey\": \"labelVal\"}}}]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.agent.sidecar", @@ -892,7 +896,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[{\"ObjectSelector\": {\"MatchLabels\": {\"labelKey1\": \"labelVal1\"}}, \"NamespaceSelector\": {\"MatchLabels\": {\"labelKey2\": \"labelVal2\"}}}]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { podWebhook := webhook( "datadog.webhook.agent.sidecar", @@ -921,7 +925,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { mockConfig.SetWithoutSource("admission_controller.agent_sidecar.selectors", "[{\"NamespaceSelector\": {\"MatchLabels\":{\"labelKey1\": \"labelVal1\"}}} , {\"ObjectSelector\": {\"MatchLabels\": {\"labelKey2\": \"labelVal2\"}}}]") mockConfig.SetWithoutSource("admission_controller.agent_sidecar.profiles", "[]") }, - configFunc: func() Config { return NewConfig(true, true, false) }, + configFunc: func(mockConfig model.Config) Config { return NewConfig(true, true, false, mockConfig) }, want: func() []admiv1beta1.MutatingWebhook { return []admiv1beta1.MutatingWebhook{} }, @@ -940,7 +944,7 @@ func TestGenerateTemplatesV1beta1(t *testing.T) { tt.setupConfig(mockConfig) c := &ControllerV1beta1{} - c.config = tt.configFunc() + c.config = tt.configFunc(mockConfig) c.webhooks = c.generateWebhooks(wmeta, nil, mockConfig, nil) c.generateTemplates() @@ -1044,7 +1048,7 @@ func TestGetValidatingWebhookSkeletonV1beta1(t *testing.T) { } c := &ControllerV1beta1{} - c.config = NewConfig(false, tt.namespaceSelector, false) + c.config = NewConfig(false, tt.namespaceSelector, false, mockConfig) nsSelector, objSelector := common.DefaultLabelSelectors(tt.namespaceSelector) @@ -1150,7 +1154,7 @@ func TestGetMutatingWebhookSkeletonV1beta1(t *testing.T) { } c := &ControllerV1beta1{} - c.config = NewConfig(false, tt.namespaceSelector, false) + c.config = NewConfig(false, tt.namespaceSelector, false, mockConfig) nsSelector, objSelector := common.DefaultLabelSelectors(tt.namespaceSelector) @@ -1181,7 +1185,7 @@ func (f *fixtureV1beta1) createController() (*ControllerV1beta1, informers.Share factory.Admissionregistration().V1beta1().MutatingWebhookConfigurations(), func() bool { return true }, make(chan struct{}), - v1beta1Cfg, + getV1beta1Cfg(f.t), wmeta, nil, datadogConfig, diff --git a/pkg/clusteragent/admission/mutate/autoscaling/autoscaling.go b/pkg/clusteragent/admission/mutate/autoscaling/autoscaling.go index b4e7225ef710e..4ac5396506357 100644 --- a/pkg/clusteragent/admission/mutate/autoscaling/autoscaling.go +++ b/pkg/clusteragent/admission/mutate/autoscaling/autoscaling.go @@ -16,10 +16,10 @@ import ( "k8s.io/client-go/dynamic" "github.com/DataDog/datadog-agent/cmd/cluster-agent/admission" + "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/pkg/clusteragent/admission/common" mutatecommon "github.com/DataDog/datadog-agent/pkg/clusteragent/admission/mutate/common" "github.com/DataDog/datadog-agent/pkg/clusteragent/autoscaling/workload" - pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" ) const ( @@ -39,10 +39,10 @@ type Webhook struct { } // NewWebhook returns a new Webhook -func NewWebhook(patcher workload.PodPatcher) *Webhook { +func NewWebhook(patcher workload.PodPatcher, datadogConfig config.Component) *Webhook { return &Webhook{ name: webhookName, - isEnabled: pkgconfigsetup.Datadog().GetBool("autoscaling.workload.enabled"), + isEnabled: datadogConfig.GetBool("autoscaling.workload.enabled"), endpoint: webhookEndpoint, resources: map[string][]string{"": {"pods"}}, operations: []admissionregistrationv1.OperationType{admissionregistrationv1.Create}, diff --git a/pkg/clusteragent/admission/start.go b/pkg/clusteragent/admission/start.go index aee1183a3133d..ef69edfd4a203 100644 --- a/pkg/clusteragent/admission/start.go +++ b/pkg/clusteragent/admission/start.go @@ -79,7 +79,7 @@ func StartControllers(ctx ControllerContext, wmeta workloadmeta.Component, pa wo return webhooks, err } - webhookConfig := webhook.NewConfig(v1Enabled, nsSelectorEnabled, matchConditionsSupported) + webhookConfig := webhook.NewConfig(v1Enabled, nsSelectorEnabled, matchConditionsSupported, datadogConfig) webhookController := webhook.NewController( ctx.Client, ctx.SecretInformers.Core().V1().Secrets(), diff --git a/pkg/collector/corechecks/containers/generic/filters.go b/pkg/collector/corechecks/containers/generic/filters.go index 788a88664bcb5..fbf0fb544e25a 100644 --- a/pkg/collector/corechecks/containers/generic/filters.go +++ b/pkg/collector/corechecks/containers/generic/filters.go @@ -56,7 +56,7 @@ func (f LegacyContainerFilter) IsExcluded(container *workloadmeta.Container) boo annotations = pod.Annotations } - return f.OldFilter.IsExcluded(annotations, container.Name, container.Image.Name, container.Labels[kubernetes.CriContainerNamespaceLabel]) + return f.OldFilter.IsExcluded(annotations, container.Name, container.Image.RawName, container.Labels[kubernetes.CriContainerNamespaceLabel]) } // RuntimeContainerFilter filters containers by runtime diff --git a/pkg/collector/corechecks/containers/kubelet/common/pod.go b/pkg/collector/corechecks/containers/kubelet/common/pod.go index f0689b2c852d1..da2706b143de5 100644 --- a/pkg/collector/corechecks/containers/kubelet/common/pod.go +++ b/pkg/collector/corechecks/containers/kubelet/common/pod.go @@ -190,7 +190,7 @@ func GetContainerID(store workloadmeta.Component, metric model.Metric, filter *c return "", ErrContainerNotFound } - if filter.IsExcluded(pod.EntityMeta.Annotations, container.Name, container.Image.Name, pod.Namespace) { + if filter.IsExcluded(pod.EntityMeta.Annotations, container.Name, container.Image.RawName, pod.Namespace) { return "", ErrContainerExcluded } diff --git a/pkg/collector/corechecks/net/network/network.go b/pkg/collector/corechecks/net/network/network.go index c3505185203aa..d4a1e5cd6ebe7 100644 --- a/pkg/collector/corechecks/net/network/network.go +++ b/pkg/collector/corechecks/net/network/network.go @@ -17,7 +17,7 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/net" + "github.com/shirou/gopsutil/v4/net" yaml "gopkg.in/yaml.v2" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" diff --git a/pkg/collector/corechecks/net/network/network_test.go b/pkg/collector/corechecks/net/network/network_test.go index b2476ca3d734c..4a033f97dbe86 100644 --- a/pkg/collector/corechecks/net/network/network_test.go +++ b/pkg/collector/corechecks/net/network/network_test.go @@ -10,7 +10,7 @@ package network import ( "testing" - "github.com/shirou/gopsutil/v3/net" + "github.com/shirou/gopsutil/v4/net" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/pkg/collector/corechecks/oracle/oracle.go b/pkg/collector/corechecks/oracle/oracle.go index a36830ceb39bb..224555ba85bd6 100644 --- a/pkg/collector/corechecks/oracle/oracle.go +++ b/pkg/collector/corechecks/oracle/oracle.go @@ -137,7 +137,7 @@ func handleServiceCheck(c *Check, err error) { status = servicecheck.ServiceCheckCritical log.Errorf("%s failed to connect: %s", c.logPrompt, err) } - sender.ServiceCheck("oracle.can_connect", status, "", c.tags, message) + sendServiceCheck(c, "oracle.can_connect", status, message) sender.Commit() } diff --git a/pkg/collector/corechecks/oracle/oracle_integration_test.go b/pkg/collector/corechecks/oracle/oracle_integration_test.go index c0df585ca2065..0d37c3d66ec50 100644 --- a/pkg/collector/corechecks/oracle/oracle_integration_test.go +++ b/pkg/collector/corechecks/oracle/oracle_integration_test.go @@ -424,6 +424,14 @@ func buildConnectionString(connectionConfig config.ConnectionConfig) string { return connStr } +func TestCanConnectTags(t *testing.T) { + chk, sender := newDefaultCheck(t, "", "") + err := chk.Run() + require.NoError(t, err) + + sender.AssertServiceCheck(t, "oracle.can_connect", servicecheck.ServiceCheckOK, chk.dbHostname, nil, "") +} + func TestLargeUint64Binding(t *testing.T) { var err error c, _ := newDefaultCheck(t, "", "") diff --git a/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go b/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go index d40a5216f1355..357409b59712c 100644 --- a/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go +++ b/pkg/collector/corechecks/servicediscovery/module/impl_linux_test.go @@ -288,13 +288,23 @@ func TestPorts(t *testing.T) { startUDP("udp4") startUDP("udp6") + expectedPortsMap := make(map[uint16]struct{}, len(expectedPorts)) + serviceMap := getServicesMap(t, url) pid := os.Getpid() require.Contains(t, serviceMap, pid) for _, port := range expectedPorts { + expectedPortsMap[port] = struct{}{} assert.Contains(t, serviceMap[pid].Ports, port) } for _, port := range unexpectedPorts { + // An unexpected port number can also be expected since UDP and TCP and + // v4 and v6 are all in the same list. Just skip the extra check in that + // case since it should be rare. + if _, alsoExpected := expectedPortsMap[port]; alsoExpected { + continue + } + assert.NotContains(t, serviceMap[pid].Ports, port) } } diff --git a/pkg/collector/corechecks/snmp/internal/devicecheck/devicecheck.go b/pkg/collector/corechecks/snmp/internal/devicecheck/devicecheck.go index 969fd45d2da52..d23d5642a2470 100644 --- a/pkg/collector/corechecks/snmp/internal/devicecheck/devicecheck.go +++ b/pkg/collector/corechecks/snmp/internal/devicecheck/devicecheck.go @@ -17,8 +17,9 @@ import ( "go.uber.org/atomic" + "github.com/DataDog/datadog-agent/comp/core/config" + haagenthelpers "github.com/DataDog/datadog-agent/comp/haagent/helpers" "github.com/DataDog/datadog-agent/pkg/collector/externalhost" - pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" configUtils "github.com/DataDog/datadog-agent/pkg/config/utils" "github.com/DataDog/datadog-agent/pkg/metrics/servicecheck" "github.com/DataDog/datadog-agent/pkg/util/hostname/validate" @@ -66,12 +67,13 @@ type DeviceCheck struct { diagnoses *diagnoses.Diagnoses interfaceBandwidthState report.InterfaceBandwidthState cacheKey string + agentConfig config.Component } const cacheKeyPrefix = "snmp-tags" // NewDeviceCheck returns a new DeviceCheck -func NewDeviceCheck(config *checkconfig.CheckConfig, ipAddress string, sessionFactory session.Factory) (*DeviceCheck, error) { +func NewDeviceCheck(config *checkconfig.CheckConfig, ipAddress string, sessionFactory session.Factory, agentConfig config.Component) (*DeviceCheck, error) { newConfig := config.CopyWithNewIP(ipAddress) var devicePinger pinger.Pinger @@ -94,6 +96,7 @@ func NewDeviceCheck(config *checkconfig.CheckConfig, ipAddress string, sessionFa diagnoses: diagnoses.NewDeviceDiagnoses(newConfig.DeviceID), interfaceBandwidthState: report.MakeInterfaceBandwidthState(), cacheKey: cacheKey, + agentConfig: agentConfig, } d.readTagsFromCache() @@ -244,11 +247,19 @@ func (d *DeviceCheck) setDeviceHostExternalTags() { if deviceHostname == "" || err != nil { return } - agentTags := configUtils.GetConfiguredTags(pkgconfigsetup.Datadog(), false) + agentTags := d.buildExternalTags() log.Debugf("Set external tags for device host, host=`%s`, agentTags=`%v`", deviceHostname, agentTags) externalhost.SetExternalTags(deviceHostname, common.SnmpExternalTagsSourceType, agentTags) } +func (d *DeviceCheck) buildExternalTags() []string { + agentTags := configUtils.GetConfiguredTags(d.agentConfig, false) + if haagenthelpers.IsEnabled(d.agentConfig) { + agentTags = append(agentTags, haagenthelpers.GetHaAgentTags(d.agentConfig)...) + } + return agentTags +} + func (d *DeviceCheck) getValuesAndTags() (bool, []string, *valuestore.ResultValueStore, error) { var deviceReachable bool var checkErrors []string diff --git a/pkg/collector/corechecks/snmp/internal/devicecheck/devicecheck_test.go b/pkg/collector/corechecks/snmp/internal/devicecheck/devicecheck_test.go index c56235171d3a2..1e7ad7fc7a001 100644 --- a/pkg/collector/corechecks/snmp/internal/devicecheck/devicecheck_test.go +++ b/pkg/collector/corechecks/snmp/internal/devicecheck/devicecheck_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + agentconfig "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/pkg/aggregator/mocksender" "github.com/DataDog/datadog-agent/pkg/metrics/servicecheck" "github.com/DataDog/datadog-agent/pkg/version" @@ -57,7 +58,7 @@ profiles: config, err := checkconfig.NewCheckConfig(rawInstanceConfig, rawInitConfig) assert.Nil(t, err) - deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory) + deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory, agentconfig.NewMock(t)) assert.Nil(t, err) sender := mocksender.NewMockSender("123") // required to initiate aggregator @@ -197,7 +198,7 @@ global_metrics: config, err := checkconfig.NewCheckConfig(rawInstanceConfig, rawInitConfig) assert.Nil(t, err) - deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory) + deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory, agentconfig.NewMock(t)) assert.Nil(t, err) sender := mocksender.NewMockSender("123") // required to initiate aggregator @@ -246,7 +247,7 @@ community_string: public config, err := checkconfig.NewCheckConfig(rawInstanceConfig, rawInitConfig) assert.Nil(t, err) - deviceCk, err := NewDeviceCheck(config, "1.2.3.4", session.NewMockSession) + deviceCk, err := NewDeviceCheck(config, "1.2.3.4", session.NewMockSession, agentconfig.NewMock(t)) assert.Nil(t, err) sender := mocksender.NewMockSender("123") // required to initiate aggregator @@ -277,7 +278,7 @@ community_string: public config, err := checkconfig.NewCheckConfig(rawInstanceConfig, rawInitConfig) assert.Nil(t, err) - deviceCk, err := NewDeviceCheck(config, "1.2.3.4", session.NewMockSession) + deviceCk, err := NewDeviceCheck(config, "1.2.3.4", session.NewMockSession, agentconfig.NewMock(t)) assert.Nil(t, err) hostname, err := deviceCk.GetDeviceHostname() @@ -343,7 +344,7 @@ profiles: config, err := checkconfig.NewCheckConfig(rawInstanceConfig, rawInitConfig) assert.Nil(t, err) - deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory) + deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory, agentconfig.NewMock(t)) assert.Nil(t, err) snmpTags := []string{"snmp_device:1.2.3.4", "device_ip:1.2.3.4", "device_id:default:1.2.3.4", "snmp_profile:f5-big-ip", "device_vendor:f5", "snmp_host:foo_sys_name", @@ -648,7 +649,7 @@ profiles: config, err := checkconfig.NewCheckConfig(rawInstanceConfig, rawInitConfig) assert.Nil(t, err) - deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory) + deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory, agentconfig.NewMock(t)) assert.Nil(t, err) sender := mocksender.NewMockSender("123") // required to initiate aggregator @@ -695,7 +696,7 @@ profiles: config, err := checkconfig.NewCheckConfig(rawInstanceConfig, rawInitConfig) assert.Nil(t, err) - deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory) + deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory, agentconfig.NewMock(t)) assert.Nil(t, err) // override pinger with mock pinger @@ -846,7 +847,7 @@ profiles: config, err := checkconfig.NewCheckConfig(rawInstanceConfig, rawInitConfig) assert.Nil(t, err) - deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory) + deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory, agentconfig.NewMock(t)) assert.Nil(t, err) // override pinger with mock pinger @@ -967,3 +968,37 @@ profiles: sender.AssertNotCalled(t, "Gauge", pingAvgRttMetric, mock.Anything, mock.Anything, mock.Anything) sender.AssertNotCalled(t, "Gauge", pingPacketLoss, mock.Anything, mock.Anything, mock.Anything) } + +func TestDeviceCheck_buildExternalTags(t *testing.T) { + // GIVEN + profile.SetConfdPathAndCleanProfiles() + sess := session.CreateFakeSession() + sessionFactory := func(*checkconfig.CheckConfig) (session.Session, error) { + return sess, nil + } + + // language=yaml + rawInstanceConfig := []byte(` +ip_address: 1.2.3.4 +community_string: public +collect_topology: false +`) + // language=yaml + rawInitConfig := []byte(``) + + config, err := checkconfig.NewCheckConfig(rawInstanceConfig, rawInitConfig) + assert.Nil(t, err) + + cfg := agentconfig.NewMock(t) + cfg.SetWithoutSource("ha_agent.enabled", true) + cfg.SetWithoutSource("ha_agent.group", "my-group") + + deviceCk, err := NewDeviceCheck(config, "1.2.3.4", sessionFactory, cfg) + assert.Nil(t, err) + + // WHEN + externalTags := deviceCk.buildExternalTags() + + // THEN + assert.Equal(t, []string{"agent_group:my-group"}, externalTags) +} diff --git a/pkg/collector/corechecks/snmp/internal/discovery/discovery.go b/pkg/collector/corechecks/snmp/internal/discovery/discovery.go index b7fb91915209a..860f3cb781991 100644 --- a/pkg/collector/corechecks/snmp/internal/discovery/discovery.go +++ b/pkg/collector/corechecks/snmp/internal/discovery/discovery.go @@ -14,6 +14,7 @@ import ( "sync" "time" + "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/pkg/persistentcache" "github.com/DataDog/datadog-agent/pkg/util/log" "go.uber.org/atomic" @@ -43,6 +44,7 @@ type Discovery struct { discoveredDevices map[checkconfig.DeviceDigest]Device sessionFactory session.Factory + agentConfig config.Component } // Device implements and store results from the Service interface for the SNMP listener @@ -237,7 +239,7 @@ func (d *Discovery) getDevicesFound() []string { } func (d *Discovery) createDevice(deviceDigest checkconfig.DeviceDigest, subnet *snmpSubnet, deviceIP string, writeCache bool) { - deviceCk, err := devicecheck.NewDeviceCheck(subnet.config, deviceIP, d.sessionFactory) + deviceCk, err := devicecheck.NewDeviceCheck(subnet.config, deviceIP, d.sessionFactory, d.agentConfig) if err != nil { // should not happen since the deviceCheck is expected to be valid at this point // and are only changing the device ip @@ -335,11 +337,12 @@ func (d *Discovery) writeCache(subnet *snmpSubnet) { } // NewDiscovery return a new Discovery instance -func NewDiscovery(config *checkconfig.CheckConfig, sessionFactory session.Factory) *Discovery { +func NewDiscovery(config *checkconfig.CheckConfig, sessionFactory session.Factory, agentConfig config.Component) *Discovery { return &Discovery{ discoveredDevices: make(map[checkconfig.DeviceDigest]Device), stop: make(chan struct{}), config: config, sessionFactory: sessionFactory, + agentConfig: agentConfig, } } diff --git a/pkg/collector/corechecks/snmp/internal/discovery/discovery_test.go b/pkg/collector/corechecks/snmp/internal/discovery/discovery_test.go index 9d59def5890d0..4ca8ccc302bf2 100644 --- a/pkg/collector/corechecks/snmp/internal/discovery/discovery_test.go +++ b/pkg/collector/corechecks/snmp/internal/discovery/discovery_test.go @@ -8,16 +8,15 @@ package discovery import ( "fmt" "net" - "path/filepath" "testing" "time" "github.com/gosnmp/gosnmp" "github.com/stretchr/testify/assert" + agentconfig "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/snmp/internal/checkconfig" "github.com/DataDog/datadog-agent/pkg/collector/corechecks/snmp/internal/session" - pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" ) func waitForDiscoveredDevices(discovery *Discovery, expectedDeviceCount int, timeout time.Duration) error { @@ -33,8 +32,8 @@ func waitForDiscoveredDevices(discovery *Discovery, expectedDeviceCount int, tim } func TestDiscovery(t *testing.T) { - path, _ := filepath.Abs(filepath.Join(".", "test", "run_path", "TestDiscovery")) - pkgconfigsetup.Datadog().SetWithoutSource("run_path", path) + config := agentconfig.NewMock(t) + config.SetWithoutSource("run_path", t.TempDir()) sess := session.CreateMockSession() sessionFactory := func(*checkconfig.CheckConfig) (session.Session, error) { @@ -59,7 +58,7 @@ func TestDiscovery(t *testing.T) { DiscoveryWorkers: 1, IgnoredIPAddresses: map[string]bool{"192.168.0.5": true}, } - discovery := NewDiscovery(checkConfig, sessionFactory) + discovery := NewDiscovery(checkConfig, sessionFactory, config) discovery.Start() assert.NoError(t, waitForDiscoveredDevices(discovery, 7, 2*time.Second)) discovery.Stop() @@ -84,8 +83,8 @@ func TestDiscovery(t *testing.T) { } func TestDiscoveryCache(t *testing.T) { - path, _ := filepath.Abs(filepath.Join(".", "test", "run_path", "TestDiscoveryCache")) - pkgconfigsetup.Datadog().SetWithoutSource("run_path", path) + config := agentconfig.NewMock(t) + config.SetWithoutSource("run_path", t.TempDir()) sess := session.CreateMockSession() sessionFactory := func(*checkconfig.CheckConfig) (session.Session, error) { @@ -109,7 +108,7 @@ func TestDiscoveryCache(t *testing.T) { DiscoveryInterval: 3600, DiscoveryWorkers: 1, } - discovery := NewDiscovery(checkConfig, sessionFactory) + discovery := NewDiscovery(checkConfig, sessionFactory, config) discovery.Start() assert.NoError(t, waitForDiscoveredDevices(discovery, 4, 2*time.Second)) discovery.Stop() @@ -141,7 +140,7 @@ func TestDiscoveryCache(t *testing.T) { DiscoveryInterval: 3600, DiscoveryWorkers: 0, // no workers, the devices will be loaded from cache } - discovery2 := NewDiscovery(checkConfig, sessionFactory) + discovery2 := NewDiscovery(checkConfig, sessionFactory, config) discovery2.Start() assert.NoError(t, waitForDiscoveredDevices(discovery2, 4, 2*time.Second)) discovery2.Stop() @@ -158,6 +157,9 @@ func TestDiscoveryCache(t *testing.T) { func TestDiscoveryTicker(t *testing.T) { t.Skip() // TODO: FIX ME, currently this test is leading to data race when ran with other tests + config := agentconfig.NewMock(t) + config.SetWithoutSource("run_path", t.TempDir()) + sess := session.CreateMockSession() sessionFactory := func(*checkconfig.CheckConfig) (session.Session, error) { return sess, nil @@ -180,7 +182,7 @@ func TestDiscoveryTicker(t *testing.T) { DiscoveryInterval: 1, DiscoveryWorkers: 1, } - discovery := NewDiscovery(checkConfig, sessionFactory) + discovery := NewDiscovery(checkConfig, sessionFactory, config) discovery.Start() time.Sleep(1500 * time.Millisecond) discovery.Stop() @@ -191,7 +193,8 @@ func TestDiscoveryTicker(t *testing.T) { } func TestDiscovery_checkDevice(t *testing.T) { - SetTestRunPath() + config := agentconfig.NewMock(t) + config.SetWithoutSource("run_path", t.TempDir()) checkConfig := &checkconfig.CheckConfig{ Network: "192.168.0.0/32", CommunityString: "public", @@ -227,7 +230,7 @@ func TestDiscovery_checkDevice(t *testing.T) { } var sess *session.MockSession - discovery := NewDiscovery(checkConfig, session.NewMockSession) + discovery := NewDiscovery(checkConfig, session.NewMockSession, config) checkDeviceOnce := func() { sess = session.CreateMockSession() @@ -306,7 +309,9 @@ func TestDiscovery_checkDevice(t *testing.T) { } func TestDiscovery_createDevice(t *testing.T) { - SetTestRunPath() + config := agentconfig.NewMock(t) + config.SetWithoutSource("run_path", t.TempDir()) + checkConfig := &checkconfig.CheckConfig{ Network: "192.168.0.0/32", CommunityString: "public", @@ -315,7 +320,7 @@ func TestDiscovery_createDevice(t *testing.T) { DiscoveryAllowedFailures: 3, Namespace: "default", } - discovery := NewDiscovery(checkConfig, session.NewMockSession) + discovery := NewDiscovery(checkConfig, session.NewMockSession, config) ipAddr, ipNet, err := net.ParseCIDR(checkConfig.Network) assert.Nil(t, err) startingIP := ipAddr.Mask(ipNet.Mask) diff --git a/pkg/collector/corechecks/snmp/internal/discovery/testing.go b/pkg/collector/corechecks/snmp/internal/discovery/testing.go deleted file mode 100644 index 820bc1747acd7..0000000000000 --- a/pkg/collector/corechecks/snmp/internal/discovery/testing.go +++ /dev/null @@ -1,20 +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. - -//go:build test - -package discovery - -import ( - "path/filepath" - - pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" -) - -// SetTestRunPath sets run_path for testing -func SetTestRunPath() { - path, _ := filepath.Abs(filepath.Join(".", "test", "run_path")) - pkgconfigsetup.Datadog().SetWithoutSource("run_path", path) -} diff --git a/pkg/collector/corechecks/snmp/snmp.go b/pkg/collector/corechecks/snmp/snmp.go index 6b59932b057c6..29e2ae2327c5b 100644 --- a/pkg/collector/corechecks/snmp/snmp.go +++ b/pkg/collector/corechecks/snmp/snmp.go @@ -11,6 +11,7 @@ import ( "sync" "time" + "github.com/DataDog/datadog-agent/comp/core/config" "go.uber.org/atomic" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" @@ -44,6 +45,7 @@ type Check struct { discovery *discovery.Discovery sessionFactory session.Factory workerRunDeviceCheckErrors *atomic.Uint64 + agentConfig config.Component } // Run executes the check @@ -155,10 +157,10 @@ func (c *Check) Configure(senderManager sender.SenderManager, integrationConfigD } if c.config.IsDiscovery() { - c.discovery = discovery.NewDiscovery(c.config, c.sessionFactory) + c.discovery = discovery.NewDiscovery(c.config, c.sessionFactory, c.agentConfig) c.discovery.Start() } else { - c.singleDeviceCk, err = devicecheck.NewDeviceCheck(c.config, c.config.IPAddress, c.sessionFactory) + c.singleDeviceCk, err = devicecheck.NewDeviceCheck(c.config, c.config.IPAddress, c.sessionFactory, c.agentConfig) if err != nil { return fmt.Errorf("failed to create device check: %s", err) } @@ -196,14 +198,17 @@ func (c *Check) GetDiagnoses() ([]diagnosis.Diagnosis, error) { } // Factory creates a new check factory -func Factory() optional.Option[func() check.Check] { - return optional.NewOption(newCheck) +func Factory(agentConfig config.Component) optional.Option[func() check.Check] { + return optional.NewOption(func() check.Check { + return newCheck(agentConfig) + }) } -func newCheck() check.Check { +func newCheck(agentConfig config.Component) check.Check { return &Check{ CheckBase: core.NewCheckBase(common.SnmpIntegrationName), sessionFactory: session.NewGosnmpSession, workerRunDeviceCheckErrors: atomic.NewUint64(0), + agentConfig: agentConfig, } } diff --git a/pkg/collector/corechecks/snmp/snmp_test.go b/pkg/collector/corechecks/snmp/snmp_test.go index 88513ca8ce0d3..2f1095dc52027 100644 --- a/pkg/collector/corechecks/snmp/snmp_test.go +++ b/pkg/collector/corechecks/snmp/snmp_test.go @@ -25,6 +25,7 @@ import ( "github.com/DataDog/datadog-agent/comp/aggregator/demultiplexer/demultiplexerimpl" "github.com/DataDog/datadog-agent/comp/core" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" + agentconfig "github.com/DataDog/datadog-agent/comp/core/config" "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder" "github.com/DataDog/datadog-agent/pkg/aggregator/mocksender" "github.com/DataDog/datadog-agent/pkg/collector/externalhost" @@ -996,10 +997,10 @@ community_string: public func TestCheckID(t *testing.T) { profile.SetConfdPathAndCleanProfiles() - check1 := newCheck() - check2 := newCheck() - check3 := newCheck() - checkSubnet := newCheck() + check1 := newCheck(agentconfig.NewMock(t)) + check2 := newCheck(agentconfig.NewMock(t)) + check3 := newCheck(agentconfig.NewMock(t)) + checkSubnet := newCheck(agentconfig.NewMock(t)) // language=yaml rawInstanceConfig1 := []byte(` ip_address: 1.1.1.1 @@ -2165,7 +2166,7 @@ func TestDeviceIDAsHostname(t *testing.T) { sessionFactory := func(*checkconfig.CheckConfig) (session.Session, error) { return sess, nil } - chk := Check{sessionFactory: sessionFactory} + chk := Check{sessionFactory: sessionFactory, agentConfig: agentconfig.NewMock(t)} pkgconfigsetup.Datadog().SetWithoutSource("hostname", "test-hostname") pkgconfigsetup.Datadog().SetWithoutSource("tags", []string{"agent_tag1:val1", "agent_tag2:val2"}) senderManager := deps.Demultiplexer @@ -2358,7 +2359,7 @@ func TestDiscoveryDeviceIDAsHostname(t *testing.T) { sessionFactory := func(*checkconfig.CheckConfig) (session.Session, error) { return sess, nil } - chk := Check{sessionFactory: sessionFactory} + chk := Check{sessionFactory: sessionFactory, agentConfig: agentconfig.NewMock(t)} pkgconfigsetup.Datadog().SetWithoutSource("hostname", "my-hostname") senderManager := deps.Demultiplexer diff --git a/pkg/collector/corechecks/system/cpu/cpu/cpu.go b/pkg/collector/corechecks/system/cpu/cpu/cpu.go index 8ca44f462bd61..a098b35a39647 100644 --- a/pkg/collector/corechecks/system/cpu/cpu/cpu.go +++ b/pkg/collector/corechecks/system/cpu/cpu/cpu.go @@ -10,7 +10,7 @@ package cpu import ( "fmt" - "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v4/cpu" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/pkg/aggregator/sender" diff --git a/pkg/collector/corechecks/system/cpu/cpu/cpu_test.go b/pkg/collector/corechecks/system/cpu/cpu/cpu_test.go index d5124637d6c4a..43a243f36d10d 100644 --- a/pkg/collector/corechecks/system/cpu/cpu/cpu_test.go +++ b/pkg/collector/corechecks/system/cpu/cpu/cpu_test.go @@ -20,7 +20,7 @@ import ( pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" "github.com/DataDog/datadog-agent/pkg/metrics" - "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v4/cpu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) diff --git a/pkg/collector/corechecks/system/cpu/load/load.go b/pkg/collector/corechecks/system/cpu/load/load.go index 6d6aa1833dedb..52be3ea30e08a 100644 --- a/pkg/collector/corechecks/system/cpu/load/load.go +++ b/pkg/collector/corechecks/system/cpu/load/load.go @@ -10,8 +10,8 @@ package load import ( "fmt" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/load" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/load" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/pkg/aggregator/sender" diff --git a/pkg/collector/corechecks/system/cpu/load/load_test.go b/pkg/collector/corechecks/system/cpu/load/load_test.go index af820e8fc21fa..fd140edd86ffd 100644 --- a/pkg/collector/corechecks/system/cpu/load/load_test.go +++ b/pkg/collector/corechecks/system/cpu/load/load_test.go @@ -9,9 +9,9 @@ package load import ( "testing" - "github.com/shirou/gopsutil/v3/load" + "github.com/shirou/gopsutil/v4/load" - "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v4/cpu" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/pkg/aggregator/mocksender" diff --git a/pkg/collector/corechecks/system/disk/disk/disk_nix.go b/pkg/collector/corechecks/system/disk/disk/disk_nix.go index 23a03601724a1..7a384f377056c 100644 --- a/pkg/collector/corechecks/system/disk/disk/disk_nix.go +++ b/pkg/collector/corechecks/system/disk/disk/disk_nix.go @@ -11,7 +11,7 @@ import ( "fmt" "path/filepath" - "github.com/shirou/gopsutil/v3/disk" + "github.com/shirou/gopsutil/v4/disk" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/pkg/aggregator/sender" diff --git a/pkg/collector/corechecks/system/disk/disk/disk_test.go b/pkg/collector/corechecks/system/disk/disk/disk_test.go index 76aae7d0cfc36..2934b7fe9ed11 100644 --- a/pkg/collector/corechecks/system/disk/disk/disk_test.go +++ b/pkg/collector/corechecks/system/disk/disk/disk_test.go @@ -10,7 +10,7 @@ import ( "regexp" "testing" - "github.com/shirou/gopsutil/v3/disk" + "github.com/shirou/gopsutil/v4/disk" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/pkg/aggregator/mocksender" diff --git a/pkg/collector/corechecks/system/disk/io/iostats.go b/pkg/collector/corechecks/system/disk/io/iostats.go index 2cdf7647bf14a..b40315ebff0af 100644 --- a/pkg/collector/corechecks/system/disk/io/iostats.go +++ b/pkg/collector/corechecks/system/disk/io/iostats.go @@ -20,7 +20,7 @@ import ( ) const ( - // SectorSize is used here to substitute non-exporeted from github.com/shirou/gopsutil/v3/disk package constant named "sectorSize" + // SectorSize is used here to substitute non-exporeted from github.com/shirou/gopsutil/v4/disk package constant named "sectorSize" SectorSize = 512 kB = (1 << 10) CheckName = "io" diff --git a/pkg/collector/corechecks/system/disk/io/iostats_nix.go b/pkg/collector/corechecks/system/disk/io/iostats_nix.go index 8fe5b1e66da5e..e3813f162da9e 100644 --- a/pkg/collector/corechecks/system/disk/io/iostats_nix.go +++ b/pkg/collector/corechecks/system/disk/io/iostats_nix.go @@ -13,8 +13,8 @@ import ( "regexp" "time" - "github.com/shirou/gopsutil/v3/disk" - "github.com/shirou/gopsutil/v3/mem" // for system.io.block_{in,out} + "github.com/shirou/gopsutil/v4/disk" + "github.com/shirou/gopsutil/v4/mem" // for system.io.block_{in,out} "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/pkg/aggregator/sender" diff --git a/pkg/collector/corechecks/system/disk/io/iostats_nix_test.go b/pkg/collector/corechecks/system/disk/io/iostats_nix_test.go index 21bfbef4109da..61a60ccab654d 100644 --- a/pkg/collector/corechecks/system/disk/io/iostats_nix_test.go +++ b/pkg/collector/corechecks/system/disk/io/iostats_nix_test.go @@ -12,7 +12,7 @@ import ( "testing" "time" - "github.com/shirou/gopsutil/v3/disk" + "github.com/shirou/gopsutil/v4/disk" "github.com/stretchr/testify/assert" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" diff --git a/pkg/collector/corechecks/system/disk/io/iostats_test.go b/pkg/collector/corechecks/system/disk/io/iostats_test.go index 005b4aad3ebda..bb7d3eaef18b7 100644 --- a/pkg/collector/corechecks/system/disk/io/iostats_test.go +++ b/pkg/collector/corechecks/system/disk/io/iostats_test.go @@ -12,8 +12,8 @@ import ( "testing" "time" - "github.com/shirou/gopsutil/v3/disk" - "github.com/shirou/gopsutil/v3/mem" + "github.com/shirou/gopsutil/v4/disk" + "github.com/shirou/gopsutil/v4/mem" "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" "github.com/DataDog/datadog-agent/pkg/aggregator" diff --git a/pkg/collector/corechecks/system/memory/memory_nix.go b/pkg/collector/corechecks/system/memory/memory_nix.go index 190a4c7e02b41..577fb222bb97b 100644 --- a/pkg/collector/corechecks/system/memory/memory_nix.go +++ b/pkg/collector/corechecks/system/memory/memory_nix.go @@ -11,7 +11,7 @@ import ( "fmt" "runtime" - "github.com/shirou/gopsutil/v3/mem" + "github.com/shirou/gopsutil/v4/mem" "github.com/DataDog/datadog-agent/pkg/util/log" diff --git a/pkg/collector/corechecks/system/memory/memory_nix_test.go b/pkg/collector/corechecks/system/memory/memory_nix_test.go index b7cfd2e55a3f9..e8be54dbb93a9 100644 --- a/pkg/collector/corechecks/system/memory/memory_nix_test.go +++ b/pkg/collector/corechecks/system/memory/memory_nix_test.go @@ -11,7 +11,7 @@ import ( "fmt" "testing" - "github.com/shirou/gopsutil/v3/mem" + "github.com/shirou/gopsutil/v4/mem" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/pkg/collector/corechecks/system/uptime/uptime_nix.go b/pkg/collector/corechecks/system/uptime/uptime_nix.go index cc121ac42de61..41c8421153e3b 100644 --- a/pkg/collector/corechecks/system/uptime/uptime_nix.go +++ b/pkg/collector/corechecks/system/uptime/uptime_nix.go @@ -7,7 +7,7 @@ package uptime import ( - "github.com/shirou/gopsutil/v3/host" + "github.com/shirou/gopsutil/v4/host" ) // For testing purpose diff --git a/pkg/collector/python/init_windows.go b/pkg/collector/python/init_windows.go index 04d18175df1f7..3de1ba7a459b0 100644 --- a/pkg/collector/python/init_windows.go +++ b/pkg/collector/python/init_windows.go @@ -9,8 +9,10 @@ package python import ( "os" + "path/filepath" pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" + "github.com/DataDog/datadog-agent/pkg/util/winutil" ) // Any platform-specific initialization belongs here. @@ -21,5 +23,41 @@ func initializePlatform() error { os.Unsetenv("PYTHONPATH") } + // only use cache file when not admin + admin, _ := winutil.IsUserAnAdmin() + if !admin { + err := enableSeparatePythonCacheDir() + if err != nil { + return err + } + } + return nil } + +// enableSeparatePythonCacheDir configures Python to use a separate directory for its pycache. +// +// Creates a python-cache subdir in the configuration directory and configures Python to use it via the PYTHONPYCACHEPREFIX env var. +// +// https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPYCACHEPREFIX +func enableSeparatePythonCacheDir() error { + pd, err := winutil.GetProgramDataDir() + if err != nil { + return err + } + pycache := filepath.Join(pd, "python-cache") + + // check if path exists and create directory if it doesn't + if _, err := os.Stat(pycache); os.IsNotExist(err) { + if err := os.MkdirAll(pycache, 0755); err != nil { + return err + } + } else if err != nil { + return err + } + + os.Setenv("PYTHONPYCACHEPREFIX", pycache) + + return nil + +} diff --git a/pkg/commonchecks/corechecks.go b/pkg/commonchecks/corechecks.go index 9af1e7f9833c8..cb20f9412ab2a 100644 --- a/pkg/commonchecks/corechecks.go +++ b/pkg/commonchecks/corechecks.go @@ -62,7 +62,7 @@ func RegisterChecks(store workloadmeta.Component, tagger tagger.Component, cfg c corecheckLoader.RegisterCheck(uptime.CheckName, uptime.Factory()) corecheckLoader.RegisterCheck(telemetryCheck.CheckName, telemetryCheck.Factory(telemetry)) corecheckLoader.RegisterCheck(ntp.CheckName, ntp.Factory()) - corecheckLoader.RegisterCheck(snmp.CheckName, snmp.Factory()) + corecheckLoader.RegisterCheck(snmp.CheckName, snmp.Factory(cfg)) corecheckLoader.RegisterCheck(networkpath.CheckName, networkpath.Factory(telemetry)) corecheckLoader.RegisterCheck(io.CheckName, io.Factory()) corecheckLoader.RegisterCheck(filehandles.CheckName, filehandles.Factory()) diff --git a/pkg/config/config_template.yaml b/pkg/config/config_template.yaml index a858e50ce8b7f..5b4403be1a654 100644 --- a/pkg/config/config_template.yaml +++ b/pkg/config/config_template.yaml @@ -1261,7 +1261,7 @@ api_key: # obfuscate_sql_values: # - val1 # cache: - ## @param DD_APM_CACHE_ENABLED - boolean - optional + ## @param DD_APM_OBFUSCATION_CACHE_ENABLED - boolean - optional ## Enables caching obfuscated statements. Currently supported for SQL and MongoDB queries. ## Enabled by default. # enabled: true diff --git a/pkg/config/env/go.mod b/pkg/config/env/go.mod index 637c78a705df1..7b16228030c49 100644 --- a/pkg/config/env/go.mod +++ b/pkg/config/env/go.mod @@ -31,7 +31,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect diff --git a/pkg/config/env/go.sum b/pkg/config/env/go.sum index d7d4a9a3701e0..4a2c4e5bdc610 100644 --- a/pkg/config/env/go.sum +++ b/pkg/config/env/go.sum @@ -81,8 +81,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 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= diff --git a/pkg/config/fetcher/from_processes.go b/pkg/config/fetcher/from_processes.go index 5b8088f41d970..95c24e283fb46 100644 --- a/pkg/config/fetcher/from_processes.go +++ b/pkg/config/fetcher/from_processes.go @@ -71,7 +71,7 @@ func TraceAgentConfig(config config.Reader) (string, error) { c := util.GetClient(false) c.Timeout = config.GetDuration("server_timeout") * time.Second - ipcAddressWithPort := fmt.Sprintf("http://127.0.0.1:%d/config", port) + ipcAddressWithPort := fmt.Sprintf("https://127.0.0.1:%d/config", port) client := settingshttp.NewClient(c, ipcAddressWithPort, "trace-agent", settingshttp.NewHTTPClientOptions(util.CloseConnection)) return client.FullConfig() diff --git a/pkg/config/mock/go.mod b/pkg/config/mock/go.mod index 48f1f452fa096..f4edf2bbb8c8e 100644 --- a/pkg/config/mock/go.mod +++ b/pkg/config/mock/go.mod @@ -61,7 +61,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/pkg/config/mock/go.sum b/pkg/config/mock/go.sum index 3f00397cbc301..7fdf16db5981c 100644 --- a/pkg/config/mock/go.sum +++ b/pkg/config/mock/go.sum @@ -86,8 +86,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/config/remote/go.mod b/pkg/config/remote/go.mod index ec7d298386516..a1c4a4ebbc561 100644 --- a/pkg/config/remote/go.mod +++ b/pkg/config/remote/go.mod @@ -85,7 +85,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/system/socket v0.59.0 // indirect github.com/DataDog/datadog-agent/pkg/util/winutil v0.59.1 // indirect github.com/DataDog/datadog-agent/pkg/version v0.59.1 // indirect - github.com/DataDog/datadog-go/v5 v5.5.0 // indirect + github.com/DataDog/datadog-go/v5 v5.6.0 // indirect github.com/DataDog/go-libddwaf/v3 v3.5.1 // indirect github.com/DataDog/go-sqllexer v0.0.17 // indirect github.com/DataDog/sketches-go v1.4.6 // indirect @@ -100,7 +100,7 @@ require ( github.com/hashicorp/go-secure-stdlib/parseutil v0.1.8 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.6 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect diff --git a/pkg/config/remote/go.sum b/pkg/config/remote/go.sum index e9342de28e23c..ca537b0d1660e 100644 --- a/pkg/config/remote/go.sum +++ b/pkg/config/remote/go.sum @@ -7,8 +7,8 @@ cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/yb github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/appsec-internal-go v1.9.0 h1:cGOneFsg0JTRzWl5U2+og5dbtyW3N8XaYwc5nXe39Vw= github.com/DataDog/appsec-internal-go v1.9.0/go.mod h1:wW0cRfWBo4C044jHGwYiyh5moQV2x0AhnwqMuiX7O/g= -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/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= github.com/DataDog/go-libddwaf/v3 v3.5.1 h1:GWA4ln4DlLxiXm+X7HA/oj0ZLcdCwOS81KQitegRTyY= github.com/DataDog/go-libddwaf/v3 v3.5.1/go.mod h1:n98d9nZ1gzenRSk53wz8l6d34ikxS+hs62A31Fqmyi4= github.com/DataDog/go-sqllexer v0.0.17 h1:u47fJAVg/+5DA74ZW3w0Qu+3qXHd3GtnA8ZBYixdPrM= @@ -149,8 +149,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/config/remote/service/service.go b/pkg/config/remote/service/service.go index a379ac5b387ec..84377477da44c 100644 --- a/pkg/config/remote/service/service.go +++ b/pkg/config/remote/service/service.go @@ -111,50 +111,21 @@ func (s *Service) getNewDirectorRoots(uptane uptaneClient, currentVersion uint64 return roots, nil } -func (s *Service) getTargetFiles(uptane uptaneClient, products []rdata.Product, cachedTargetFiles []*pbgo.TargetFileMeta) ([]*pbgo.File, error) { - productSet := make(map[rdata.Product]struct{}) - for _, product := range products { - productSet[product] = struct{}{} - } - targets, err := uptane.Targets() +func (s *Service) getTargetFiles(uptaneClient uptaneClient, targetFilePaths []string) ([]*pbgo.File, error) { + files, err := uptaneClient.TargetFiles(targetFilePaths) if err != nil { return nil, err } - cachedTargets := make(map[string]data.FileMeta) - for _, cachedTarget := range cachedTargetFiles { - hashes := make(data.Hashes) - for _, hash := range cachedTarget.Hashes { - h, err := hex.DecodeString(hash.Hash) - if err != nil { - return nil, err - } - hashes[hash.Algorithm] = h - } - cachedTargets[cachedTarget.Path] = data.FileMeta{ - Hashes: hashes, - Length: cachedTarget.Length, - } - } + var configFiles []*pbgo.File - for targetPath, targetMeta := range targets { - configPathMeta, err := rdata.ParseConfigPath(targetPath) - if err != nil { - return nil, err - } - if _, inClientProducts := productSet[rdata.Product(configPathMeta.Product)]; inClientProducts { - if notEqualErr := tufutil.FileMetaEqual(cachedTargets[targetPath], targetMeta.FileMeta); notEqualErr == nil { - continue - } - fileContents, err := uptane.TargetFile(targetPath) - if err != nil { - return nil, err - } - configFiles = append(configFiles, &pbgo.File{ - Path: targetPath, - Raw: fileContents, - }) - } + for path, contents := range files { + // Note: This unconditionally succeeds as long as we don't change bufferDestination earlier + configFiles = append(configFiles, &pbgo.File{ + Path: path, + Raw: contents, + }) } + return configFiles, nil } @@ -211,6 +182,7 @@ type uptaneClient interface { StoredOrgUUID() (string, error) Targets() (data.TargetFiles, error) TargetFile(path string) ([]byte, error) + TargetFiles(files []string) (map[string][]byte, error) TargetsMeta() ([]byte, error) TargetsCustom() ([]byte, error) TUFVersionState() (uptane.TUFVersions, error) @@ -828,36 +800,30 @@ func (s *CoreAgentService) ClientGetConfigs(_ context.Context, request *pbgo.Cli if err != nil { return nil, err } - targetsRaw, err := s.uptane.TargetsMeta() + + directorTargets, err := s.uptane.Targets() if err != nil { return nil, err } - targetFiles, err := s.getTargetFiles(s.uptane, rdata.StringListToProduct(request.Client.Products), request.CachedTargetFiles) + matchedClientConfigs, err := executeTracerPredicates(request.Client, directorTargets) if err != nil { return nil, err } - directorTargets, err := s.uptane.Targets() + neededFiles, err := filterNeededTargetFiles(matchedClientConfigs, request.CachedTargetFiles, directorTargets) if err != nil { return nil, err } - matchedClientConfigs, err := executeTracerPredicates(request.Client, directorTargets) + + targetFiles, err := s.getTargetFiles(s.uptane, neededFiles) if err != nil { return nil, err } - // filter files to only return the ones that predicates marked for this client - matchedConfigsMap := make(map[string]interface{}) - for _, configPointer := range matchedClientConfigs { - matchedConfigsMap[configPointer] = struct{}{} - } - filteredFiles := make([]*pbgo.File, 0, len(matchedClientConfigs)) - for _, targetFile := range targetFiles { - if _, ok := matchedConfigsMap[targetFile.Path]; ok { - filteredFiles = append(filteredFiles, targetFile) - } + targetsRaw, err := s.uptane.TargetsMeta() + if err != nil { + return nil, err } - canonicalTargets, err := enforceCanonicalJSON(targetsRaw) if err != nil { return nil, err @@ -866,11 +832,42 @@ func (s *CoreAgentService) ClientGetConfigs(_ context.Context, request *pbgo.Cli return &pbgo.ClientGetConfigsResponse{ Roots: roots, Targets: canonicalTargets, - TargetFiles: filteredFiles, + TargetFiles: targetFiles, ClientConfigs: matchedClientConfigs, }, nil } +func filterNeededTargetFiles(neededConfigs []string, cachedTargetFiles []*pbgo.TargetFileMeta, tufTargets data.TargetFiles) ([]string, error) { + // Build an O(1) lookup of cached target files + cachedTargetsMap := make(map[string]data.FileMeta) + for _, cachedTarget := range cachedTargetFiles { + hashes := make(data.Hashes) + for _, hash := range cachedTarget.Hashes { + h, err := hex.DecodeString(hash.Hash) + if err != nil { + return nil, err + } + hashes[hash.Algorithm] = h + } + cachedTargetsMap[cachedTarget.Path] = data.FileMeta{ + Hashes: hashes, + Length: cachedTarget.Length, + } + } + + // We don't need to pull the raw contents if the client already has the exact version of the file cached + filteredList := make([]string, 0, len(neededConfigs)) + for _, path := range neededConfigs { + if notEqualErr := tufutil.FileMetaEqual(cachedTargetsMap[path], tufTargets[path].FileMeta); notEqualErr == nil { + continue + } + + filteredList = append(filteredList, path) + } + + return filteredList, nil +} + // ConfigGetState returns the state of the configuration and the director repos in the local store func (s *CoreAgentService) ConfigGetState() (*pbgo.GetStateConfigResponse, error) { state, err := s.uptane.State() @@ -1117,29 +1114,14 @@ func (c *HTTPClient) getUpdate( if tufVersions.DirectorTargets == currentTargetsVersion { return nil, nil } - roots, err := c.getNewDirectorRoots(c.uptane, currentRootVersion, tufVersions.DirectorRoot) - if err != nil { - return nil, err - } - targetsRaw, err := c.uptane.TargetsMeta() - if err != nil { - return nil, err - } - targetFiles, err := c.getTargetFiles(c.uptane, rdata.StringListToProduct(products), cachedTargetFiles) - if err != nil { - return nil, err - } - - canonicalTargets, err := enforceCanonicalJSON(targetsRaw) - if err != nil { - return nil, err - } + // Filter out files that either: + // - don't correspond to the product list the client is requesting + // - have expired directorTargets, err := c.uptane.Targets() if err != nil { return nil, err } - productsMap := make(map[string]struct{}) for _, product := range products { productsMap[product] = struct{}{} @@ -1165,14 +1147,33 @@ func (c *HTTPClient) getUpdate( configs = append(configs, path) } + span.SetTag("configs.returned", configs) + span.SetTag("configs.expired", expiredConfigs) + // Gather the files and map-ify them for the state data structure + targetFiles, err := c.getTargetFiles(c.uptane, configs) + if err != nil { + return nil, err + } fileMap := make(map[string][]byte, len(targetFiles)) for _, f := range targetFiles { fileMap[f.Path] = f.Raw } - span.SetTag("configs.returned", configs) - span.SetTag("configs.expired", expiredConfigs) + // Gather some TUF metadata files we need to send down + roots, err := c.getNewDirectorRoots(c.uptane, currentRootVersion, tufVersions.DirectorRoot) + if err != nil { + return nil, err + } + targetsRaw, err := c.uptane.TargetsMeta() + if err != nil { + return nil, err + } + canonicalTargets, err := enforceCanonicalJSON(targetsRaw) + if err != nil { + return nil, err + } + return &state.Update{ TUFRoots: roots, TUFTargets: canonicalTargets, diff --git a/pkg/config/remote/service/service_test.go b/pkg/config/remote/service/service_test.go index 40d8302db3192..34175eea2feba 100644 --- a/pkg/config/remote/service/service_test.go +++ b/pkg/config/remote/service/service_test.go @@ -116,6 +116,11 @@ func (m *mockUptane) TargetFile(path string) ([]byte, error) { return args.Get(0).([]byte), args.Error(1) } +func (m *mockUptane) TargetFiles(files []string) (map[string][]byte, error) { + args := m.Called(files) + return args.Get(0).(map[string][]byte), args.Error(1) +} + func (m *mockUptane) TargetsMeta() ([]byte, error) { args := m.Called() return args.Get(0).([]byte), args.Error(1) @@ -486,8 +491,8 @@ func TestService(t *testing.T) { }, nil) uptaneClient.On("DirectorRoot", uint64(3)).Return(root3, nil) uptaneClient.On("DirectorRoot", uint64(4)).Return(root4, nil) - uptaneClient.On("TargetFile", "datadog/2/APM_SAMPLING/id/1").Return(fileAPM1, nil) - uptaneClient.On("TargetFile", "datadog/2/APM_SAMPLING/id/2").Return(fileAPM2, nil) + + uptaneClient.On("TargetFiles", mock.MatchedBy(listsEqual([]string{"datadog/2/APM_SAMPLING/id/1", "datadog/2/APM_SAMPLING/id/2"}))).Return(map[string][]byte{"datadog/2/APM_SAMPLING/id/1": fileAPM1, "datadog/2/APM_SAMPLING/id/2": fileAPM2}, nil) uptaneClient.On("Update", lastConfigResponse).Return(nil) api.On("Fetch", mock.Anything, &pbgo.LatestConfigsRequest{ Hostname: service.hostname, @@ -513,7 +518,7 @@ func TestService(t *testing.T) { configResponse, err := service.ClientGetConfigs(context.Background(), &pbgo.ClientGetConfigsRequest{Client: client}) assert.NoError(t, err) assert.ElementsMatch(t, [][]byte{canonicalRoot3, canonicalRoot4}, configResponse.Roots) - assert.ElementsMatch(t, []*pbgo.File{{Path: "datadog/2/APM_SAMPLING/id/1", Raw: fileAPM1}, {Path: "datadog/2/APM_SAMPLING/id/2", Raw: fileAPM2}}, configResponse.TargetFiles) + assert.ElementsMatch(t, []*pbgo.File{{Path: "datadog/2/APM_SAMPLING/id/1", Raw: fileAPM1}, {Path: "datadog/2/APM_SAMPLING/id/2", Raw: fileAPM2}}, configResponse.TargetFiles, nil) assert.Equal(t, canonicalTargets, configResponse.Targets) assert.ElementsMatch(t, configResponse.ClientConfigs, @@ -597,8 +602,7 @@ func TestServiceClientPredicates(t *testing.T) { DirectorRoot: 1, DirectorTargets: 5, }, nil) - uptaneClient.On("TargetFile", "datadog/2/APM_SAMPLING/id/1").Return([]byte(``), nil) - uptaneClient.On("TargetFile", "datadog/2/APM_SAMPLING/id/2").Return([]byte(``), nil) + uptaneClient.On("TargetFiles", mock.MatchedBy(listsEqual([]string{"datadog/2/APM_SAMPLING/id/1", "datadog/2/APM_SAMPLING/id/2"}))).Return(map[string][]byte{"datadog/2/APM_SAMPLING/id/1": []byte(``), "datadog/2/APM_SAMPLING/id/2": []byte(``)}, nil) uptaneClient.On("Update", lastConfigResponse).Return(nil) api.On("Fetch", mock.Anything, &pbgo.LatestConfigsRequest{ Hostname: service.hostname, @@ -887,8 +891,7 @@ func TestConfigExpiration(t *testing.T) { DirectorRoot: 1, DirectorTargets: 5, }, nil) - uptaneClient.On("TargetFile", "datadog/2/APM_SAMPLING/id/1").Return([]byte(``), nil) - uptaneClient.On("TargetFile", "datadog/2/APM_SAMPLING/id/2").Return([]byte(``), nil) + uptaneClient.On("TargetFiles", []string{"datadog/2/APM_SAMPLING/id/1"}).Return(map[string][]byte{"datadog/2/APM_SAMPLING/id/1": []byte(``), "datadog/2/APM_SAMPLING/id/2": []byte(``)}, nil) uptaneClient.On("Update", lastConfigResponse).Return(nil) api.On("Fetch", mock.Anything, &pbgo.LatestConfigsRequest{ Hostname: service.hostname, @@ -1190,7 +1193,7 @@ func TestHTTPClientRecentUpdate(t *testing.T) { }, nil, ) - uptaneClient.On("TargetFile", "datadog/2/TESTING1/id/1").Return([]byte(`testing_1`), nil) + uptaneClient.On("TargetFiles", []string{"datadog/2/TESTING1/id/1"}).Return(map[string][]byte{"datadog/2/TESTING1/id/1": []byte(`testing_1`)}, nil) client := setupCDNClient(t, uptaneClient) defer client.Close() @@ -1236,7 +1239,7 @@ func TestHTTPClientUpdateSuccess(t *testing.T) { }, nil, ) - uptaneClient.On("TargetFile", "datadog/2/TESTING1/id/1").Return([]byte(`testing_1`), nil) + uptaneClient.On("TargetFiles", []string{"datadog/2/TESTING1/id/1"}).Return(map[string][]byte{"datadog/2/TESTING1/id/1": []byte(`testing_1`)}, nil) updateErr := fmt.Errorf("uh oh") if tt.updateSucceeds { @@ -1261,3 +1264,24 @@ func TestHTTPClientUpdateSuccess(t *testing.T) { }) } } + +func listsEqual(mustMatch []string) func(candidate []string) bool { + return func(candidate []string) bool { + if len(candidate) != len(mustMatch) { + return false + } + + candidateSet := make(map[string]struct{}) + for _, item := range candidate { + candidateSet[item] = struct{}{} + } + + for _, item := range mustMatch { + if _, ok := candidateSet[item]; !ok { + return false + } + } + + return true + } +} diff --git a/pkg/config/remote/uptane/client.go b/pkg/config/remote/uptane/client.go index b4da1c675b296..fcd1d3834b478 100644 --- a/pkg/config/remote/uptane/client.go +++ b/pkg/config/remote/uptane/client.go @@ -342,6 +342,37 @@ func (c *Client) TargetFile(path string) ([]byte, error) { return c.unsafeTargetFile(path) } +// TargetFiles returns the content of various multiple target files if the repository is in a +// verified state. +func (c *Client) TargetFiles(targetFiles []string) (map[string][]byte, error) { + c.Lock() + defer c.Unlock() + + err := c.verify() + if err != nil { + return nil, err + } + + // Build the storage space + destinations := make(map[string]client.Destination) + for _, path := range targetFiles { + destinations[path] = &bufferDestination{} + } + + err = c.directorTUFClient.DownloadBatch(destinations) + if err != nil { + return nil, err + } + + // Build the return type + files := make(map[string][]byte) + for path, contents := range destinations { + files[path] = contents.(*bufferDestination).Bytes() + } + + return files, nil +} + // TargetsMeta returns the current raw targets.json meta of this uptane client func (c *Client) TargetsMeta() ([]byte, error) { c.Lock() diff --git a/pkg/config/setup/go.mod b/pkg/config/setup/go.mod index b7c9ff41de81b..efed57c318b83 100644 --- a/pkg/config/setup/go.mod +++ b/pkg/config/setup/go.mod @@ -73,7 +73,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/pkg/config/setup/go.sum b/pkg/config/setup/go.sum index 7f15a6d221890..eb1a58f09f4b8 100644 --- a/pkg/config/setup/go.sum +++ b/pkg/config/setup/go.sum @@ -91,8 +91,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/config/utils/go.mod b/pkg/config/utils/go.mod index 5fc90b2da63fd..ef80f1fde725b 100644 --- a/pkg/config/utils/go.mod +++ b/pkg/config/utils/go.mod @@ -66,7 +66,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/pkg/config/utils/go.sum b/pkg/config/utils/go.sum index 3f00397cbc301..7fdf16db5981c 100644 --- a/pkg/config/utils/go.sum +++ b/pkg/config/utils/go.sum @@ -86,8 +86,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/flare/archive.go b/pkg/flare/archive.go index c3e5dffe00ca8..b61c6d9dd6ed2 100644 --- a/pkg/flare/archive.go +++ b/pkg/flare/archive.go @@ -214,7 +214,7 @@ func getExpVar(fb flaretypes.FlareBuilder) error { apmDebugPort := pkgconfigsetup.Datadog().GetInt("apm_config.debug.port") f := filepath.Join("expvar", "trace-agent") - resp, err := http.Get(fmt.Sprintf("http://127.0.0.1:%d/debug/vars", apmDebugPort)) + resp, err := http.Get(fmt.Sprintf("https://127.0.0.1:%d/debug/vars", apmDebugPort)) if err != nil { return fb.AddFile(f, []byte(fmt.Sprintf("Error retrieving vars: %v", err))) } diff --git a/pkg/flare/archive_win.go b/pkg/flare/archive_win.go index e62f23d58a8dc..96afe5ac17a94 100644 --- a/pkg/flare/archive_win.go +++ b/pkg/flare/archive_win.go @@ -31,7 +31,7 @@ var ( eventLogChannelsToExport = map[string]string{ "System": "Event/System/Provider[@Name=\"Service Control Manager\"]", - "Application": "Event/System/Provider[@Name=\"datadog-trace-agent\" or @Name=\"DatadogAgent\"]", + "Application": "Event/System/Provider[@Name=\"datadog-trace-agent\" or @Name=\"DatadogAgent\" or @Name=\".NET Runtime\" or @Name=\"Application Error\"]", "Microsoft-Windows-WMI-Activity/Operational": "*", } execTimeout = 30 * time.Second diff --git a/pkg/fleet/daemon/daemon.go b/pkg/fleet/daemon/daemon.go index 63ed3e2a3a626..ba79d5456dd3e 100644 --- a/pkg/fleet/daemon/daemon.go +++ b/pkg/fleet/daemon/daemon.go @@ -140,7 +140,34 @@ func (d *daemonImpl) GetState() (map[string]repository.State, error) { d.m.Lock() defer d.m.Unlock() - return d.installer.States() + states, err := d.installer.States() + if err != nil { + return nil, err + } + + var configStates map[string]repository.State + if d.env.RemotePolicies { + configStates, err = d.installer.ConfigStates() + if err != nil { + return nil, err + } + } + + res := make(map[string]repository.State) + for pkg, state := range states { + res[pkg] = state + } + for pkg, state := range configStates { + if _, ok := res[pkg]; !ok { + res[pkg] = repository.State{ + Stable: "", + Experiment: "", + StablePoliciesState: state.StablePoliciesState, + ExperimentPoliciesState: state.ExperimentPoliciesState, + } + } + } + return res, nil } // GetRemoteConfigState returns the remote config state. @@ -599,17 +626,24 @@ func (d *daemonImpl) refreshState(ctx context.Context) { log.Errorf("could not get available size: %v", err) } + for pkg, configState := range configState { + if _, ok := state[pkg]; !ok { + state[pkg] = repository.State{} + } + tmp := state[pkg] + tmp.StablePoliciesState = configState.StablePoliciesState + tmp.ExperimentPoliciesState = configState.ExperimentPoliciesState + state[pkg] = tmp + } + var packages []*pbgo.PackageState for pkg, s := range state { p := &pbgo.PackageState{ - Package: pkg, - StableVersion: s.Stable, - ExperimentVersion: s.Experiment, - } - cs, hasConfig := configState[pkg] - if hasConfig { - p.StableConfigState = cs.StablePoliciesState - p.ExperimentConfigState = cs.ExperimentPoliciesState + Package: pkg, + StableVersion: s.Stable, + ExperimentVersion: s.Experiment, + StableConfigState: s.StablePoliciesState, + ExperimentConfigState: s.ExperimentPoliciesState, } configState, err := d.resolveRemoteConfigVersion(ctx, pkg) diff --git a/pkg/fleet/installer/installer.go b/pkg/fleet/installer/installer.go index 3dd39b8fddb81..d9a2a910f45ef 100644 --- a/pkg/fleet/installer/installer.go +++ b/pkg/fleet/installer/installer.go @@ -34,6 +34,7 @@ import ( const ( packageDatadogAgent = "datadog-agent" packageAPMInjector = "datadog-apm-inject" + packageAPMLibraries = "datadog-apm-libraries" packageDatadogInstaller = "datadog-installer" ) @@ -210,6 +211,16 @@ func (i *installerImpl) Install(ctx context.Context, url string, args []string) if err != nil { return fmt.Errorf("could not configure package: %w", err) } + if pkg.Name == packageDatadogInstaller { + // We must handle the configuration of some packages that are not + // don't have an OCI. To properly configure their configuration repositories, + // we call configurePackage when setting up the installer; which is the only + // package that is always installed. + err = i.configurePackage(ctx, packageAPMLibraries) + if err != nil { + return fmt.Errorf("could not configure package: %w", err) + } + } err = i.setupPackage(ctx, pkg.Name, args) // Postinst if err != nil { return fmt.Errorf("could not setup package: %w", err) @@ -662,7 +673,7 @@ func (i *installerImpl) configurePackage(ctx context.Context, pkg string) (err e defer func() { span.Finish(err) }() switch pkg { - case packageDatadogAgent, packageAPMInjector: + case packageDatadogAgent, packageAPMInjector, packageAPMLibraries: config, err := i.cdn.Get(ctx, pkg) if err != nil { return fmt.Errorf("could not get %s CDN config: %w", pkg, err) diff --git a/pkg/fleet/installer/oci/download.go b/pkg/fleet/installer/oci/download.go index 9260d19bc0e97..7fcce0234512c 100644 --- a/pkg/fleet/installer/oci/download.go +++ b/pkg/fleet/installer/oci/download.go @@ -20,7 +20,6 @@ import ( "syscall" "time" - "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" oci "github.com/google/go-containerregistry/pkg/v1" @@ -44,8 +43,6 @@ const ( RegistryAuthDefault string = "docker" // RegistryAuthGCR is the Google Container Registry authentication method. RegistryAuthGCR string = "gcr" - // RegistryAuthECR is the Amazon Elastic Container Registry authentication method. - RegistryAuthECR string = "ecr" // RegistryAuthPassword is the password registry authentication method. RegistryAuthPassword string = "password" ) @@ -154,8 +151,6 @@ func getKeychain(auth string, username string, password string) authn.Keychain { switch auth { case RegistryAuthGCR: return google.Keychain - case RegistryAuthECR: - return authn.NewKeychainFromHelper(ecr.NewECRHelper()) case RegistryAuthPassword: return usernamePasswordKeychain{ username: username, diff --git a/pkg/fleet/installer/packages/datadog_agent.go b/pkg/fleet/installer/packages/datadog_agent.go index 34dbac394050f..c3b56f0e9c87b 100644 --- a/pkg/fleet/installer/packages/datadog_agent.go +++ b/pkg/fleet/installer/packages/datadog_agent.go @@ -60,6 +60,7 @@ var ( "system-probe.yaml", "inject/tracer.yaml", "inject", + "managed", } // matches omnibus/package-scripts/agent-deb/postinst rootOwnedAgentPaths = []string{ diff --git a/pkg/fleet/installer/packages/datadog_agent_windows.go b/pkg/fleet/installer/packages/datadog_agent_windows.go index 69935fdee41d8..48e3e1e00148c 100644 --- a/pkg/fleet/installer/packages/datadog_agent_windows.go +++ b/pkg/fleet/installer/packages/datadog_agent_windows.go @@ -10,10 +10,13 @@ package packages import ( "context" "fmt" - + "github.com/DataDog/datadog-agent/pkg/fleet/internal/msi" + "github.com/DataDog/datadog-agent/pkg/fleet/internal/paths" "github.com/DataDog/datadog-agent/pkg/fleet/internal/winregistry" "github.com/DataDog/datadog-agent/pkg/fleet/telemetry" "github.com/DataDog/datadog-agent/pkg/util/log" + "os" + "path" ) const ( @@ -29,9 +32,8 @@ func PrepareAgent(_ context.Context) error { func SetupAgent(ctx context.Context, args []string) (err error) { span, _ := telemetry.StartSpanFromContext(ctx, "setup_agent") defer func() { - if err != nil { - log.Errorf("Failed to setup agent: %s", err) - } + // Don't log error here, or it will appear twice in the output + // since installerImpl.Install will also print the error. span.Finish(err) }() // Make sure there are no Agent already installed @@ -108,20 +110,38 @@ func installAgentPackage(target string, args []string) error { if err != nil { return fmt.Errorf("failed to get Agent user: %w", err) } - args = append(args, fmt.Sprintf("DDAGENTUSER_NAME=%s", agentUser)) - cmd, err := msiexec(target, datadogAgent, "/i", args) + rootPath := "" + _, err = os.Stat(paths.RootTmpDir) + // If bootstrap has not been called before, `paths.RootTmpDir` might not exist + if os.IsExist(err) { + rootPath = paths.RootTmpDir + } + tempDir, err := os.MkdirTemp(rootPath, "datadog-agent") + if err != nil { + return err + } + logFile := path.Join(tempDir, "msi.log") + + cmd, err := msi.Cmd( + msi.Install(), + msi.WithMsiFromPackagePath(target, datadogAgent), + msi.WithDdAgentUserName(agentUser), + msi.WithAdditionalArgs(args), + msi.WithLogFile(path.Join(tempDir, "msi.log")), + ) + var output []byte if err == nil { - err = cmd.Run() + output, err = cmd.Run() } if err != nil { - return fmt.Errorf("failed to install Agent %s: %w", target, err) + return fmt.Errorf("failed to install Agent %s: %w\nLog file located at: %s\n%s", target, err, logFile, string(output)) } return nil } func removeAgentIfInstalled(ctx context.Context) (err error) { - if isProductInstalled("Datadog Agent") { + if msi.IsProductInstalled("Datadog Agent") { span, _ := telemetry.StartSpanFromContext(ctx, "remove_agent") defer func() { if err != nil { @@ -131,7 +151,7 @@ func removeAgentIfInstalled(ctx context.Context) (err error) { } span.Finish(err) }() - err := removeProduct("Datadog Agent") + err := msi.RemoveProduct("Datadog Agent") if err != nil { return err } diff --git a/pkg/fleet/installer/packages/datadog_installer_windows.go b/pkg/fleet/installer/packages/datadog_installer_windows.go index d7714ddb257cc..6a4b313120840 100644 --- a/pkg/fleet/installer/packages/datadog_installer_windows.go +++ b/pkg/fleet/installer/packages/datadog_installer_windows.go @@ -10,9 +10,11 @@ package packages import ( "context" - - "github.com/DataDog/datadog-agent/pkg/fleet/telemetry" - "github.com/DataDog/datadog-agent/pkg/util/log" + "fmt" + "github.com/DataDog/datadog-agent/pkg/fleet/internal/msi" + "github.com/DataDog/datadog-agent/pkg/fleet/internal/paths" + "os" + "path" ) const ( @@ -20,68 +22,62 @@ const ( ) // SetupInstaller installs and starts the installer -func SetupInstaller(ctx context.Context) (err error) { - span, _ := telemetry.StartSpanFromContext(ctx, "setup_installer") - defer func() { - if err != nil { - log.Errorf("Failed to setup installer: %s", err) - } - span.Finish(err) - }() - cmd, err := msiexec("stable", datadogInstaller, "/i", nil) - if err == nil { - // This is the first time that we are installing the installer, - // so we can run it synchronously. - err = cmd.Run() +func SetupInstaller(_ context.Context) error { + rootPath := "" + _, err := os.Stat(paths.RootTmpDir) + // If bootstrap has not been called before, `paths.RootTmpDir` might not exist + if os.IsExist(err) { + rootPath = paths.RootTmpDir + } + tempDir, err := os.MkdirTemp(rootPath, "datadog-installer") + if err != nil { + return err + } + + cmd, err := msi.Cmd(msi.Install(), msi.WithMsiFromPackagePath("stable", datadogInstaller), msi.WithLogFile(path.Join(tempDir, "setup_installer.log"))) + if err != nil { + return fmt.Errorf("failed to setup installer: %w", err) + } + output, err := cmd.Run() + if err != nil { + return fmt.Errorf("failed to setup installer: %w\n%s", err, string(output)) } - return err + return nil } // RemoveInstaller removes the installer -func RemoveInstaller(ctx context.Context) (err error) { - span, _ := telemetry.StartSpanFromContext(ctx, "remove_installer") - defer func() { - if err != nil { - log.Errorf("Failed to remove installer: %s", err) - } - span.Finish(err) - }() - err = removeProduct("Datadog Installer") - return err +func RemoveInstaller(_ context.Context) error { + return msi.RemoveProduct("Datadog Installer") } // StartInstallerExperiment starts the installer experiment -func StartInstallerExperiment(ctx context.Context) (err error) { - span, _ := telemetry.StartSpanFromContext(ctx, "start_installer_experiment") - defer func() { - if err != nil { - log.Errorf("Failed to start installer experiment: %s", err) - } - span.Finish(err) - }() - cmd, err := msiexec("experiment", datadogInstaller, "/i", nil) - if err == nil { - // Launch the msiexec process asynchronously. - err = cmd.Start() +func StartInstallerExperiment(_ context.Context) error { + tempDir, err := os.MkdirTemp(paths.RootTmpDir, "datadog-installer") + if err != nil { + return err + } + + cmd, err := msi.Cmd(msi.Install(), msi.WithMsiFromPackagePath("experiment", datadogInstaller), msi.WithLogFile(path.Join(tempDir, "start_installer_experiment.log"))) + if err != nil { + return fmt.Errorf("failed to start installer experiment: %w", err) } - return err + // Launch the msiexec process asynchronously. + return cmd.FireAndForget() } // StopInstallerExperiment stops the installer experiment -func StopInstallerExperiment(ctx context.Context) (err error) { - span, _ := telemetry.StartSpanFromContext(ctx, "stop_installer_experiment") - defer func() { - if err != nil { - log.Errorf("Failed to stop installer experiment: %s", err) - } - span.Finish(err) - }() - cmd, err := msiexec("stable", datadogInstaller, "/i", nil) - if err == nil { - // Launch the msiexec process asynchronously. - err = cmd.Start() +func StopInstallerExperiment(_ context.Context) error { + tempDir, err := os.MkdirTemp(paths.RootTmpDir, "datadog-installer") + if err != nil { + return err + } + + cmd, err := msi.Cmd(msi.Install(), msi.WithMsiFromPackagePath("stable", datadogInstaller), msi.WithLogFile(path.Join(tempDir, "stop_installer_experiment.log"))) + if err != nil { + return fmt.Errorf("failed to stop installer experiment: %w", err) } - return err + // Launch the msiexec process asynchronously. + return cmd.FireAndForget() } // PromoteInstallerExperiment promotes the installer experiment diff --git a/pkg/fleet/installer/setup/common/config.go b/pkg/fleet/installer/setup/common/config.go index 650b6b0acebe7..7d9e00aba1483 100644 --- a/pkg/fleet/installer/setup/common/config.go +++ b/pkg/fleet/installer/setup/common/config.go @@ -103,6 +103,7 @@ type DatadogConfig struct { APIKey string `yaml:"api_key"` Hostname string `yaml:"hostname,omitempty"` Site string `yaml:"site,omitempty"` + Proxy DatadogConfigProxy `yaml:"proxy,omitempty"` Env string `yaml:"env,omitempty"` Tags []string `yaml:"tags,omitempty"` LogsEnabled bool `yaml:"logs_enabled,omitempty"` @@ -111,6 +112,13 @@ type DatadogConfig struct { ExpectedTagsDuration string `yaml:"expected_tags_duration,omitempty"` } +// DatadogConfigProxy represents the configuration for the proxy +type DatadogConfigProxy struct { + HTTP string `yaml:"http,omitempty"` + HTTPS string `yaml:"https,omitempty"` + NoProxy []string `yaml:"no_proxy,omitempty"` +} + // DatadogConfigDJM represents the configuration for the Data Jobs Monitoring type DatadogConfigDJM struct { Enabled bool `yaml:"enabled,omitempty"` diff --git a/pkg/fleet/installer/setup/common/setup.go b/pkg/fleet/installer/setup/common/setup.go index 60931ef01da69..0a7b93447c22f 100644 --- a/pkg/fleet/installer/setup/common/setup.go +++ b/pkg/fleet/installer/setup/common/setup.go @@ -12,6 +12,7 @@ import ( "fmt" "io" "os" + "strings" "time" "github.com/DataDog/datadog-agent/pkg/fleet/installer" @@ -60,6 +61,10 @@ Running the %s installation script (https://github.com/DataDog/datadog-agent/tre if err != nil { return nil, fmt.Errorf("failed to create installer: %w", err) } + var proxyNoProxy []string + if os.Getenv("DD_PROXY_NO_PROXY") != "" { + proxyNoProxy = strings.Split(os.Getenv("DD_PROXY_NO_PROXY"), ",") + } span, ctx := telemetry.StartSpanFromContext(ctx, fmt.Sprintf("setup.%s", flavor)) s := &Setup{ configDir: configDir, @@ -75,7 +80,12 @@ Running the %s installation script (https://github.com/DataDog/datadog-agent/tre APIKey: env.APIKey, Hostname: os.Getenv("DD_HOSTNAME"), Site: env.Site, - Env: os.Getenv("DD_ENV"), + Proxy: DatadogConfigProxy{ + HTTP: os.Getenv("DD_PROXY_HTTP"), + HTTPS: os.Getenv("DD_PROXY_HTTPS"), + NoProxy: proxyNoProxy, + }, + Env: os.Getenv("DD_ENV"), }, IntegrationConfigs: make(map[string]IntegrationConfig), }, diff --git a/pkg/fleet/internal/bootstrap/bootstrap_windows.go b/pkg/fleet/internal/bootstrap/bootstrap_windows.go index 6990ec77cf042..7172d02a1b6a9 100644 --- a/pkg/fleet/internal/bootstrap/bootstrap_windows.go +++ b/pkg/fleet/internal/bootstrap/bootstrap_windows.go @@ -11,8 +11,8 @@ package bootstrap import ( "context" "fmt" + "github.com/DataDog/datadog-agent/pkg/fleet/internal/msi" "os" - "os/exec" "path/filepath" "github.com/DataDog/datadog-agent/pkg/fleet/installer/env" @@ -81,20 +81,19 @@ func downloadInstaller(ctx context.Context, env *env.Env, url string, tmpDir str } else if len(msis) == 0 { return nil, fmt.Errorf("no MSIs in package") } - msiArgs := []string{ - "/i", - msis[0], - "/qn", - "MSIFASTINSTALL=7", - } - if env.AgentUserName != "" { - msiArgs = append(msiArgs, fmt.Sprintf("DDAGENTUSER_NAME=%s", env.AgentUserName)) - // don't need to look at the registry here since the installer will read it if the command line - // parameter is not provided + + cmd, err := msi.Cmd( + msi.Install(), + msi.WithMsi(msis[0]), + msi.WithDdAgentUserName(env.AgentUserName), + ) + var output []byte + if err == nil { + output, err = cmd.Run() } - err = exec.Command("msiexec", msiArgs...).Run() + if err != nil { - return nil, fmt.Errorf("failed to install the Datadog Installer") + return nil, fmt.Errorf("failed to install the Datadog Installer: %w\n%s", err, string(output)) } return iexec.NewInstallerExec(env, paths.StableInstallerPath), nil } diff --git a/pkg/fleet/internal/cdn/cdn.go b/pkg/fleet/internal/cdn/cdn.go index 4f65108dfa90f..f35418cc0b7bc 100644 --- a/pkg/fleet/internal/cdn/cdn.go +++ b/pkg/fleet/internal/cdn/cdn.go @@ -7,6 +7,7 @@ package cdn import ( + "bytes" "context" "encoding/json" "errors" @@ -18,9 +19,13 @@ import ( "github.com/DataDog/datadog-agent/pkg/fleet/installer/env" "github.com/DataDog/datadog-agent/pkg/fleet/telemetry" pbgo "github.com/DataDog/datadog-agent/pkg/proto/pbgo/core" + "gopkg.in/yaml.v2" ) -const policyMetadataFilename = "policy.metadata" +const ( + policyMetadataFilename = "policy.metadata" + doNotEditDisclaimer = `# This configuration was generated by Datadog's Fleet Automation. DO NOT EDIT.` +) var ( // ErrProductNotSupported is returned when the product is not supported. @@ -134,7 +139,16 @@ func (c *CDN) Get(ctx context.Context, pkg string) (cfg Config, err error) { if err != nil { return nil, err } - cfg, err = newAPMConfig(c.hostTagsGetter.get(), orderedLayers...) + cfg, err = newAPMSSIConfig(c.hostTagsGetter.get(), orderedLayers...) + if err != nil { + return nil, err + } + case "datadog-apm-libraries": + orderedLayers, err := c.fetcher.get(ctx) + if err != nil { + return nil, err + } + cfg, err = newAPMLibrariesConfig(c.hostTagsGetter.get(), orderedLayers...) if err != nil { return nil, err } @@ -175,3 +189,19 @@ func writePolicyMetadata(config Config, dir string) error { } return nil } + +// marshalYAMLConfig marshals the config as YAML. +func marshalYAMLConfig(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_datadog_agent.go b/pkg/fleet/internal/cdn/config_datadog_agent.go index b9882ebaad469..71e96d0d2655e 100644 --- a/pkg/fleet/internal/cdn/config_datadog_agent.go +++ b/pkg/fleet/internal/cdn/config_datadog_agent.go @@ -6,7 +6,6 @@ package cdn import ( - "bytes" "crypto/sha256" "encoding/json" "fmt" @@ -18,12 +17,10 @@ import ( pbgo "github.com/DataDog/datadog-agent/pkg/proto/pbgo/core" "github.com/DataDog/datadog-agent/pkg/util/log" - "gopkg.in/yaml.v2" ) const ( - layerKeys = "fleet_layers" - doNotEditDisclaimer = `# This configuration was generated by Datadog's Fleet Automation. DO NOT EDIT.` + layerKeys = "fleet_layers" configDatadogYAML = "datadog.yaml" configSecurityAgentYAML = "security-agent.yaml" @@ -106,15 +103,15 @@ func newAgentConfig(orderedLayers ...[]byte) (*agentConfig, error) { compiledLayer.AgentConfig[layerKeys] = policyIDs // Marshal into YAML configs - config, err := marshalAgentConfig(compiledLayer.AgentConfig) + config, err := marshalYAMLConfig(compiledLayer.AgentConfig) if err != nil { return nil, err } - securityAgentConfig, err := marshalAgentConfig(compiledLayer.SecurityAgentConfig) + securityAgentConfig, err := marshalYAMLConfig(compiledLayer.SecurityAgentConfig) if err != nil { return nil, err } - systemProbeConfig, err := marshalAgentConfig(compiledLayer.SystemProbeConfig) + systemProbeConfig, err := marshalYAMLConfig(compiledLayer.SystemProbeConfig) if err != nil { return nil, err } @@ -182,22 +179,6 @@ func (a *agentConfig) Write(dir string) error { return writePolicyMetadata(a, dir) } -// marshalAgentConfig marshals the config as YAML. -func marshalAgentConfig(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 -} - // getAgentIDs returns the UID and GID of the dd-agent user and group. func getAgentIDs() (uid, gid int, err error) { ddAgentUser, err := user.Lookup("dd-agent") diff --git a/pkg/fleet/internal/cdn/config_datadog_apm.go b/pkg/fleet/internal/cdn/config_datadog_apm_inject.go similarity index 83% rename from pkg/fleet/internal/cdn/config_datadog_apm.go rename to pkg/fleet/internal/cdn/config_datadog_apm_inject.go index fd171f06e0d92..f5cc04894b7f7 100644 --- a/pkg/fleet/internal/cdn/config_datadog_apm.go +++ b/pkg/fleet/internal/cdn/config_datadog_apm_inject.go @@ -21,37 +21,37 @@ const ( injectorConfigFilename = "injector.msgpack" ) -// apmConfig represents the injector configuration from the CDN. -type apmConfig struct { +// apmSSIConfig represents the injector configuration from the CDN. +type apmSSIConfig struct { version string policyIDs []string injectorConfig []byte } -// apmConfigLayer is a config layer that can be merged with other layers into a config. -type apmConfigLayer struct { +// apmSSIConfigLayer is a config layer that can be merged with other layers into a config. +type apmSSIConfigLayer struct { ID string `json:"name"` InjectorConfig map[string]interface{} `json:"apm_ssi_config"` } // State returns the APM configs state -func (i *apmConfig) State() *pbgo.PoliciesState { +func (i *apmSSIConfig) State() *pbgo.PoliciesState { return &pbgo.PoliciesState{ MatchedPolicies: i.policyIDs, Version: i.version, } } -func newAPMConfig(hostTags []string, orderedLayers ...[]byte) (*apmConfig, error) { +func newAPMSSIConfig(hostTags []string, orderedLayers ...[]byte) (*apmSSIConfig, error) { // Compile ordered layers into a single config // TODO: maybe we don't want that and we should reject if there are more than one config? policyIDs := []string{} - compiledLayer := &apmConfigLayer{ + compiledLayer := &apmSSIConfigLayer{ InjectorConfig: map[string]interface{}{}, } for _, rawLayer := range orderedLayers { - layer := &apmConfigLayer{} + layer := &apmSSIConfigLayer{} if err := json.Unmarshal(rawLayer, layer); err != nil { log.Warnf("Failed to unmarshal layer: %v", err) continue @@ -84,7 +84,7 @@ func newAPMConfig(hostTags []string, orderedLayers ...[]byte) (*apmConfig, error return nil, err } - return &apmConfig{ + return &apmSSIConfig{ version: fmt.Sprintf("%x", hash.Sum(nil)), policyIDs: policyIDs, @@ -93,7 +93,7 @@ func newAPMConfig(hostTags []string, orderedLayers ...[]byte) (*apmConfig, error } // Write writes the agent configuration to the given directory. -func (i *apmConfig) Write(dir string) error { +func (i *apmSSIConfig) Write(dir string) error { if i.injectorConfig != nil { err := os.WriteFile(filepath.Join(dir, injectorConfigFilename), []byte(i.injectorConfig), 0644) // Must be world readable if err != nil { diff --git a/pkg/fleet/internal/cdn/config_datadog_apm_libraries.go b/pkg/fleet/internal/cdn/config_datadog_apm_libraries.go new file mode 100644 index 0000000000000..bf31d18bd69a3 --- /dev/null +++ b/pkg/fleet/internal/cdn/config_datadog_apm_libraries.go @@ -0,0 +1,101 @@ +// 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 ( + "crypto/sha256" + "encoding/json" + "fmt" + "os" + "path/filepath" + + pbgo "github.com/DataDog/datadog-agent/pkg/proto/pbgo/core" + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +const ( + apmLibrariesConfigPath = "libraries_config.yaml" +) + +// apmLibrariesConfig represents the injector configuration from the CDN. +type apmLibrariesConfig struct { + version string + policyIDs []string + + apmLibrariesConfig []byte +} + +// apmLibrariesConfigLayer is a config layer that can be merged with other layers into a config. +type apmLibrariesConfigLayer struct { + ID string `json:"name"` + APMLibrariesConfig map[string]interface{} `json:"apm_libraries_config"` +} + +// State returns the APM configs state +func (i *apmLibrariesConfig) State() *pbgo.PoliciesState { + return &pbgo.PoliciesState{ + MatchedPolicies: i.policyIDs, + Version: i.version, + } +} + +func newAPMLibrariesConfig(hostTags []string, orderedLayers ...[]byte) (*apmLibrariesConfig, error) { + // Compile ordered layers into a single config + policyIDs := []string{} + compiledLayer := &apmLibrariesConfigLayer{ + APMLibrariesConfig: map[string]interface{}{}, + } + for _, rawLayer := range orderedLayers { + layer := &apmLibrariesConfigLayer{} + if err := json.Unmarshal(rawLayer, layer); err != nil { + log.Warnf("Failed to unmarshal layer: %v", err) + continue + } + + if layer.APMLibrariesConfig != nil { + cfg, err := merge(compiledLayer.APMLibrariesConfig, layer.APMLibrariesConfig) + if err != nil { + return nil, err + } + compiledLayer.APMLibrariesConfig = cfg.(map[string]interface{}) + policyIDs = append(policyIDs, layer.ID) + } + } + + hash := sha256.New() + version, err := json.Marshal(compiledLayer) + if err != nil { + return nil, err + } + hash.Write(version) + + // Add host tags AFTER compiling the version -- we don't want to trigger noop updates + compiledLayer.APMLibrariesConfig["host_tags"] = hostTags + + // Marshal into msgpack configs + yamlCfg, err := marshalYAMLConfig(compiledLayer.APMLibrariesConfig) + if err != nil { + return nil, err + } + + return &apmLibrariesConfig{ + version: fmt.Sprintf("%x", hash.Sum(nil)), + policyIDs: policyIDs, + + apmLibrariesConfig: yamlCfg, + }, nil +} + +// Write writes the agent configuration to the given directory. +func (i *apmLibrariesConfig) Write(dir string) error { + if i.apmLibrariesConfig != nil { + err := os.WriteFile(filepath.Join(dir, apmLibrariesConfigPath), []byte(i.apmLibrariesConfig), 0644) // Must be world readable + if err != nil { + return fmt.Errorf("could not write %s: %w", apmLibrariesConfigPath, err) + } + } + return writePolicyMetadata(i, dir) +} diff --git a/pkg/fleet/internal/cdn/scope_expression.go b/pkg/fleet/internal/cdn/scope_expression.go index 659d6798c0670..cc86626fcf9c0 100644 --- a/pkg/fleet/internal/cdn/scope_expression.go +++ b/pkg/fleet/internal/cdn/scope_expression.go @@ -10,7 +10,9 @@ import ( "fmt" "regexp" + "github.com/DataDog/datadog-agent/comp/metadata/host/hostimpl/utils" "github.com/DataDog/datadog-agent/pkg/fleet/installer/env" + "github.com/DataDog/datadog-agent/pkg/gohai/platform" "github.com/DataDog/datadog-agent/pkg/version" "github.com/expr-lang/expr" ) @@ -115,6 +117,8 @@ func getScopeExprVars(env *env.Env, hostTagsGetter hostTagsGetter) map[string]in return map[string]interface{}{ "hostname": env.Hostname, "installer_version": version.AgentVersion, // AgentVersion evaluates to the installer version here + "os": platform.CollectInfo().KernelName.ValueOrDefault(), + "os_version": utils.GetOSVersion(), "tags": hostTagsGetter.get(), } diff --git a/pkg/fleet/internal/msi/file_in_use.log b/pkg/fleet/internal/msi/file_in_use.log new file mode 100644 index 0000000000000..eb0ad60b3ddd6 Binary files /dev/null and b/pkg/fleet/internal/msi/file_in_use.log differ diff --git a/pkg/fleet/internal/msi/invalid_credentials.log b/pkg/fleet/internal/msi/invalid_credentials.log new file mode 100644 index 0000000000000..3d568391bdb12 Binary files /dev/null and b/pkg/fleet/internal/msi/invalid_credentials.log differ diff --git a/pkg/fleet/internal/msi/missing_password_for_dc.log b/pkg/fleet/internal/msi/missing_password_for_dc.log new file mode 100644 index 0000000000000..c87c3dc183493 Binary files /dev/null and b/pkg/fleet/internal/msi/missing_password_for_dc.log differ diff --git a/pkg/fleet/internal/msi/msiexec.go b/pkg/fleet/internal/msi/msiexec.go new file mode 100644 index 0000000000000..f2ca387fb3aa2 --- /dev/null +++ b/pkg/fleet/internal/msi/msiexec.go @@ -0,0 +1,289 @@ +// 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 msi contains helper functions to work with msi packages +package msi + +import ( + "errors" + "fmt" + "github.com/DataDog/datadog-agent/pkg/fleet/internal/paths" + "io/fs" + "os" + "os/exec" + "path" + "path/filepath" + "regexp" +) + +type msiexecArgs struct { + // target should be either a full path to a MSI, an URL to a MSI or a product code. + target string + + // msiAction should be "/i" for installation, "/x" for uninstallation etc... + msiAction string + + // logFile should be a full local path where msiexec will write the installation logs. + // If nothing is specified, a random, temporary file is used. + logFile string + ddagentUserName string + + // additionalArgs are further args that can be passed to msiexec + additionalArgs []string +} + +// MsiexecOption is an option type for creating msiexec command lines +type MsiexecOption func(*msiexecArgs) error + +// Install specifies that msiexec will be invoked to install a product +func Install() MsiexecOption { + return func(a *msiexecArgs) error { + a.msiAction = "/i" + return nil + } +} + +// Uninstall specifies that msiexec will be invoked to uninstall a product +func Uninstall() MsiexecOption { + return func(a *msiexecArgs) error { + a.msiAction = "/x" + return nil + } +} + +// WithMsi specifies the MSI target for msiexec +func WithMsi(target string) MsiexecOption { + return func(a *msiexecArgs) error { + a.target = target + return nil + } +} + +// WithMsiFromPackagePath finds an MSI from the packages folder +func WithMsiFromPackagePath(target, product string) MsiexecOption { + return func(a *msiexecArgs) error { + updaterPath := filepath.Join(paths.PackagesPath, product, target) + msis, err := filepath.Glob(filepath.Join(updaterPath, fmt.Sprintf("%s-*-1-x86_64.msi", product))) + if err != nil { + return err + } + if len(msis) > 1 { + return fmt.Errorf("too many MSIs in package") + } else if len(msis) == 0 { + return fmt.Errorf("no MSIs in package") + } + a.target = msis[0] + return nil + } +} + +// WithProduct specifies the product name to target for msiexec +func WithProduct(productName string) MsiexecOption { + return func(a *msiexecArgs) error { + product, err := FindProductCode(productName) + if err != nil { + return fmt.Errorf("error trying to find product %s: %w", productName, err) + } + a.target = product.Code + return nil + } +} + +// WithLogFile specifies the log file for msiexec +func WithLogFile(logFile string) MsiexecOption { + return func(a *msiexecArgs) error { + a.logFile = logFile + return nil + } +} + +// WithAdditionalArgs specifies additional arguments for msiexec +func WithAdditionalArgs(additionalArgs []string) MsiexecOption { + return func(a *msiexecArgs) error { + a.additionalArgs = additionalArgs + return nil + } +} + +// WithDdAgentUserName specifies the DDAGENTUSER_NAME to use +func WithDdAgentUserName(ddagentUserName string) MsiexecOption { + return func(a *msiexecArgs) error { + a.ddagentUserName = ddagentUserName + return nil + } +} + +// Msiexec is a type wrapping msiexec +type Msiexec struct { + *exec.Cmd + + // logFile is the path to the MSI log file + logFile string + + // postExecActions is a list of actions to be executed after msiexec has run + postExecActions []func() +} + +func (m *Msiexec) openAndProcessLogFile() ([]byte, error) { + logfile, err := os.Open(m.logFile) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + // File does not exist is not necessarily an error + return nil, nil + } + return nil, err + } + result, err := m.processLogFile(logfile) + _ = logfile.Close() + return result, err +} + +// processLogFile takes an open file and processes it with a series of processors to obtain +// a condensed version of the log file with only the relevant information. +func (m *Msiexec) processLogFile(logFile fs.File) ([]byte, error) { + // Compile a list of regular expressions we are interested in extracting from the logs + return processLogFile(logFile, + func(bytes []byte) []TextRange { + // Only need one TextRange of context before and after since other regexes will combine + return FindAllIndexWithContext(regexp.MustCompile("Datadog[.]CustomActions.*"), bytes, 1, 1) + }, + func(bytes []byte) []TextRange { + // Only need one TextRange of context before and after since other regexes will combine + return FindAllIndexWithContext(regexp.MustCompile("System[.]Exception"), bytes, 1, 1) + }, + func(bytes []byte) []TextRange { + // typically looks like this: + // Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.StartDDServices + // CA: 01:50:49: StartDDServices. Failed to start services: System.InvalidOperationException: Cannot start service datadogagent on computer '.'. ---> System.ComponentModel.Win32Exception: The service did not start due to a logon failure + // --- End of inner exception stack trace --- + // at System.ServiceProcess.ServiceController.Start(String args) + // at Datadog.CustomActions.Native.ServiceController.StartService(String serviceName, TimeSpan timeout) + // at Datadog.CustomActions.ServiceCustomAction.StartDDServices() + // Other regexes will pick up on the stack trace, but there's not much information to get before the error + return FindAllIndexWithContext(regexp.MustCompile("Cannot start service"), bytes, 1, 2) + }, + func(bytes []byte) []TextRange { + // Typically looks like this: + // CA(ddnpm): DriverInstall: serviceDef::create() + // CA(ddnpm): DriverInstall: Failed to CreateService 1073 + // CA(ddnpm): DriverInstall: Service exists, verifying + // CA(ddnpm): DriverInstall: Updated path for existing service + // So include a bit of context before and after + return FindAllIndexWithContext(regexp.MustCompile("Failed to CreateService"), bytes, 5, 5) + }, + func(bytes []byte) []TextRange { + // Typically looks like this: + // Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.ProcessDdAgentUserCredentials + // CA: 01:49:43: LookupAccountWithExtendedDomainSyntax. User not found, trying again with fixed domain part: \toto + // CA: 01:49:43: ProcessDdAgentUserCredentials. User toto doesn't exist. + // CA: 01:49:43: ProcessDdAgentUserCredentials. domain part is empty, using default + // CA: 01:49:43: ProcessDdAgentUserCredentials. Installing with DDAGENTUSER_PROCESSED_NAME=toto and DDAGENTUSER_PROCESSED_DOMAIN=datadoghq-qa-labs.local + // CA: 01:49:43: HandleProcessDdAgentUserCredentialsException. Error processing ddAgentUser credentials: Datadog.CustomActions.InvalidAgentUserConfigurationException: A password was not provided. A password is a required when installing on Domain Controllers. + // at Datadog.CustomActions.ProcessUserCustomActions.ProcessDdAgentUserCredentials(Boolean calledFromUIControl) + // MSI (s) (C8!50) [01:49:43:906]: Product: Datadog Agent -- A password was not provided. A password is a required when installing on Domain Controllers. + // + // A password was not provided. A password is a required when installing on Domain Controllers. + // CustomAction ProcessDdAgentUserCredentials returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) + // Action ended 1:49:43: ProcessDdAgentUserCredentials. Return value 3. + // So include lots of context to ensure we get the full picture + return FindAllIndexWithContext(regexp.MustCompile("A password was not provided"), bytes, 6, 6) + }, + func(bytes []byte) []TextRange { + // Typically looks like this: + // Info 1603. The file C:\Program Files\Datadog\Datadog Agent\bin\agent\process-agent.exe is being held in use by the following process: Name: process-agent, Id: 4704, Window Title: '(not determined yet)'. Close that application and retry. + // Not much context to be had before and after + return FindAllIndexWithContext(regexp.MustCompile("is being held in use by the following process"), bytes, 1, 1) + }, + func(bytes []byte) []TextRange { + // Typically looks like this: + // Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.StartDDServices + // CustomAction WixFailWhenDeferred returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) + // Action ended 2:11:49: InstallFinalize. Return value 3. + // The important context is the TextRange after the error ("Return value 3") but the previous lines can include some useful information too + return FindAllIndexWithContext(regexp.MustCompile("returned actual error"), bytes, 5, 1) + }, + func(bytes []byte) []TextRange { + // Typically looks like this: + // Action 12:24:00: InstallServices. Installing new services + // InstallServices: Service: + // Error 1923. Service 'Datadog Agent' (datadogagent) could not be installed. Verify that you have sufficient privileges to install system services. + // MSI (s) (54:EC) [12:25:53:886]: Product: Datadog Agent -- Error 1923. Service 'Datadog Agent' (datadogagent) could not be installed. Verify that you have sufficient privileges to install system services. + return FindAllIndexWithContext(regexp.MustCompile("Verify that you have sufficient privileges to install system services"), bytes, 2, 1) + }) +} + +// Run runs msiexec synchronously +func (m *Msiexec) Run() ([]byte, error) { + err := m.Cmd.Run() + // The log file *should not* be too big. Avoid verbose log files. + logFileBytes, err2 := m.openAndProcessLogFile() + err = errors.Join(err, err2) + for _, p := range m.postExecActions { + p() + } + + return logFileBytes, err +} + +// RunAsync runs msiexec asynchronously +func (m *Msiexec) RunAsync(done func([]byte, error)) error { + err := m.Cmd.Start() + if err != nil { + return err + } + go func() { + err := m.Cmd.Wait() + // The log file *should not* be too big. Avoid verbose log files. + logFileBytes, err2 := m.openAndProcessLogFile() + err = errors.Join(err, err2) + for _, p := range m.postExecActions { + p() + } + done(logFileBytes, err) + }() + return nil +} + +// FireAndForget starts msiexec and doesn't wait for it to finish. +// The log file won't be read at the end and post execution actions will not be executed. +func (m *Msiexec) FireAndForget() error { + return m.Cmd.Start() +} + +// Cmd creates a new Msiexec wrapper around cmd.Exec that will call msiexec +func Cmd(options ...MsiexecOption) (*Msiexec, error) { + a := &msiexecArgs{} + for _, opt := range options { + if err := opt(a); err != nil { + return nil, err + } + } + if a.msiAction == "" || a.target == "" { + return nil, fmt.Errorf("argument error") + } + + cmd := &Msiexec{} + if len(a.logFile) == 0 { + tempDir, err := os.MkdirTemp("", "datadog-installer") + if err != nil { + return nil, err + } + a.logFile = path.Join(tempDir, "msi.log") + cmd.postExecActions = append(cmd.postExecActions, func() { + _ = os.RemoveAll(tempDir) + }) + } + args := append(a.additionalArgs, a.msiAction, a.target, "/qn", "MSIFASTINSTALL=7", "/log", a.logFile) + if a.ddagentUserName != "" { + args = append(args, fmt.Sprintf("DDAGENTUSER_NAME=%s", a.ddagentUserName)) + } + + cmd.Cmd = exec.Command("msiexec", args...) + cmd.logFile = a.logFile + + return cmd, nil +} diff --git a/pkg/fleet/internal/msi/msilog.go b/pkg/fleet/internal/msi/msilog.go new file mode 100644 index 0000000000000..47f8ef5f30641 --- /dev/null +++ b/pkg/fleet/internal/msi/msilog.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 2016-present Datadog, Inc. + +//go:build windows + +// Package msi contains helper functions to work with msi packages +package msi + +import ( + "bytes" + "fmt" + "golang.org/x/text/encoding/unicode" + "io" + "io/fs" + "regexp" + "sort" +) + +// TextRange is a simple struct to represent a range of text in a file. +type TextRange struct { + start int + end int +} + +// FindAllIndexWithContext is similar to FindAllIndex but expands the matched range for a number of lines +// before and after the TextRange (called contextBefore and contextAfter). +func FindAllIndexWithContext(r *regexp.Regexp, input []byte, contextBefore, contextAfter int) []TextRange { + contextBefore = max(contextBefore, 0) + contextAfter = max(contextAfter, 0) + var extractedRanges []TextRange + results := r.FindAllIndex(input, -1) + for _, result := range results { + lineCounter := 0 + charCounter := result[0] + for ; charCounter >= 0; charCounter-- { + if input[charCounter] == '\n' { + lineCounter++ + } + if lineCounter > contextBefore { + break + } + } + lineStart := charCounter + 1 + + lineCounter = 0 + charCounter = result[1] + for ; charCounter < len(input); charCounter++ { + if input[charCounter] == '\n' { + lineCounter++ + } + if lineCounter > contextAfter { + break + } + } + lineEnd := charCounter + + extractedRanges = append(extractedRanges, TextRange{lineStart, lineEnd}) + } + + return extractedRanges +} + +// insert merges newRanges into existingRanges by combining overlapping or adjacent ranges. +func insert(existingRanges, newRanges []TextRange) []TextRange { + // Combine all ranges into a single slice for sorting + allRanges := append(existingRanges, newRanges...) + + // Sort ranges by start value (and end value if starts are equal) + sort.Slice(allRanges, func(i, j int) bool { + if allRanges[i].start == allRanges[j].start { + return allRanges[i].end < allRanges[j].end + } + return allRanges[i].start < allRanges[j].start + }) + + // Merge ranges + var merged []TextRange + for _, current := range allRanges { + // If merged is empty or the current range does not overlap with the last merged range + if len(merged) == 0 || merged[len(merged)-1].end < current.start { + merged = append(merged, current) // Add the current range + } else { + // Overlapping or adjacent: Extend the end of the last merged range + merged[len(merged)-1].end = max(merged[len(merged)-1].end, current.end) + } + } + + return merged +} + +// Combine processes input using multiple logFileProcessors and merges their output ranges. +func Combine(input []byte, processors ...logFileProcessor) []TextRange { + var allRanges []TextRange + + // Collect all ranges from each processor + for _, processor := range processors { + allRanges = append(allRanges, processor(input)...) + } + + // Use the improved insert function to merge all collected ranges + return insert(nil, allRanges) +} + +type logFileProcessor func([]byte) []TextRange + +// processLogFile reads a UTF-16 MSI log file and applies various processors on it +// to retain only the relevant log lines. It combines the various outputs from the processors and +// decorate each range of log lines with a marker ('---') to distinguish them. +func processLogFile(logFile fs.File, processors ...logFileProcessor) ([]byte, error) { + logFileBuffer := bytes.NewBuffer(nil) + _, err := io.Copy(logFileBuffer, logFile) + if err != nil { + return nil, err + } + decodedLogsBytes, err := unicode.UTF16(unicode.LittleEndian, unicode.UseBOM).NewDecoder().Bytes(logFileBuffer.Bytes()) + if err != nil { + return nil, err + } + + var output []byte + rangesToSave := Combine(decodedLogsBytes, processors...) + for _, ranges := range rangesToSave { + output = append(output, []byte(fmt.Sprintf("--- %d:%d\r\n", ranges.start, ranges.end))...) + output = append(output, decodedLogsBytes[ranges.start:ranges.end]...) + output = append(output, '\r', '\n', '\r', '\n') + } + return output, nil +} diff --git a/pkg/fleet/internal/msi/msilog_test.go b/pkg/fleet/internal/msi/msilog_test.go new file mode 100644 index 0000000000000..f52ff24f2a65f --- /dev/null +++ b/pkg/fleet/internal/msi/msilog_test.go @@ -0,0 +1,393 @@ +// 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 msi + +import ( + "embed" + "github.com/stretchr/testify/require" + "golang.org/x/text/encoding/unicode" + "regexp" + "strings" + "testing" +) + +//go:embed wixfailwhendeferred.log +//go:embed missing_password_for_dc.log +//go:embed file_in_use.log +//go:embed invalid_credentials.log +//go:embed service_marked_for_deletion.log +var logFilesFS embed.FS + +func TestFindAllIndexWithContext(t *testing.T) { + data, err := logFilesFS.ReadFile("wixfailwhendeferred.log") + require.NoError(t, err) + + r := regexp.MustCompile("returned actual error") + decodedLogsBytes, err := unicode.UTF16(unicode.LittleEndian, unicode.UseBOM).NewDecoder().Bytes(data) + require.NoError(t, err) + + matches := FindAllIndexWithContext(r, decodedLogsBytes, 2, 1) + + expectedMatches := []string{ + `Action start 2:10:53: WixRemoveFoldersEx. +WixRemoveFoldersEx: Error 0x80070057: Missing folder property: dd_PROJECTLOCATION_0 for row: RemoveFolderEx +CustomAction WixRemoveFoldersEx returned actual error code 1603 but will be translated to success due to continue marking +Action ended 2:10:53: WixRemoveFoldersEx. Return value 1.`, + `Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.PrepareDecompressPythonDistributions +CA: 02:10:56: PrepareDecompressPythonDistributions. Could not set the progress bar size +CustomAction PrepareDecompressPythonDistributions returned actual error code 1603 but will be translated to success due to continue marking +Action ended 2:10:56: PrepareDecompressPythonDistributions. Return value 1.`, + `SFXCA: Binding to CLR version v4.0.30319 +Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.StartDDServices +CustomAction WixFailWhenDeferred returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) +Action ended 2:11:49: InstallFinalize. Return value 3.`, + } + for i, expectedMatch := range expectedMatches { + text := strings.ReplaceAll(string(decodedLogsBytes[matches[i].start:matches[i].end]), "\r", "") + require.Equal(t, expectedMatch, text) + } +} + +func TestFindAllIndexWithContextOutOfRangeDoesntFail(t *testing.T) { + data, err := logFilesFS.ReadFile("wixfailwhendeferred.log") + require.NoError(t, err) + + r := regexp.MustCompile("returned actual error") + decodedLogsBytes, err := unicode.UTF16(unicode.LittleEndian, unicode.UseBOM).NewDecoder().Bytes(data) + require.NoError(t, err) + + matches := FindAllIndexWithContext(r, decodedLogsBytes, -21, -1435) + expectedMatches := []string{ + `CustomAction WixRemoveFoldersEx returned actual error code 1603 but will be translated to success due to continue marking`, + `CustomAction PrepareDecompressPythonDistributions returned actual error code 1603 but will be translated to success due to continue marking`, + `CustomAction WixFailWhenDeferred returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)`, + } + for i, expectedMatch := range expectedMatches { + text := strings.ReplaceAll(string(decodedLogsBytes[matches[i].start:matches[i].end]), "\r", "") + require.Equal(t, expectedMatch, text) + } +} + +func TestCombineRanges(t *testing.T) { + tests := map[string]struct { + input []logFileProcessor + expected []TextRange + }{ + "overlap left": { + input: []logFileProcessor{ + func(_ []byte) []TextRange { + return []TextRange{{1, 5}} + }, + func(_ []byte) []TextRange { + return []TextRange{{4, 7}} + }}, + expected: []TextRange{{1, 7}}, + }, + "overlap right": { + input: []logFileProcessor{ + func(_ []byte) []TextRange { + return []TextRange{{2, 4}} + }, + func(_ []byte) []TextRange { + return []TextRange{{1, 3}} + }}, + expected: []TextRange{{1, 4}}, + }, + "no overlap": { + input: []logFileProcessor{ + func(_ []byte) []TextRange { + return []TextRange{{2, 4}} + }, + func(_ []byte) []TextRange { + return []TextRange{{5, 10}} + }}, + expected: []TextRange{{2, 4}, {5, 10}}, + }, + "full overlap": { + input: []logFileProcessor{ + func(_ []byte) []TextRange { + return []TextRange{{2, 4}} + }, + func(_ []byte) []TextRange { + return []TextRange{{1, 10}} + }}, + expected: []TextRange{{1, 10}}, + }, + "full overlap inverted": { + input: []logFileProcessor{ + func(_ []byte) []TextRange { + return []TextRange{{1, 10}} + }, + func(_ []byte) []TextRange { + return []TextRange{{2, 4}} + }}, + expected: []TextRange{{1, 10}}, + }, + "test many ranges": { + input: []logFileProcessor{ + func(_ []byte) []TextRange { + return []TextRange{{16067, 16421}} + }, + func(_ []byte) []TextRange { + return []TextRange{{19659, 20140}} + }, + func(_ []byte) []TextRange { + return []TextRange{{16002, 16359}} + }, + func(_ []byte) []TextRange { + return []TextRange{{19559, 19951}} + }, + func(_ []byte) []TextRange { + return []TextRange{{59421, 59556}} + }}, + expected: []TextRange{{16002, 16421}, {19559, 20140}, {59421, 59556}}, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + require.Equal(t, test.expected, Combine(nil, test.input...)) + }) + } +} + +func TestReadLogFile(t *testing.T) { + m := &Msiexec{} + + tests := map[string]struct { + input string + expected string + }{ + "Wix built-in failure mode": { + input: "wixfailwhendeferred.log", + expected: `--- 1547:2038 +Action ended 2:10:53: LaunchConditions. Return value 1. +Action start 2:10:53: ValidateProductID. +Action ended 2:10:53: ValidateProductID. Return value 1. +Action start 2:10:53: WixRemoveFoldersEx. +WixRemoveFoldersEx: Error 0x80070057: Missing folder property: dd_PROJECTLOCATION_0 for row: RemoveFolderEx +CustomAction WixRemoveFoldersEx returned actual error code 1603 but will be translated to success due to continue marking +Action ended 2:10:53: WixRemoveFoldersEx. Return value 1. + +--- 6770:7391 +Action start 2:10:55: PrepareDecompressPythonDistributions. +SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSIB32B.tmp-\ +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.PrepareDecompressPythonDistributions +CA: 02:10:56: PrepareDecompressPythonDistributions. Could not set the progress bar size +CustomAction PrepareDecompressPythonDistributions returned actual error code 1603 but will be translated to success due to continue marking +Action ended 2:10:56: PrepareDecompressPythonDistributions. Return value 1. + +--- 16002:16421 +CA: 02:11:30: AddUser. ddagentuser already exists, not creating +CA: 02:11:30: GetPreviousAgentUser. Could not find previous agent user: System.Exception: Agent user information is not in registry + at Datadog.CustomActions.InstallStateCustomActions.GetPreviousAgentUser(ISession session, IRegistryServices registryServices, INativeMethods nativeMethods) +CA: 02:11:30: ConfigureUser. Resetting ddagentuser password. + +--- 19559:20140 +CA: 02:11:36: ConfigureServiceUsers. Configuring services with account WIN-ST17FJ32SOG\ddagentuser +CA: 02:11:36: GetPreviousAgentUser. Could not find previous agent user: System.Exception: Agent user information is not in registry + at Datadog.CustomActions.InstallStateCustomActions.GetPreviousAgentUser(ISession session, IRegistryServices registryServices, INativeMethods nativeMethods) +CA: 02:11:36: UpdateAndLogAccessControl. datadog-process-agent current ACLs: D:(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA) + +--- 24843:25383 +CA(ddprocmon): DriverInstall: Done with create() 0 +CA(ddprocmon): DriverInstall: done installing services +SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSI593F.tmp-\ +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.StartDDServices +CustomAction WixFailWhenDeferred returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) +Action ended 2:11:49: InstallFinalize. Return value 3. + +`, + }, + "Missing password for DC": { + input: "missing_password_for_dc.log", + expected: `--- 3625:5242 +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.ProcessDdAgentUserCredentials +CA: 01:49:43: LookupAccountWithExtendedDomainSyntax. User not found, trying again with fixed domain part: \toto +CA: 01:49:43: ProcessDdAgentUserCredentials. User toto doesn't exist. +CA: 01:49:43: ProcessDdAgentUserCredentials. domain part is empty, using default +CA: 01:49:43: ProcessDdAgentUserCredentials. Installing with DDAGENTUSER_PROCESSED_NAME=toto and DDAGENTUSER_PROCESSED_DOMAIN=datadoghq-qa-labs.local +CA: 01:49:43: HandleProcessDdAgentUserCredentialsException. Error processing ddAgentUser credentials: Datadog.CustomActions.InvalidAgentUserConfigurationException: A password was not provided. A password is a required when installing on Domain Controllers. + at Datadog.CustomActions.ProcessUserCustomActions.ProcessDdAgentUserCredentials(Boolean calledFromUIControl) +MSI (s) (C8!50) [01:49:43:906]: Product: Datadog Agent -- A password was not provided. A password is a required when installing on Domain Controllers. + +A password was not provided. A password is a required when installing on Domain Controllers. +CustomAction ProcessDdAgentUserCredentials returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) +Action ended 1:49:43: ProcessDdAgentUserCredentials. Return value 3. +Action ended 1:49:43: INSTALL. Return value 3. +Property(S): UpgradeCode = {0C50421B-AEFB-4F15-A809-7AF256D608A5} +Property(S): NETFRAMEWORK45 = #528449 +Property(S): WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 + +`, + }, + "File in use": { + input: "file_in_use.log", + expected: `--- 3557:3890 +Action start 1:45:18: InstallValidate. +Info 1603. The file C:\Program Files\Datadog\Datadog Agent\bin\agent\process-agent.exe is being held in use by the following process: Name: process-agent, Id: 4704, Window Title: '(not determined yet)'. Close that application and retry. +Action ended 1:45:21: InstallValidate. Return value 1. + +--- 5653:5849 +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action CustomActions!Datadog.CustomActions.PrerequisitesCustomActions.EnsureAdminCaller +Action ended 1:45:22: RunAsAdmin. Return value 1. + +--- 5983:6218 +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action CustomActions!Datadog.CustomActions.InstallStateCustomActions.ReadInstallState +CA: 01:45:23: RegistryProperty. Found DDAGENTUSER_NAME in registry DDOG-HQ-QA-LABS\ddGmsa$ + +--- 7338:7520 +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action CustomActions!Datadog.CustomActions.ConfigCustomActions.ReadConfig +Action ended 1:45:25: ReadConfig. Return value 1. + +--- 7627:7960 +Action start 1:45:25: InstallValidate. +Info 1603. The file C:\Program Files\Datadog\Datadog Agent\bin\agent\process-agent.exe is being held in use by the following process: Name: process-agent, Id: 4704, Window Title: '(not determined yet)'. Close that application and retry. +Action ended 1:45:27: InstallValidate. Return value 1. + +--- 12929:13180 +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action CustomActions!Datadog.CustomActions.Rollback.RestoreDaclRollbackCustomAction.DoRollback +CA: 01:45:35: DoRollback. Resetting inheritance flag on "C:\Program Files\Datadog\Datadog Agent\" + +--- 13273:13484 +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action CustomActions!Datadog.CustomActions.ServiceCustomAction.StopDDServices +CA: 01:45:39: StopDDServices. Service datadog-system-probe status: Stopped + +--- 14824:15093 +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action CustomActions!Datadog.CustomActions.ConfigureUserCustomActions.UninstallUser +CA: 01:45:42: UninstallUser. Removing file access for DDOG-HQ-QA-LABS\ddGmsa$ (S-1-5-21-3647231507-2031390810-2876811253-1605) + +--- 464565:465186 +Action start 1:46:16: PrepareDecompressPythonDistributions. +SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSI58A1.tmp-\ +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.PrepareDecompressPythonDistributions +CA: 01:46:17: PrepareDecompressPythonDistributions. Could not set the progress bar size +CustomAction PrepareDecompressPythonDistributions returned actual error code 1603 but will be translated to success due to continue marking +Action ended 1:46:17: PrepareDecompressPythonDistributions. Return value 1. + +`, + }, + "Invalid credentials": { + input: "invalid_credentials.log", + expected: `--- 7263:7883 +Action start 1:50:19: PrepareDecompressPythonDistributions. +SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSID56.tmp-\ +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.PrepareDecompressPythonDistributions +CA: 01:50:19: PrepareDecompressPythonDistributions. Could not set the progress bar size +CustomAction PrepareDecompressPythonDistributions returned actual error code 1603 but will be translated to success due to continue marking +Action ended 1:50:19: PrepareDecompressPythonDistributions. Return value 1. + +--- 25259:26729 +CA: 01:50:48: StoreAgentUserInRegistry. Storing installedUser=ddagentuser +CA(ddnpm): DriverInstall: Initialized +CA(ddnpm): DriverInstall: Installing services +CA(ddnpm): DriverInstall: installing service +CA(ddnpm): DriverInstall: serviceDef::create() +CA(ddnpm): DriverInstall: Failed to CreateService 1073 +CA(ddnpm): DriverInstall: Service exists, verifying +CA(ddnpm): DriverInstall: Updated path for existing service +CA(ddnpm): DriverInstall: done installing services +CA(ddapm): DriverInstall: Initialized +CA(ddapm): DriverInstall: Installing services +CA(ddapm): DriverInstall: installing service +CA(ddapm): DriverInstall: serviceDef::create() +CA(ddapm): DriverInstall: Failed to CreateService 1073 +CA(ddapm): DriverInstall: Service exists, verifying +CA(ddapm): DriverInstall: Updated path for existing service +CA(ddapm): DriverInstall: done installing services +CA(ddprocmon): DriverInstall: Initialized +CA(ddprocmon): DriverInstall: Installing services +CA(ddprocmon): DriverInstall: installing service +CA(ddprocmon): DriverInstall: serviceDef::create() +CA(ddprocmon): DriverInstall: Failed to CreateService 1073 +CA(ddprocmon): DriverInstall: Service exists, verifying +CA(ddprocmon): DriverInstall: Updated path for existing service +CA(ddprocmon): DriverInstall: done installing services +SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSI7FD3.tmp-\ +SFXCA: Binding to CLR version v4.0.30319 + +--- 26730:27404 +Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.StartDDServices +CA: 01:50:49: StartDDServices. Failed to start services: System.InvalidOperationException: Cannot start service datadogagent on computer '.'. ---> System.ComponentModel.Win32Exception: The service did not start due to a logon failure + --- End of inner exception stack trace --- + at System.ServiceProcess.ServiceController.Start(String args) + at Datadog.CustomActions.Native.ServiceController.StartService(String serviceName, TimeSpan timeout) + at Datadog.CustomActions.ServiceCustomAction.StartDDServices() +Action ended 1:50:49: InstallFinalize. Return value 1. + +`, + }, + "Service marked for deletion": { + input: "service_marked_for_deletion.log", + expected: `--- 1546:2037 +Action ended 6:11:36: LaunchConditions. Return value 1. +Action start 6:11:36: ValidateProductID. +Action ended 6:11:36: ValidateProductID. Return value 1. +Action start 6:11:36: WixRemoveFoldersEx. +WixRemoveFoldersEx: Error 0x80070057: Missing folder property: dd_PROJECTLOCATION_0 for row: RemoveFolderEx +CustomAction WixRemoveFoldersEx returned actual error code 1603 but will be translated to success due to continue marking +Action ended 6:11:36: WixRemoveFoldersEx. Return value 1. + +--- 6876:7497 +Action start 6:11:38: PrepareDecompressPythonDistributions. +SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSI7CB7.tmp-\ +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.PrepareDecompressPythonDistributions +CA: 06:11:39: PrepareDecompressPythonDistributions. Could not set the progress bar size +CustomAction PrepareDecompressPythonDistributions returned actual error code 1603 but will be translated to success due to continue marking +Action ended 6:11:39: PrepareDecompressPythonDistributions. Return value 1. + +--- 16762:17181 +CA: 06:12:16: AddUser. ddagentuser already exists, not creating +CA: 06:12:16: GetPreviousAgentUser. Could not find previous agent user: System.Exception: Agent user information is not in registry + at Datadog.CustomActions.InstallStateCustomActions.GetPreviousAgentUser(ISession session, IRegistryServices registryServices, INativeMethods nativeMethods) +CA: 06:12:16: ConfigureUser. Resetting ddagentuser password. + +--- 19832:20285 + } +] +MSI (s) (B4:24) [06:12:21:764]: Product: Datadog Agent -- Error 1923. Service 'Datadog Agent' (datadogagent) could not be installed. Verify that you have sufficient privileges to install system services. + +Error 1923. Service 'Datadog Agent' (datadogagent) could not be installed. Verify that you have sufficient privileges to install system services. +SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSI2787.tmp-\ + +--- 20286:20851 +SFXCA: Binding to CLR version v4.0.30319 +Calling custom action AgentCustomActions!Datadog.AgentCustomActions.CustomActions.EnsureNpmServiceDependency +ExecServiceConfig: Error 0x80070430: Cannot change service configuration. Error: The specified service has been marked for deletion. + +ExecServiceConfig: Error 0x80070430: Failed to configure service: datadogagent +CustomAction ExecServiceConfig returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) +Action ended 6:12:22: InstallFinalize. Return value 3. + +`, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + file, err := logFilesFS.Open(test.input) + require.NoError(t, err) + got, err := m.processLogFile(file) + require.NoError(t, err) + resultString := strings.ReplaceAll(string(got), "\r", "") + require.Equal(t, test.expected, resultString) + }) + } +} diff --git a/pkg/fleet/installer/packages/msiexec.go b/pkg/fleet/internal/msi/product.go similarity index 59% rename from pkg/fleet/installer/packages/msiexec.go rename to pkg/fleet/internal/msi/product.go index e65692bb38c8f..e87144d748f9d 100644 --- a/pkg/fleet/installer/packages/msiexec.go +++ b/pkg/fleet/internal/msi/product.go @@ -5,34 +5,14 @@ //go:build windows -package packages +package msi import ( "fmt" - "os/exec" - "path/filepath" - "github.com/DataDog/datadog-agent/pkg/fleet/internal/paths" - "github.com/DataDog/datadog-agent/pkg/util/log" "golang.org/x/sys/windows/registry" ) -func msiexec(target, product, operation string, args []string) (*exec.Cmd, error) { - updaterPath := filepath.Join(paths.PackagesPath, product, target) - msis, err := filepath.Glob(filepath.Join(updaterPath, fmt.Sprintf("%s-*-1-x86_64.msi", product))) - if err != nil { - return nil, err - } - if len(msis) > 1 { - return nil, fmt.Errorf("too many MSIs in package") - } else if len(msis) == 0 { - return nil, fmt.Errorf("no MSIs in package") - } - - cmd := exec.Command("msiexec", append([]string{operation, msis[0], "/qn", "MSIFASTINSTALL=7"}, args...)...) - return cmd, nil -} - // Product represents a software from the Windows Registry type Product struct { // Code is the software product code @@ -41,7 +21,8 @@ type Product struct { UninstallString string } -func findProductCode(name string) (*Product, error) { +// FindProductCode looks for the productName in the registry and returns information about it +func FindProductCode(productName string) (*Product, error) { rootPath := "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" reg, err := registry.OpenKey(registry.LOCAL_MACHINE, rootPath, registry.ENUMERATE_SUB_KEYS) if err != nil { @@ -53,55 +34,55 @@ func findProductCode(name string) (*Product, error) { return nil, err } for _, key := range keys { - product, err := processKey(rootPath, key, name) + product, err := processKey(rootPath, key, productName) if err == nil && product != nil { - return product, err + return product, nil } } - return nil, nil + return nil, fmt.Errorf("product not found") } -func processKey(rootPath, key, name string) (*Product, error) { - subkey, err := registry.OpenKey(registry.LOCAL_MACHINE, rootPath+"\\"+key, registry.QUERY_VALUE) +// IsProductInstalled returns true if the given productName is installed +func IsProductInstalled(productName string) bool { + product, err := FindProductCode(productName) if err != nil { - return nil, err - } - defer subkey.Close() - - displayName, _, err := subkey.GetStringValue("DisplayName") - if err == nil && displayName == name { - product := &Product{} - product.UninstallString, _, _ = subkey.GetStringValue("UninstallString") - product.Code = key - return product, nil + return false } - - return nil, nil + return product != nil } -// removeProduct uses the registry to try and find a product and use msiexec to remove it. +// RemoveProduct uses the registry to try and find a product and use msiexec to remove it. // It is different from msiexec in that it uses the registry and not the stable/experiment path on disk to // uninstall the product. // This is needed because in certain circumstances the installer database stored in the stable/experiment paths does not // reflect the installed version, and using those installers can lead to undefined behavior (either failure to uninstall, // or weird bugs from uninstalling a product with an installer from a different version). -func removeProduct(productName string) error { - log.Debugf("Removing product %s", productName) - product, err := findProductCode(productName) +func RemoveProduct(productName string) error { + cmd, err := Cmd(Uninstall(), WithProduct(productName)) if err != nil { - return fmt.Errorf("error trying to find product %s: %w", productName, err) + return fmt.Errorf("failed to remove product: %w", err) } - if product != nil { - cmd := exec.Command("msiexec", "/x", product.Code, "/qn", "MSIFASTINSTALL=7") - return cmd.Run() + output, err := cmd.Run() + if err != nil { + return fmt.Errorf("failed to remove product: %w\n%s", err, string(output)) } - return fmt.Errorf("product %s not found", productName) + return nil } -func isProductInstalled(productName string) bool { - product, err := findProductCode(productName) +func processKey(rootPath, key, name string) (*Product, error) { + subkey, err := registry.OpenKey(registry.LOCAL_MACHINE, rootPath+"\\"+key, registry.QUERY_VALUE) if err != nil { - return false + return nil, err } - return product != nil + defer subkey.Close() + + displayName, _, err := subkey.GetStringValue("DisplayName") + if err == nil && displayName == name { + product := &Product{} + product.UninstallString, _, _ = subkey.GetStringValue("UninstallString") + product.Code = key + return product, nil + } + + return nil, nil } diff --git a/pkg/fleet/internal/msi/service_marked_for_deletion.log b/pkg/fleet/internal/msi/service_marked_for_deletion.log new file mode 100644 index 0000000000000..7844b7a546931 Binary files /dev/null and b/pkg/fleet/internal/msi/service_marked_for_deletion.log differ diff --git a/pkg/fleet/internal/msi/wixfailwhendeferred.log b/pkg/fleet/internal/msi/wixfailwhendeferred.log new file mode 100644 index 0000000000000..fb1982434be9b Binary files /dev/null and b/pkg/fleet/internal/msi/wixfailwhendeferred.log differ diff --git a/pkg/fleet/telemetry/telemetry.go b/pkg/fleet/telemetry/telemetry.go index df641722cb18a..5bbfd8ca773c4 100644 --- a/pkg/fleet/telemetry/telemetry.go +++ b/pkg/fleet/telemetry/telemetry.go @@ -219,10 +219,9 @@ func StartSpanFromIDs(ctx context.Context, operationName, traceID, parentID stri spanCtx, err := tracer.Extract(ctxCarrier) if err != nil { log.Debugf("failed to extract span context from install script params: %v", err) - return Span{tracer.StartSpan("remote_request")}, ctx + return StartSpanFromContext(ctx, operationName, spanOptions...) } spanOptions = append([]ddtrace.StartSpanOption{tracer.ChildOf(spanCtx)}, spanOptions...) - return StartSpanFromContext(ctx, operationName, spanOptions...) } diff --git a/pkg/gpu/aggregator.go b/pkg/gpu/aggregator.go index 6e907c24428a1..30a20e9146efd 100644 --- a/pkg/gpu/aggregator.go +++ b/pkg/gpu/aggregator.go @@ -38,13 +38,13 @@ type aggregator struct { // processTerminated is true if the process has ended and this aggregator should be deleted processTerminated bool - // sysCtx is the system context with global GPU-system data - sysCtx *systemContext + // deviceMaxThreads is the maximum number of threads the GPU can run in parallel, for utilization calculations + deviceMaxThreads uint64 } -func newAggregator(sysCtx *systemContext) *aggregator { +func newAggregator(deviceMaxThreads uint64) *aggregator { return &aggregator{ - sysCtx: sysCtx, + deviceMaxThreads: deviceMaxThreads, } } @@ -60,8 +60,7 @@ func (agg *aggregator) processKernelSpan(span *kernelSpan) { } durationSec := float64(tsEnd-tsStart) / float64(time.Second.Nanoseconds()) - maxThreads := uint64(agg.sysCtx.maxGpuThreadsPerDevice[0]) // TODO: MultiGPU support not enabled yet - agg.totalThreadSecondsUsed += durationSec * float64(min(span.avgThreadCount, maxThreads)) // we can't use more threads than the GPU has + agg.totalThreadSecondsUsed += durationSec * float64(min(span.avgThreadCount, agg.deviceMaxThreads)) // we can't use more threads than the GPU has } // processPastData takes spans/allocations that have already been closed @@ -86,8 +85,7 @@ func (agg *aggregator) processCurrentData(data *streamData) { func (agg *aggregator) getGPUUtilization() float64 { intervalSecs := float64(agg.measuredIntervalNs) / float64(time.Second.Nanoseconds()) if intervalSecs > 0 { - // TODO: MultiGPU support not enabled yet - availableThreadSeconds := float64(agg.sysCtx.maxGpuThreadsPerDevice[0]) * intervalSecs + availableThreadSeconds := float64(agg.deviceMaxThreads) * intervalSecs return agg.totalThreadSecondsUsed / availableThreadSeconds } diff --git a/pkg/gpu/context.go b/pkg/gpu/context.go index 6c38ae4ad978c..77bac5185339f 100644 --- a/pkg/gpu/context.go +++ b/pkg/gpu/context.go @@ -248,3 +248,17 @@ func (ctx *systemContext) setDeviceSelection(pid int, tid int, deviceIndex int32 ctx.selectedDeviceByPIDAndTID[pid][tid] = deviceIndex } + +// getDeviceByUUID returns the device with the given UUID. +func (ctx *systemContext) getDeviceByUUID(uuid string) (nvml.Device, error) { + for _, dev := range ctx.gpuDevices { + devUUID, ret := dev.GetUUID() + if ret != nvml.SUCCESS { + return nil, fmt.Errorf("error getting device UUID: %s", nvml.ErrorString(ret)) + } + if devUUID == uuid { + return dev, nil + } + } + return nil, fmt.Errorf("device with UUID %s not found", uuid) +} diff --git a/pkg/gpu/stats.go b/pkg/gpu/stats.go index 753fadcf084d9..ba50db6c5226a 100644 --- a/pkg/gpu/stats.go +++ b/pkg/gpu/stats.go @@ -8,8 +8,13 @@ package gpu import ( + "fmt" + + "github.com/NVIDIA/go-nvml/pkg/nvml" + "github.com/DataDog/datadog-agent/pkg/collector/corechecks/gpu/model" ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" + "github.com/DataDog/datadog-agent/pkg/util/log" ) // statsGenerator connects to the active stream handlers and generates stats for the GPU monitoring, by distributing @@ -40,7 +45,12 @@ func (g *statsGenerator) getStats(nowKtime int64) *model.GPUStats { g.currGenerationKTime = nowKtime for key, handler := range g.streamHandlers { - aggr := g.getOrCreateAggregator(key) + aggr, err := g.getOrCreateAggregator(key) + if err != nil { + log.Errorf("Error getting or creating aggregator for key %v: %s", key, err) + continue + } + currData := handler.getCurrentData(uint64(nowKtime)) pastData := handler.getPastData(true) @@ -76,7 +86,7 @@ func (g *statsGenerator) getStats(nowKtime int64) *model.GPUStats { return stats } -func (g *statsGenerator) getOrCreateAggregator(sKey streamKey) *aggregator { +func (g *statsGenerator) getOrCreateAggregator(sKey streamKey) (*aggregator, error) { aggKey := model.StatsKey{ PID: sKey.pid, DeviceUUID: sKey.gpuUUID, @@ -84,13 +94,23 @@ func (g *statsGenerator) getOrCreateAggregator(sKey streamKey) *aggregator { } if _, ok := g.aggregators[aggKey]; !ok { - g.aggregators[aggKey] = newAggregator(g.sysCtx) + gpuDevice, err := g.sysCtx.getDeviceByUUID(sKey.gpuUUID) + if err != nil { + return nil, fmt.Errorf("Error getting device by UUID %s: %s", sKey.gpuUUID, err) + } + + maxThreads, ret := gpuDevice.GetNumGpuCores() + if ret != nvml.SUCCESS { + return nil, fmt.Errorf("Error getting number of GPU cores: %s", nvml.ErrorString(ret)) + } + + g.aggregators[aggKey] = newAggregator(uint64(maxThreads)) } // Update the last check time and the measured interval, as these change between check runs g.aggregators[aggKey].lastCheckKtime = uint64(g.lastGenerationKTime) g.aggregators[aggKey].measuredIntervalNs = g.currGenerationKTime - g.lastGenerationKTime - return g.aggregators[aggKey] + return g.aggregators[aggKey], nil } // getNormalizationFactor returns the factor to use for utilization diff --git a/pkg/gpu/stats_test.go b/pkg/gpu/stats_test.go index 4ebbec874ecdc..c0445e6c4e869 100644 --- a/pkg/gpu/stats_test.go +++ b/pkg/gpu/stats_test.go @@ -233,3 +233,49 @@ func TestGetStatsWithPastAndCurrentData(t *testing.T) { expectedUtil := expectedUtilKern1 + expectedUtilKern2 require.InDelta(t, expectedUtil, metrics.UtilizationPercentage, 0.001) } + +func TestGetStatsMultiGPU(t *testing.T) { + statsGen, streamHandlers, ktime := getStatsGeneratorForTest(t) + + startKtime := ktime + int64(1*time.Second) + endKtime := startKtime + int64(1*time.Second) + + pid := uint32(1) + numThreads := uint64(5) + + // Add kernels for all devices + for i, uuid := range testutil.GPUUUIDs { + streamID := uint64(i) + streamKey := streamKey{pid: pid, stream: streamID, gpuUUID: uuid} + streamHandlers[streamKey] = &StreamHandler{ + processEnded: false, + kernelSpans: []*kernelSpan{ + { + startKtime: uint64(startKtime), + endKtime: uint64(endKtime), + avgThreadCount: numThreads, + numKernels: 10, + }, + }, + } + } + + checkDuration := 10 * time.Second + checkKtime := ktime + int64(checkDuration) + stats := statsGen.getStats(checkKtime) + require.NotNil(t, stats) + + // Check the metrics for each device + for i, uuid := range testutil.GPUUUIDs { + metricsKey := model.StatsKey{PID: pid, DeviceUUID: uuid} + metrics := getMetricsEntry(metricsKey, stats) + require.NotNil(t, metrics, "cannot find metrics for key %+v", metricsKey) + + gpuCores := float64(testutil.GPUCores[i]) + threadSecondsUsed := float64(numThreads) * float64(endKtime-startKtime) / 1e9 + threadSecondsAvailable := gpuCores * checkDuration.Seconds() + expectedUtil := threadSecondsUsed / threadSecondsAvailable + + require.InDelta(t, expectedUtil, metrics.UtilizationPercentage, 0.001, "invalid utilization for device %d (uuid=%s)", i, uuid) + } +} diff --git a/pkg/gpu/testutil/mocks.go b/pkg/gpu/testutil/mocks.go index b703a39001ef4..a7dadd39215ad 100644 --- a/pkg/gpu/testutil/mocks.go +++ b/pkg/gpu/testutil/mocks.go @@ -23,20 +23,23 @@ var GPUUUIDs = []string{ "GPU-00000000-1234-1234-1234-123456789014", } +// GPUCores is a list of number of cores for the devices returned by the mock, should be the same length as GPUUUIDs +var GPUCores = []int{DefaultGpuCores, 20, 30} + // DefaultGpuUUID is the UUID for the default device returned by the mock var DefaultGpuUUID = GPUUUIDs[0] // GetDeviceMock returns a mock of the nvml.Device with the given UUID. -func GetDeviceMock(uuid string) *nvmlmock.Device { +func GetDeviceMock(deviceIdx int) *nvmlmock.Device { return &nvmlmock.Device{ GetNumGpuCoresFunc: func() (int, nvml.Return) { - return DefaultGpuCores, nvml.SUCCESS + return GPUCores[deviceIdx], nvml.SUCCESS }, GetCudaComputeCapabilityFunc: func() (int, int, nvml.Return) { return 7, 5, nvml.SUCCESS }, GetUUIDFunc: func() (string, nvml.Return) { - return uuid, nvml.SUCCESS + return GPUUUIDs[deviceIdx], nvml.SUCCESS }, } } @@ -49,7 +52,7 @@ func GetBasicNvmlMock() *nvmlmock.Interface { return len(GPUUUIDs), nvml.SUCCESS }, DeviceGetHandleByIndexFunc: func(index int) (nvml.Device, nvml.Return) { - return GetDeviceMock(GPUUUIDs[index]), nvml.SUCCESS + return GetDeviceMock(index), nvml.SUCCESS }, DeviceGetCudaComputeCapabilityFunc: func(nvml.Device) (int, int, nvml.Return) { return 7, 5, nvml.SUCCESS diff --git a/pkg/logs/auditor/go.mod b/pkg/logs/auditor/go.mod index 3fc9bf65dfa46..f9543ab0dda08 100644 --- a/pkg/logs/auditor/go.mod +++ b/pkg/logs/auditor/go.mod @@ -80,7 +80,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/pkg/logs/auditor/go.sum b/pkg/logs/auditor/go.sum index 3f00397cbc301..7fdf16db5981c 100644 --- a/pkg/logs/auditor/go.sum +++ b/pkg/logs/auditor/go.sum @@ -86,8 +86,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/logs/client/go.mod b/pkg/logs/client/go.mod index 093922b236bf3..49dad213dc24f 100644 --- a/pkg/logs/client/go.mod +++ b/pkg/logs/client/go.mod @@ -100,7 +100,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/pkg/logs/client/go.sum b/pkg/logs/client/go.sum index 1140bccbba9c9..5f7384266b821 100644 --- a/pkg/logs/client/go.sum +++ b/pkg/logs/client/go.sum @@ -88,8 +88,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/logs/diagnostic/go.mod b/pkg/logs/diagnostic/go.mod index 65fb4af75f769..690eb4c56105e 100644 --- a/pkg/logs/diagnostic/go.mod +++ b/pkg/logs/diagnostic/go.mod @@ -84,7 +84,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect diff --git a/pkg/logs/diagnostic/go.sum b/pkg/logs/diagnostic/go.sum index 9694f5d5e2355..dd16364891695 100644 --- a/pkg/logs/diagnostic/go.sum +++ b/pkg/logs/diagnostic/go.sum @@ -87,8 +87,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/logs/message/go.mod b/pkg/logs/message/go.mod index 716c4a57de92f..93c9793bafaf5 100644 --- a/pkg/logs/message/go.mod +++ b/pkg/logs/message/go.mod @@ -76,7 +76,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/pkg/logs/message/go.sum b/pkg/logs/message/go.sum index 3f00397cbc301..7fdf16db5981c 100644 --- a/pkg/logs/message/go.sum +++ b/pkg/logs/message/go.sum @@ -86,8 +86,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/logs/pipeline/go.mod b/pkg/logs/pipeline/go.mod index b2cca0985481e..10ad9ab1983b5 100644 --- a/pkg/logs/pipeline/go.mod +++ b/pkg/logs/pipeline/go.mod @@ -120,7 +120,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/pkg/logs/pipeline/go.sum b/pkg/logs/pipeline/go.sum index 9061e9b89a5c6..b0f7d9ee40dfd 100644 --- a/pkg/logs/pipeline/go.sum +++ b/pkg/logs/pipeline/go.sum @@ -99,8 +99,8 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/logs/processor/go.mod b/pkg/logs/processor/go.mod index cc9458ea710c0..b98eacd627e97 100644 --- a/pkg/logs/processor/go.mod +++ b/pkg/logs/processor/go.mod @@ -99,7 +99,7 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/pkg/logs/processor/go.sum b/pkg/logs/processor/go.sum index f97a65425513e..1fb7bbe76cabd 100644 --- a/pkg/logs/processor/go.sum +++ b/pkg/logs/processor/go.sum @@ -94,8 +94,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/logs/sds/go.mod b/pkg/logs/sds/go.mod index 33c40479ed13f..f5818700af57b 100644 --- a/pkg/logs/sds/go.mod +++ b/pkg/logs/sds/go.mod @@ -93,7 +93,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/pkg/logs/sds/go.sum b/pkg/logs/sds/go.sum index a5a699a22e560..c9341f0f48498 100644 --- a/pkg/logs/sds/go.sum +++ b/pkg/logs/sds/go.sum @@ -88,8 +88,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/logs/sender/go.mod b/pkg/logs/sender/go.mod index 5a77fb5bb761d..437b2592b6e94 100644 --- a/pkg/logs/sender/go.mod +++ b/pkg/logs/sender/go.mod @@ -100,7 +100,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/pkg/logs/sender/go.sum b/pkg/logs/sender/go.sum index 1140bccbba9c9..5f7384266b821 100644 --- a/pkg/logs/sender/go.sum +++ b/pkg/logs/sender/go.sum @@ -88,8 +88,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/logs/sources/go.mod b/pkg/logs/sources/go.mod index a5ff5d7147d72..47c016d543c91 100644 --- a/pkg/logs/sources/go.mod +++ b/pkg/logs/sources/go.mod @@ -74,7 +74,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/pkg/logs/sources/go.sum b/pkg/logs/sources/go.sum index 3f00397cbc301..7fdf16db5981c 100644 --- a/pkg/logs/sources/go.sum +++ b/pkg/logs/sources/go.sum @@ -86,8 +86,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/logs/util/testutils/go.mod b/pkg/logs/util/testutils/go.mod index ebf193c2c90a2..46e01043de4bf 100644 --- a/pkg/logs/util/testutils/go.mod +++ b/pkg/logs/util/testutils/go.mod @@ -74,7 +74,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/pkg/logs/util/testutils/go.sum b/pkg/logs/util/testutils/go.sum index 3f00397cbc301..7fdf16db5981c 100644 --- a/pkg/logs/util/testutils/go.sum +++ b/pkg/logs/util/testutils/go.sum @@ -86,8 +86,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/metrics/go.mod b/pkg/metrics/go.mod index a7369cfd728f6..66e73954c2885 100644 --- a/pkg/metrics/go.mod +++ b/pkg/metrics/go.mod @@ -85,7 +85,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/pkg/metrics/go.sum b/pkg/metrics/go.sum index cc70504832885..31112092709e6 100644 --- a/pkg/metrics/go.sum +++ b/pkg/metrics/go.sum @@ -96,8 +96,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/network/config/config.go b/pkg/network/config/config.go index c6d57230a4003..47f8c85cda215 100644 --- a/pkg/network/config/config.go +++ b/pkg/network/config/config.go @@ -414,8 +414,8 @@ func New() *Config { log.Info("network tracer DNS inspection disabled by configuration") } - if c.EnableProcessEventMonitoring { - log.Info("network process event monitoring enabled") + if !c.EnableProcessEventMonitoring { + log.Info("network process event monitoring disabled") } return c } diff --git a/pkg/network/ebpf/c/co-re/tracer-fentry.c b/pkg/network/ebpf/c/co-re/tracer-fentry.c index 09259e948047d..b89ab7e351d35 100644 --- a/pkg/network/ebpf/c/co-re/tracer-fentry.c +++ b/pkg/network/ebpf/c/co-re/tracer-fentry.c @@ -8,6 +8,7 @@ #include "ipv6.h" #include "sock.h" #include "skb.h" +#include "pid_tgid.h" #include "tracer/tracer.h" #include "tracer/events.h" @@ -52,7 +53,7 @@ static __always_inline bool event_in_task(char *prog_name) { } static __always_inline int read_conn_tuple_partial_from_flowi4(conn_tuple_t *t, struct flowi4 *fl4, u64 pid_tgid, metadata_mask_t type) { - t->pid = pid_tgid >> 32; + t->pid = GET_USER_MODE_PID(pid_tgid); t->metadata = type; if (t->saddr_l == 0) { @@ -85,7 +86,7 @@ static __always_inline int read_conn_tuple_partial_from_flowi4(conn_tuple_t *t, } static __always_inline int read_conn_tuple_partial_from_flowi6(conn_tuple_t *t, struct flowi6 *fl6, u64 pid_tgid, metadata_mask_t type) { - t->pid = pid_tgid >> 32; + t->pid = GET_USER_MODE_PID(pid_tgid); t->metadata = type; struct in6_addr addr = BPF_CORE_READ(fl6, saddr); @@ -233,7 +234,7 @@ int BPF_PROG(tcp_close, struct sock *sk, long timeout) { u64 pid_tgid = bpf_get_current_pid_tgid(); // Get network namespace id - log_debug("fentry/tcp_close: tgid: %llu, pid: %llu", pid_tgid >> 32, pid_tgid & 0xFFFFFFFF); + log_debug("fentry/tcp_close: kernel thread id: %llu, user mode pid: %llu", GET_KERNEL_THREAD_ID(pid_tgid), GET_USER_MODE_PID(pid_tgid)); if (!read_conn_tuple(&t, sk, pid_tgid, CONN_TYPE_TCP)) { return 0; } @@ -410,14 +411,14 @@ SEC("fentry/tcp_retransmit_skb") int BPF_PROG(tcp_retransmit_skb, struct sock *sk, struct sk_buff *skb, int segs, int err) { RETURN_IF_NOT_IN_SYSPROBE_TASK("fentry/tcp_retransmit_skb"); log_debug("fexntry/tcp_retransmit"); - u64 tid = bpf_get_current_pid_tgid(); + u64 pid_tgid = bpf_get_current_pid_tgid(); tcp_retransmit_skb_args_t args = {}; args.retrans_out_pre = BPF_CORE_READ(tcp_sk(sk), retrans_out); if (args.retrans_out_pre < 0) { return 0; } - bpf_map_update_with_telemetry(pending_tcp_retransmit_skb, &tid, &args, BPF_ANY); + bpf_map_update_with_telemetry(pending_tcp_retransmit_skb, &pid_tgid, &args, BPF_ANY); return 0; } @@ -426,18 +427,18 @@ SEC("fexit/tcp_retransmit_skb") int BPF_PROG(tcp_retransmit_skb_exit, struct sock *sk, struct sk_buff *skb, int segs, int err) { RETURN_IF_NOT_IN_SYSPROBE_TASK("fexit/tcp_retransmit_skb"); log_debug("fexit/tcp_retransmit"); - u64 tid = bpf_get_current_pid_tgid(); + u64 pid_tgid = bpf_get_current_pid_tgid(); if (err < 0) { - bpf_map_delete_elem(&pending_tcp_retransmit_skb, &tid); + bpf_map_delete_elem(&pending_tcp_retransmit_skb, &pid_tgid); return 0; } - tcp_retransmit_skb_args_t *args = bpf_map_lookup_elem(&pending_tcp_retransmit_skb, &tid); + tcp_retransmit_skb_args_t *args = bpf_map_lookup_elem(&pending_tcp_retransmit_skb, &pid_tgid); if (args == NULL) { return 0; } u32 retrans_out_pre = args->retrans_out_pre; u32 retrans_out = BPF_CORE_READ(tcp_sk(sk), retrans_out); - bpf_map_delete_elem(&pending_tcp_retransmit_skb, &tid); + bpf_map_delete_elem(&pending_tcp_retransmit_skb, &pid_tgid); if (retrans_out < 0) { return 0; @@ -450,7 +451,7 @@ SEC("fentry/tcp_connect") int BPF_PROG(tcp_connect, struct sock *sk) { RETURN_IF_NOT_IN_SYSPROBE_TASK("fentry/tcp_connect"); u64 pid_tgid = bpf_get_current_pid_tgid(); - log_debug("fentry/tcp_connect: tgid: %llu, pid: %llu", pid_tgid >> 32, pid_tgid & 0xFFFFFFFF); + log_debug("fentry/tcp_connect: kernel thread id: %llu, user mode pid: %llu", GET_KERNEL_THREAD_ID(pid_tgid), GET_USER_MODE_PID(pid_tgid)); conn_tuple_t t = {}; if (!read_conn_tuple(&t, sk, 0, CONN_TYPE_TCP)) { @@ -479,8 +480,8 @@ int BPF_PROG(tcp_finish_connect, struct sock *sk, struct sk_buff *skb, int rc) { return 0; } u64 pid_tgid = pid_tgid_p->pid_tgid; - t.pid = pid_tgid >> 32; - log_debug("fentry/tcp_finish_connect: tgid: %llu, pid: %llu", pid_tgid >> 32, pid_tgid & 0xFFFFFFFF); + t.pid = GET_USER_MODE_PID(pid_tgid); + log_debug("fentry/tcp_finish_connect: kernel thread id: %llu, user mode pid: %llu", GET_KERNEL_THREAD_ID(pid_tgid), GET_USER_MODE_PID(pid_tgid)); handle_tcp_stats(&t, sk, TCP_ESTABLISHED); handle_message(&t, 0, 0, CONN_DIRECTION_OUTGOING, 0, 0, PACKET_COUNT_NONE, sk); @@ -498,7 +499,7 @@ int BPF_PROG(inet_csk_accept_exit, struct sock *_sk, int flags, int *err, bool k } u64 pid_tgid = bpf_get_current_pid_tgid(); - log_debug("fexit/inet_csk_accept: tgid: %llu, pid: %llu", pid_tgid >> 32, pid_tgid & 0xFFFFFFFF); + log_debug("fexit/inet_csk_accept: kernel thread id: %llu, user mode pid: %llu", GET_KERNEL_THREAD_ID(pid_tgid), GET_USER_MODE_PID(pid_tgid)); conn_tuple_t t = {}; if (!read_conn_tuple(&t, sk, pid_tgid, CONN_TYPE_TCP)) { diff --git a/pkg/network/ebpf/c/pid_tgid.h b/pkg/network/ebpf/c/pid_tgid.h new file mode 100644 index 0000000000000..a3439bca233a7 --- /dev/null +++ b/pkg/network/ebpf/c/pid_tgid.h @@ -0,0 +1,52 @@ +#ifndef __PID_TGID_H +#define __PID_TGID_H + +/* + * The following documentation is based on https://stackoverflow.com/a/9306150 + * Note on Process and Thread Identifiers: + * + * What users refer to as a "PID" is not quite the same as what the kernel sees. + * + * In the kernel: + * - Each thread has its own ID, called a PID (though it might be better termed a TID, or Thread ID). + * - Threads within the same process share a TGID (Thread Group ID), which is the PID of the first thread + * created when the process was initialized. + * + * When a process is created: + * - It starts as a single thread where the PID and TGID are the same. + * + * When a new thread is created: + * - It receives its own unique PID for independent scheduling by the kernel. + * - It inherits the TGID from the original (parent) thread, tying it to the same process. + * + * This separation allows the kernel to schedule threads independently while maintaining the process view + * (TGID) when reporting information to users. + * + * Example Hierarchy of Threads: + * + * USER VIEW + * vvvvvvvv + * + * | + * <-- PID 43 -->|<----------------- PID 42 -----------------> + * | | + * | +---------+ | + * | | process | | + * | _| pid=42 |_ | + * __(fork) _/ | tgid=42 | \_ (new thread) _ + * / | +---------+ | \ + * +---------+ | | +---------+ + * | process | | | | process | + * | pid=43 | | | | pid=44 | + * | tgid=43 | | | | tgid=42 | + * +---------+ | | +---------+ + * | | + * <-- PID 43 -->|<--------- PID 42 -------->|<--- PID 44 ---> + * | | + * ^^^^^^^^ + * KERNEL VIEW + */ +#define GET_USER_MODE_PID(x) ((x) >> 32) +#define GET_KERNEL_THREAD_ID(x) ((x) & 0xFFFFFFFF) + +#endif // __PID_TGID_H diff --git a/pkg/network/ebpf/c/prebuilt/conntrack.c b/pkg/network/ebpf/c/prebuilt/conntrack.c index 8e77c1fd98ff8..8417806ce3077 100644 --- a/pkg/network/ebpf/c/prebuilt/conntrack.c +++ b/pkg/network/ebpf/c/prebuilt/conntrack.c @@ -12,6 +12,7 @@ #include "conntrack/maps.h" #include "ip.h" #include "ipv6.h" +#include "pid_tgid.h" SEC("kprobe/__nf_conntrack_hash_insert") int BPF_BYPASSABLE_KPROBE(kprobe___nf_conntrack_hash_insert, struct nf_conn *ct) { @@ -32,7 +33,7 @@ int BPF_BYPASSABLE_KPROBE(kprobe___nf_conntrack_hash_insert, struct nf_conn *ct) SEC("kprobe/ctnetlink_fill_info") int BPF_BYPASSABLE_KPROBE(kprobe_ctnetlink_fill_info) { - u32 pid = bpf_get_current_pid_tgid() >> 32; + u32 pid = GET_USER_MODE_PID(bpf_get_current_pid_tgid()); if (pid != systemprobe_pid()) { log_debug("skipping kprobe/ctnetlink_fill_info invocation from non-system-probe process"); return 0; diff --git a/pkg/network/ebpf/c/prebuilt/offset-guess.c b/pkg/network/ebpf/c/prebuilt/offset-guess.c index cc32fee223935..556a770082684 100644 --- a/pkg/network/ebpf/c/prebuilt/offset-guess.c +++ b/pkg/network/ebpf/c/prebuilt/offset-guess.c @@ -298,11 +298,11 @@ int kprobe__sock_common_getsockopt(struct pt_regs* ctx) { SEC("kprobe/tcp_v6_connect") int kprobe__tcp_v6_connect(struct pt_regs* ctx) { struct sock* sk; - u64 pid = bpf_get_current_pid_tgid(); + u64 pid_tgid = bpf_get_current_pid_tgid(); sk = (struct sock*)PT_REGS_PARM1(ctx); - bpf_map_update_elem(&connectsock_ipv6, &pid, &sk, BPF_ANY); + bpf_map_update_elem(&connectsock_ipv6, &pid_tgid, &sk, BPF_ANY); return 0; } @@ -310,17 +310,17 @@ int kprobe__tcp_v6_connect(struct pt_regs* ctx) { // Used for offset guessing (see: pkg/ebpf/offsetguess.go) SEC("kretprobe/tcp_v6_connect") int kretprobe__tcp_v6_connect(struct pt_regs* __attribute__((unused)) ctx) { - u64 pid = bpf_get_current_pid_tgid(); + u64 pid_tgid = bpf_get_current_pid_tgid(); u64 zero = 0; struct sock** skpp; tracer_status_t* status; - skpp = bpf_map_lookup_elem(&connectsock_ipv6, &pid); + skpp = bpf_map_lookup_elem(&connectsock_ipv6, &pid_tgid); if (skpp == 0) { return 0; // missed entry } struct sock* skp = *skpp; - bpf_map_delete_elem(&connectsock_ipv6, &pid); + bpf_map_delete_elem(&connectsock_ipv6, &pid_tgid); status = bpf_map_lookup_elem(&tracer_status, &zero); if (status == NULL || is_sk_buff_event(status->what)) { diff --git a/pkg/network/ebpf/c/prebuilt/usm_events_test.c b/pkg/network/ebpf/c/prebuilt/usm_events_test.c index 820afb50ef0f0..f2bfb640aa54a 100644 --- a/pkg/network/ebpf/c/prebuilt/usm_events_test.c +++ b/pkg/network/ebpf/c/prebuilt/usm_events_test.c @@ -9,6 +9,7 @@ #include "defs.h" #include "map-defs.h" #include "protocols/events.h" +#include "pid_tgid.h" // -------------------------------------------------------- // this is a test program for pkg/networks/protocols/events @@ -37,7 +38,7 @@ struct syscalls_enter_write_args { SEC("tracepoint/syscalls/sys_enter_write") int tracepoint__syscalls__sys_enter_write(struct syscalls_enter_write_args *ctx) { __u32 zero = 0; - __u32 pid = bpf_get_current_pid_tgid() >> 32; + __u32 pid = GET_USER_MODE_PID(bpf_get_current_pid_tgid()); test_ctx_t *test_ctx = bpf_map_lookup_elem(&test, &zero); if (!test_ctx || test_ctx->expected_fd != ctx->fd || test_ctx->expected_pid != pid) return 0; diff --git a/pkg/network/ebpf/c/protocols/sockfd-probes.h b/pkg/network/ebpf/c/protocols/sockfd-probes.h index 9c31f236ab087..06ecbeee6fe57 100644 --- a/pkg/network/ebpf/c/protocols/sockfd-probes.h +++ b/pkg/network/ebpf/c/protocols/sockfd-probes.h @@ -13,6 +13,7 @@ #include "sock.h" #include "sockfd.h" +#include "pid_tgid.h" SEC("kprobe/tcp_close") int BPF_KPROBE(kprobe__tcp_close, struct sock *sk) { @@ -53,7 +54,7 @@ int BPF_KPROBE(kprobe__sockfd_lookup_light, int sockfd) { // but can reduce the accuracy of programs relying on socket FDs for // processes with a lot of FD churn pid_fd_t key = { - .pid = pid_tgid >> 32, + .pid = GET_USER_MODE_PID(pid_tgid), .fd = sockfd, }; conn_tuple_t *t = bpf_map_lookup_elem(&tuple_by_pid_fd, &key); @@ -121,7 +122,7 @@ int BPF_KRETPROBE(kretprobe__sockfd_lookup_light, struct socket *socket) { } pid_fd_t pid_fd = { - .pid = pid_tgid >> 32, + .pid = GET_USER_MODE_PID(pid_tgid), .fd = (*sockfd), }; diff --git a/pkg/network/ebpf/c/protocols/tls/go-tls-conn.h b/pkg/network/ebpf/c/protocols/tls/go-tls-conn.h index ba812de0385bd..d297ad11f57cf 100644 --- a/pkg/network/ebpf/c/protocols/tls/go-tls-conn.h +++ b/pkg/network/ebpf/c/protocols/tls/go-tls-conn.h @@ -4,6 +4,7 @@ #include "bpf_helpers.h" #include "ip.h" #include "port_range.h" +#include "pid_tgid.h" #include "protocols/http/maps.h" #include "protocols/tls/go-tls-types.h" @@ -49,7 +50,7 @@ static __always_inline conn_tuple_t* conn_tup_from_tls_conn(tls_offsets_data_t* // The code path below should be executed only once during the lifecycle of a TLS connection pid_fd_t pid_fd = { - .pid = pid_tgid >> 32, + .pid = GET_USER_MODE_PID(pid_tgid), // fd is populated by the code downstream .fd = 0, }; diff --git a/pkg/network/ebpf/c/protocols/tls/https.h b/pkg/network/ebpf/c/protocols/tls/https.h index f1d0562033a54..ac3c509daaeb3 100644 --- a/pkg/network/ebpf/c/protocols/tls/https.h +++ b/pkg/network/ebpf/c/protocols/tls/https.h @@ -17,6 +17,7 @@ #include "bpf_builtins.h" #include "port_range.h" #include "sock.h" +#include "pid_tgid.h" #include "protocols/amqp/helpers.h" #include "protocols/redis/helpers.h" @@ -250,7 +251,7 @@ static __always_inline conn_tuple_t* tup_from_ssl_ctx(void *ssl_ctx, u64 pid_tgi // the code path below should be executed only once during the lifecycle of a SSL session pid_fd_t pid_fd = { - .pid = pid_tgid >> 32, + .pid = GET_USER_MODE_PID(pid_tgid), .fd = ssl_sock->fd, }; diff --git a/pkg/network/ebpf/c/protocols/tls/native-tls-maps.h b/pkg/network/ebpf/c/protocols/tls/native-tls-maps.h index 282c593308b16..5e139833d4302 100644 --- a/pkg/network/ebpf/c/protocols/tls/native-tls-maps.h +++ b/pkg/network/ebpf/c/protocols/tls/native-tls-maps.h @@ -17,6 +17,6 @@ BPF_HASH_MAP(bio_new_socket_args, __u64, __u32, 1024) BPF_HASH_MAP(fd_by_ssl_bio, __u32, void *, 1024) -BPF_HASH_MAP(ssl_ctx_by_pid_tgid, __u64, void *, 1024) +BPF_HASH_MAP(ssl_ctx_by_pid_tgid, __u64, void *, 1) #endif diff --git a/pkg/network/ebpf/c/runtime/conntrack.c b/pkg/network/ebpf/c/runtime/conntrack.c index a054504439230..e7418edcd986e 100644 --- a/pkg/network/ebpf/c/runtime/conntrack.c +++ b/pkg/network/ebpf/c/runtime/conntrack.c @@ -21,6 +21,7 @@ #include "conntrack/maps.h" #include "netns.h" #include "ip.h" +#include "pid_tgid.h" #if defined(FEATURE_TCPV6_ENABLED) || defined(FEATURE_UDPV6_ENABLED) #include "ipv6.h" @@ -50,7 +51,7 @@ int BPF_BYPASSABLE_KPROBE(kprobe___nf_conntrack_hash_insert, struct nf_conn *ct) SEC("kprobe/ctnetlink_fill_info") int BPF_BYPASSABLE_KPROBE(kprobe_ctnetlink_fill_info) { - u32 pid = bpf_get_current_pid_tgid() >> 32; + u32 pid = GET_USER_MODE_PID(bpf_get_current_pid_tgid()); if (pid != systemprobe_pid()) { log_debug("skipping kprobe/ctnetlink_fill_info invocation from non-system-probe process"); return 0; diff --git a/pkg/network/ebpf/c/runtime/usm.c b/pkg/network/ebpf/c/runtime/usm.c index 3cb3f1245a3ab..bf3737b311a92 100644 --- a/pkg/network/ebpf/c/runtime/usm.c +++ b/pkg/network/ebpf/c/runtime/usm.c @@ -13,6 +13,7 @@ #include "ipv6.h" #include "sock.h" #include "port_range.h" +#include "pid_tgid.h" #include "protocols/classification/dispatcher-helpers.h" #include "protocols/http/buffer.h" @@ -84,7 +85,7 @@ int tracepoint__net__netif_receive_skb(void *ctx) { SEC("uprobe/crypto/tls.(*Conn).Write") int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Write) { u64 pid_tgid = bpf_get_current_pid_tgid(); - u64 pid = pid_tgid >> 32; + u64 pid = GET_USER_MODE_PID(pid_tgid); tls_offsets_data_t* od = get_offsets_data(); if (od == NULL) { log_debug("[go-tls-write] no offsets data in map for pid %llu", pid); @@ -125,7 +126,7 @@ int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Write) { SEC("uprobe/crypto/tls.(*Conn).Write/return") int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Write__return) { u64 pid_tgid = bpf_get_current_pid_tgid(); - u64 pid = pid_tgid >> 32; + u64 pid = GET_USER_MODE_PID(pid_tgid); tls_offsets_data_t* od = get_offsets_data(); if (od == NULL) { log_debug("[go-tls-write-return] no offsets data in map for pid %llu", pid); @@ -200,10 +201,10 @@ int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Write__return) { SEC("uprobe/crypto/tls.(*Conn).Read") int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Read) { u64 pid_tgid = bpf_get_current_pid_tgid(); - u64 pid = pid_tgid >> 32; + u64 pid = GET_USER_MODE_PID(pid_tgid); tls_offsets_data_t* od = get_offsets_data(); if (od == NULL) { - log_debug("[go-tls-read] no offsets data in map for pid %llu", pid_tgid >> 32); + log_debug("[go-tls-read] no offsets data in map for pid %llu", pid); return 0; } @@ -211,7 +212,7 @@ int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Read) { go_tls_function_args_key_t call_key = {0}; call_key.pid = pid; if (read_goroutine_id(ctx, &od->goroutine_id, &call_key.goroutine_id)) { - log_debug("[go-tls-read] failed reading go routine id for pid %llu", pid_tgid >> 32); + log_debug("[go-tls-read] failed reading go routine id for pid %llu", pid); return 0; } @@ -219,11 +220,11 @@ int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Read) { // (since the parameters might not be live by the time the return probe is hit). go_tls_read_args_data_t call_data = {0}; if (read_location(ctx, &od->read_conn_pointer, sizeof(call_data.conn_pointer), &call_data.conn_pointer)) { - log_debug("[go-tls-read] failed reading conn pointer for pid %llu", pid_tgid >> 32); + log_debug("[go-tls-read] failed reading conn pointer for pid %llu", pid); return 0; } if (read_location(ctx, &od->read_buffer.ptr, sizeof(call_data.b_data), &call_data.b_data)) { - log_debug("[go-tls-read] failed reading buffer pointer for pid %llu", pid_tgid >> 32); + log_debug("[go-tls-read] failed reading buffer pointer for pid %llu", pid); return 0; } @@ -235,7 +236,7 @@ int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Read) { SEC("uprobe/crypto/tls.(*Conn).Read/return") int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Read__return) { u64 pid_tgid = bpf_get_current_pid_tgid(); - u64 pid = pid_tgid >> 32; + u64 pid = GET_USER_MODE_PID(pid_tgid); tls_offsets_data_t* od = get_offsets_data(); if (od == NULL) { log_debug("[go-tls-read-return] no offsets data in map for pid %llu", pid); @@ -305,13 +306,13 @@ int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Close) { u64 pid_tgid = bpf_get_current_pid_tgid(); tls_offsets_data_t* od = get_offsets_data(); if (od == NULL) { - log_debug("[go-tls-close] no offsets data in map for pid %llu", pid_tgid >> 32); + log_debug("[go-tls-close] no offsets data in map for pid %llu", GET_USER_MODE_PID(pid_tgid)); return 0; } // Read the PID and goroutine ID to make the partial call key go_tls_function_args_key_t call_key = {0}; - call_key.pid = pid_tgid >> 32; + call_key.pid = GET_USER_MODE_PID(pid_tgid); if (read_goroutine_id(ctx, &od->goroutine_id, &call_key.goroutine_id) == 0) { bpf_map_delete_elem(&go_tls_read_args, &call_key); bpf_map_delete_elem(&go_tls_write_args, &call_key); @@ -319,13 +320,13 @@ int BPF_BYPASSABLE_UPROBE(uprobe__crypto_tls_Conn_Close) { void* conn_pointer = NULL; if (read_location(ctx, &od->close_conn_pointer, sizeof(conn_pointer), &conn_pointer)) { - log_debug("[go-tls-close] failed reading close conn pointer for pid %llu", pid_tgid >> 32); + log_debug("[go-tls-close] failed reading close conn pointer for pid %llu", GET_USER_MODE_PID(pid_tgid)); return 0; } conn_tuple_t* t = conn_tup_from_tls_conn(od, conn_pointer, pid_tgid); if (t == NULL) { - log_debug("[go-tls-close] failed getting conn tup from tls conn for pid %llu", pid_tgid >> 32); + log_debug("[go-tls-close] failed getting conn tup from tls conn for pid %llu", GET_USER_MODE_PID(pid_tgid)); return 0; } diff --git a/pkg/network/ebpf/c/shared-libraries/probes.h b/pkg/network/ebpf/c/shared-libraries/probes.h index a33e228a63b26..a45e9d0b494e1 100644 --- a/pkg/network/ebpf/c/shared-libraries/probes.h +++ b/pkg/network/ebpf/c/shared-libraries/probes.h @@ -4,6 +4,7 @@ #include "bpf_telemetry.h" #include "bpf_bypass.h" +#include "pid_tgid.h" #include "shared-libraries/types.h" static __always_inline void fill_path_safe(lib_path_t *path, const char *path_argument) { @@ -38,7 +39,7 @@ static __always_inline void do_sys_open_helper_enter(const char *filename) { } u64 pid_tgid = bpf_get_current_pid_tgid(); - path.pid = pid_tgid >> 32; + path.pid = GET_USER_MODE_PID(pid_tgid); bpf_map_update_with_telemetry(open_at_args, &pid_tgid, &path, BPF_ANY); return; } diff --git a/pkg/network/ebpf/c/sock.h b/pkg/network/ebpf/c/sock.h index c71e48a544f1d..997acc13edef6 100644 --- a/pkg/network/ebpf/c/sock.h +++ b/pkg/network/ebpf/c/sock.h @@ -8,6 +8,7 @@ #include "ip.h" #include "ipv6.h" #include "netns.h" +#include "pid_tgid.h" #ifdef COMPILE_CORE @@ -178,7 +179,7 @@ static __always_inline u16 _sk_family(struct sock *skp) { */ static __always_inline int read_conn_tuple_partial(conn_tuple_t* t, struct sock* skp, u64 pid_tgid, metadata_mask_t type) { int err = 0; - t->pid = pid_tgid >> 32; + t->pid = GET_USER_MODE_PID(pid_tgid); t->metadata = type; // Retrieve network namespace id first since addresses and ports may not be available for unconnected UDP diff --git a/pkg/network/ebpf/c/tracer.c b/pkg/network/ebpf/c/tracer.c index 8de25a2a37e6b..66cefbee1d08d 100644 --- a/pkg/network/ebpf/c/tracer.c +++ b/pkg/network/ebpf/c/tracer.c @@ -19,6 +19,7 @@ #include "tracer/port.h" #include "tracer/tcp_recv.h" #include "protocols/classification/protocol-classification.h" +#include "pid_tgid.h" __maybe_unused static __always_inline bool tcp_failed_connections_enabled() { __u64 val = 0; @@ -226,7 +227,7 @@ int BPF_BYPASSABLE_KPROBE(kprobe__tcp_done, struct sock *sk) { pid_ts_t *failed_conn_pid = bpf_map_lookup_elem(&tcp_ongoing_connect_pid, &skp_conn); if (failed_conn_pid) { bpf_map_delete_elem(&tcp_ongoing_connect_pid, &skp_conn); - t.pid = failed_conn_pid->pid_tgid >> 32; + t.pid = GET_USER_MODE_PID(failed_conn_pid->pid_tgid); } else { increment_telemetry_count(tcp_done_missing_pid); return 0; @@ -256,7 +257,7 @@ int BPF_BYPASSABLE_KPROBE(kprobe__tcp_close, struct sock *sk) { u64 pid_tgid = bpf_get_current_pid_tgid(); // Get network namespace id - log_debug("kprobe/tcp_close: tgid: %llu, pid: %llu", pid_tgid >> 32, pid_tgid & 0xFFFFFFFF); + log_debug("kprobe/tcp_close: kernel thread id: %llu, user mode pid: %llu", GET_KERNEL_THREAD_ID(pid_tgid), GET_USER_MODE_PID(pid_tgid)); if (!read_conn_tuple(&t, sk, pid_tgid, CONN_TYPE_TCP)) { return 0; } @@ -734,7 +735,7 @@ int BPF_BYPASSABLE_KRETPROBE(kretprobe__udpv6_recvmsg) { static __always_inline int handle_ret_udp_recvmsg_pre_4_7_0(int copied, void *udp_sock_map) { u64 pid_tgid = bpf_get_current_pid_tgid(); - log_debug("kretprobe/udp_recvmsg: tgid: %llu, pid: %llu", pid_tgid >> 32, pid_tgid & 0xFFFFFFFF); + log_debug("kretprobe/udp_recvmsg: kernel thread id: %llu, user mode pid: %llu", GET_KERNEL_THREAD_ID(pid_tgid), GET_USER_MODE_PID(pid_tgid)); // Retrieve socket pointer from kprobe via pid/tgid udp_recv_sock_t *st = bpf_map_lookup_elem(udp_sock_map, &pid_tgid); @@ -886,18 +887,18 @@ int BPF_BYPASSABLE_KPROBE(kprobe__tcp_retransmit_skb_pre_4_7_0, struct sock *sk) SEC("kretprobe/tcp_retransmit_skb") int BPF_BYPASSABLE_KRETPROBE(kretprobe__tcp_retransmit_skb, int ret) { - __u64 tid = bpf_get_current_pid_tgid(); + __u64 pid_tgid = bpf_get_current_pid_tgid(); if (ret < 0) { - bpf_map_delete_elem(&pending_tcp_retransmit_skb, &tid); + bpf_map_delete_elem(&pending_tcp_retransmit_skb, &pid_tgid); return 0; } - tcp_retransmit_skb_args_t *args = bpf_map_lookup_elem(&pending_tcp_retransmit_skb, &tid); + tcp_retransmit_skb_args_t *args = bpf_map_lookup_elem(&pending_tcp_retransmit_skb, &pid_tgid); if (args == NULL) { return 0; } struct sock *sk = args->sk; int segs = args->segs; - bpf_map_delete_elem(&pending_tcp_retransmit_skb, &tid); + bpf_map_delete_elem(&pending_tcp_retransmit_skb, &pid_tgid); log_debug("kretprobe/tcp_retransmit: segs: %d", segs); return handle_retransmit(sk, segs); } @@ -908,30 +909,30 @@ int BPF_BYPASSABLE_KRETPROBE(kretprobe__tcp_retransmit_skb, int ret) { SEC("kprobe/tcp_retransmit_skb") int BPF_BYPASSABLE_KPROBE(kprobe__tcp_retransmit_skb, struct sock *sk) { - u64 tid = bpf_get_current_pid_tgid(); + u64 pid_tgid = bpf_get_current_pid_tgid(); tcp_retransmit_skb_args_t args = {}; args.sk = sk; args.segs = 0; BPF_CORE_READ_INTO(&args.retrans_out_pre, tcp_sk(sk), retrans_out); - bpf_map_update_with_telemetry(pending_tcp_retransmit_skb, &tid, &args, BPF_ANY); + bpf_map_update_with_telemetry(pending_tcp_retransmit_skb, &pid_tgid, &args, BPF_ANY); return 0; } SEC("kretprobe/tcp_retransmit_skb") int BPF_BYPASSABLE_KRETPROBE(kretprobe__tcp_retransmit_skb, int rc) { log_debug("kretprobe/tcp_retransmit"); - u64 tid = bpf_get_current_pid_tgid(); + u64 pid_tgid = bpf_get_current_pid_tgid(); if (rc < 0) { - bpf_map_delete_elem(&pending_tcp_retransmit_skb, &tid); + bpf_map_delete_elem(&pending_tcp_retransmit_skb, &pid_tgid); return 0; } - tcp_retransmit_skb_args_t *args = bpf_map_lookup_elem(&pending_tcp_retransmit_skb, &tid); + tcp_retransmit_skb_args_t *args = bpf_map_lookup_elem(&pending_tcp_retransmit_skb, &pid_tgid); if (args == NULL) { return 0; } struct sock *sk = args->sk; u32 retrans_out_pre = args->retrans_out_pre; - bpf_map_delete_elem(&pending_tcp_retransmit_skb, &tid); + bpf_map_delete_elem(&pending_tcp_retransmit_skb, &pid_tgid); u32 retrans_out = 0; BPF_CORE_READ_INTO(&retrans_out, tcp_sk(sk), retrans_out); return handle_retransmit(sk, retrans_out - retrans_out_pre); @@ -942,7 +943,7 @@ int BPF_BYPASSABLE_KRETPROBE(kretprobe__tcp_retransmit_skb, int rc) { SEC("kprobe/tcp_connect") int BPF_BYPASSABLE_KPROBE(kprobe__tcp_connect, struct sock *skp) { u64 pid_tgid = bpf_get_current_pid_tgid(); - log_debug("kprobe/tcp_connect: tgid: %llu, pid: %llu", pid_tgid >> 32, pid_tgid & 0xFFFFFFFF); + log_debug("kprobe/tcp_connect: kernel thread id: %llu, user mode pid: %llu", GET_KERNEL_THREAD_ID(pid_tgid), GET_USER_MODE_PID(pid_tgid)); conn_tuple_t t = {}; if (!read_conn_tuple(&t, skp, 0, CONN_TYPE_TCP)) { @@ -971,8 +972,8 @@ int BPF_BYPASSABLE_KPROBE(kprobe__tcp_finish_connect, struct sock *skp) { } u64 pid_tgid = pid_tgid_p->pid_tgid; - t.pid = pid_tgid >> 32; - log_debug("kprobe/tcp_finish_connect: tgid: %llu, pid: %llu", pid_tgid >> 32, pid_tgid & 0xFFFFFFFF); + t.pid = GET_USER_MODE_PID(pid_tgid); + log_debug("kprobe/tcp_finish_connect: kernel thread id: %llu, user mode pid: %llu", GET_KERNEL_THREAD_ID(pid_tgid), GET_USER_MODE_PID(pid_tgid)); handle_tcp_stats(&t, skp, TCP_ESTABLISHED); handle_message(&t, 0, 0, CONN_DIRECTION_OUTGOING, 0, 0, PACKET_COUNT_NONE, skp); @@ -989,7 +990,7 @@ int BPF_BYPASSABLE_KRETPROBE(kretprobe__inet_csk_accept, struct sock *sk) { } u64 pid_tgid = bpf_get_current_pid_tgid(); - log_debug("kretprobe/inet_csk_accept: tgid: %llu, pid: %llu", pid_tgid >> 32, pid_tgid & 0xFFFFFFFF); + log_debug("kretprobe/inet_csk_accept: kernel thread id: %llu, user mode pid: %llu", GET_KERNEL_THREAD_ID(pid_tgid), GET_USER_MODE_PID(pid_tgid)); conn_tuple_t t = {}; if (!read_conn_tuple(&t, sk, pid_tgid, CONN_TYPE_TCP)) { diff --git a/pkg/network/ebpf/c/tracer/bind.h b/pkg/network/ebpf/c/tracer/bind.h index 67a01a2da4f4c..cc8c3dd99e5cc 100644 --- a/pkg/network/ebpf/c/tracer/bind.h +++ b/pkg/network/ebpf/c/tracer/bind.h @@ -1,6 +1,7 @@ #ifndef __TRACER_BIND_H #define __TRACER_BIND_H +#include "pid_tgid.h" #include "tracer/tracer.h" #include "tracer/maps.h" #include "tracer/port.h" @@ -19,7 +20,7 @@ static __always_inline u16 sockaddr_sin_port(struct sockaddr *addr) { } static __always_inline int sys_enter_bind(struct socket *sock, struct sockaddr *addr) { - __u64 tid = bpf_get_current_pid_tgid(); + __u64 pid_tgid = bpf_get_current_pid_tgid(); __u16 type = 0; bpf_probe_read_kernel_with_telemetry(&type, sizeof(__u16), &sock->type); @@ -28,7 +29,7 @@ static __always_inline int sys_enter_bind(struct socket *sock, struct sockaddr * } if (addr == NULL) { - log_debug("sys_enter_bind: could not read sockaddr, sock=%p, tid=%llu", sock, tid); + log_debug("sys_enter_bind: could not read sockaddr, sock=%p, pid_tgid=%llu", sock, pid_tgid); return 0; } @@ -49,19 +50,19 @@ static __always_inline int sys_enter_bind(struct socket *sock, struct sockaddr * args.addr = addr; - bpf_map_update_with_telemetry(pending_bind, &tid, &args, BPF_ANY); - log_debug("sys_enter_bind: started a bind on UDP sock=%p tid=%llu", sock, tid); + bpf_map_update_with_telemetry(pending_bind, &pid_tgid, &args, BPF_ANY); + log_debug("sys_enter_bind: started a bind on UDP sock=%p pid_tgid=%llu", sock, pid_tgid); return 0; } static __always_inline int sys_exit_bind(__s64 ret) { - __u64 tid = bpf_get_current_pid_tgid(); + __u64 pid_tgid = bpf_get_current_pid_tgid(); // bail if this bind() is not the one we're instrumenting - bind_syscall_args_t *args = bpf_map_lookup_elem(&pending_bind, &tid); + bind_syscall_args_t *args = bpf_map_lookup_elem(&pending_bind, &pid_tgid); - log_debug("sys_exit_bind: tid=%llu, ret=%lld", tid, ret); + log_debug("sys_exit_bind: pid_tgid=%llu, ret=%lld", pid_tgid, ret); if (args == NULL) { log_debug("sys_exit_bind: was not a UDP bind, will not process"); @@ -70,7 +71,7 @@ static __always_inline int sys_exit_bind(__s64 ret) { struct sock * sk = args->sk; struct sockaddr *addr = args->addr; - bpf_map_delete_elem(&pending_bind, &tid); + bpf_map_delete_elem(&pending_bind, &pid_tgid); if (ret != 0) { return 0; diff --git a/pkg/network/ebpf/c/tracer/stats.h b/pkg/network/ebpf/c/tracer/stats.h index b05811c86190a..862d8e32f81f1 100644 --- a/pkg/network/ebpf/c/tracer/stats.h +++ b/pkg/network/ebpf/c/tracer/stats.h @@ -16,6 +16,7 @@ #include "protocols/tls/tags-types.h" #include "ip.h" #include "skb.h" +#include "pid_tgid.h" #ifdef COMPILE_PREBUILT static __always_inline __u64 offset_rtt(); @@ -286,7 +287,7 @@ static __always_inline int handle_skb_consume_udp(struct sock *sk, struct sk_buf flip_tuple(&t); log_debug("skb_consume_udp: bytes=%d", data_len); - t.pid = pid_tgid >> 32; + t.pid = GET_USER_MODE_PID(pid_tgid); t.netns = get_netns_from_sock(sk); return handle_message(&t, 0, data_len, CONN_DIRECTION_UNKNOWN, 0, 1, PACKET_COUNT_INCREMENT, sk); } diff --git a/pkg/network/tracer/connection/ebpfless/map_utils.go b/pkg/network/tracer/connection/ebpfless/map_utils.go new file mode 100644 index 0000000000000..3e41f4832707d --- /dev/null +++ b/pkg/network/tracer/connection/ebpfless/map_utils.go @@ -0,0 +1,19 @@ +// 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 + +// WriteMapWithSizeLimit updates a map via m[key] = val. +// However, if the map would overflow sizeLimit, it returns false instead. +func WriteMapWithSizeLimit[Key comparable, Val any](m map[Key]Val, key Key, val Val, sizeLimit int) bool { + _, exists := m[key] + if !exists && len(m) >= sizeLimit { + return false + } + m[key] = val + return true +} diff --git a/pkg/network/tracer/connection/ebpfless/map_utils_test.go b/pkg/network/tracer/connection/ebpfless/map_utils_test.go new file mode 100644 index 0000000000000..e387328d00610 --- /dev/null +++ b/pkg/network/tracer/connection/ebpfless/map_utils_test.go @@ -0,0 +1,38 @@ +// 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 + +import ( + "github.com/stretchr/testify/require" + "testing" +) + +func TestWriteMapWithSizeLimit(t *testing.T) { + m := map[string]int{} + + // not full: any write should work + ok := WriteMapWithSizeLimit(m, "foo", 123, 1) + require.True(t, ok) + + expectedFoo := map[string]int{ + "foo": 123, + } + require.Equal(t, expectedFoo, m) + + // full: shouldn't write a new key + ok = WriteMapWithSizeLimit(m, "bar", 456, 1) + require.False(t, ok) + require.Equal(t, expectedFoo, m) + + // full: replacing key should still work + ok = WriteMapWithSizeLimit(m, "foo", 789, 1) + require.True(t, ok) + require.Equal(t, map[string]int{ + "foo": 789, + }, m) +} diff --git a/pkg/network/tracer/connection/ebpfless/tcp_processor.go b/pkg/network/tracer/connection/ebpfless/tcp_processor.go index b312f460269ee..73ea6a1152aa3 100644 --- a/pkg/network/tracer/connection/ebpfless/tcp_processor.go +++ b/pkg/network/tracer/connection/ebpfless/tcp_processor.go @@ -9,6 +9,7 @@ package ebpfless import ( "fmt" + "github.com/DataDog/datadog-agent/pkg/util/log" "syscall" "time" @@ -17,7 +18,7 @@ import ( "github.com/google/gopacket/layers" "github.com/DataDog/datadog-agent/pkg/network" - "github.com/DataDog/datadog-agent/pkg/util/log" + "github.com/DataDog/datadog-agent/pkg/network/config" ) type connectionState struct { @@ -51,18 +52,40 @@ type connectionState struct { // remoteFinSeq is the tcp.Seq number for the incoming FIN (including any payload length) remoteFinSeq uint32 + // rttTracker is used to track round trip times rttTracker rttTracker + + // lastUpdateEpoch contains the last timestamp this connection sent/received a packet + // TODO find a way to combine this with ConnectionStats.lastUpdateEpoch + // This exists because connections in pendingConns don't have a ConnectionStats object yet. + // Can we make all connections in TCPProcessor have a ConnectionStats no matter what, and + // filter them out in GetConnections? + lastUpdateEpoch uint64 +} + +func (st *connectionState) hasMissedHandshake() bool { + return st.localSynState == synStateMissed || st.remoteSynState == synStateMissed } // TCPProcessor encapsulates TCP state tracking for the ebpfless tracer type TCPProcessor struct { - conns map[network.ConnectionTuple]connectionState + cfg *config.Config + // pendingConns contains connections with tcpState == connStatAttempted + pendingConns map[network.ConnectionTuple]*connectionState + // establishedConns contains connections with tcpState == connStatEstablished + establishedConns map[network.ConnectionTuple]*connectionState } +// TODO make this into a config value +const maxPendingConns = 4096 +const pendingConnTimeoutNs = uint64(5 * time.Second) + // NewTCPProcessor constructs an empty TCPProcessor -func NewTCPProcessor() *TCPProcessor { +func NewTCPProcessor(cfg *config.Config) *TCPProcessor { return &TCPProcessor{ - conns: map[network.ConnectionTuple]connectionState{}, + cfg: cfg, + pendingConns: make(map[network.ConnectionTuple]*connectionState, maxPendingConns), + establishedConns: make(map[network.ConnectionTuple]*connectionState, cfg.MaxTrackedConnections), } } @@ -125,9 +148,13 @@ func (t *TCPProcessor) updateSynFlag(conn *network.ConnectionStats, st *connecti updateConnStatsForOpen(conn) } // if both synStates are ack'd, move to established - if st.tcpState == connStatAttempted && st.localSynState == synStateAcked && st.remoteSynState == synStateAcked { + if st.tcpState == connStatAttempted && st.localSynState.isSynAcked() && st.remoteSynState.isSynAcked() { st.tcpState = connStatEstablished - conn.Monotonic.TCPEstablished++ + if st.hasMissedHandshake() { + statsTelemetry.missedTCPHandshakes.Inc() + } else { + conn.Monotonic.TCPEstablished++ + } } } @@ -136,6 +163,7 @@ func (t *TCPProcessor) updateSynFlag(conn *network.ConnectionStats, st *connecti func (t *TCPProcessor) updateTCPStats(conn *network.ConnectionStats, st *connectionState, pktType uint8, tcp *layers.TCP, payloadLen uint16, timestampNs uint64) { nextSeq := calcNextSeq(tcp, payloadLen) + st.lastUpdateEpoch = timestampNs if pktType == unix.PACKET_OUTGOING { conn.Monotonic.SentPackets++ // packetCanRetransmit filters out packets that look like retransmits but aren't, like TCP keepalives @@ -155,7 +183,7 @@ func (t *TCPProcessor) updateTCPStats(conn *network.ConnectionStats, st *connect ackOutdated := !st.hasLocalAck || isSeqBefore(st.lastLocalAck, tcp.Ack) if tcp.ACK && ackOutdated { // wait until data comes in via synStateAcked - if st.hasLocalAck && st.remoteSynState == synStateAcked { + if st.hasLocalAck && st.remoteSynState.isSynAcked() { ackDiff := tcp.Ack - st.lastLocalAck isFinAck := st.hasRemoteFin && tcp.Ack == st.remoteFinSeq if isFinAck { @@ -232,13 +260,13 @@ func (t *TCPProcessor) updateRstFlag(conn *network.ConnectionStats, st *connecti // Process handles a TCP packet, calculating stats and keeping track of its state according to the // TCP state machine. -func (t *TCPProcessor) Process(conn *network.ConnectionStats, timestampNs uint64, pktType uint8, ip4 *layers.IPv4, ip6 *layers.IPv6, tcp *layers.TCP) error { +func (t *TCPProcessor) Process(conn *network.ConnectionStats, timestampNs uint64, pktType uint8, ip4 *layers.IPv4, ip6 *layers.IPv6, tcp *layers.TCP) (ProcessResult, error) { if pktType != unix.PACKET_OUTGOING && pktType != unix.PACKET_HOST { - return fmt.Errorf("TCPProcessor saw invalid pktType: %d", pktType) + return ProcessResultNone, fmt.Errorf("TCPProcessor saw invalid pktType: %d", pktType) } payloadLen, err := TCPPayloadLen(conn.Family, ip4, ip6, tcp) if err != nil { - return err + return ProcessResultNone, err } log.TraceFunc(func() string { @@ -247,16 +275,93 @@ func (t *TCPProcessor) Process(conn *network.ConnectionStats, timestampNs uint64 // skip invalid packets we don't recognize: if checkInvalidTCP(tcp) { - return nil + return ProcessResultNone, nil } - st := t.conns[conn.ConnectionTuple] + st := t.getConn(conn.ConnectionTuple) + origState := st.tcpState - t.updateSynFlag(conn, &st, pktType, tcp, payloadLen) - t.updateTCPStats(conn, &st, pktType, tcp, payloadLen, timestampNs) - t.updateFinFlag(conn, &st, pktType, tcp, payloadLen) - t.updateRstFlag(conn, &st, pktType, tcp, payloadLen) + t.updateSynFlag(conn, st, pktType, tcp, payloadLen) + t.updateTCPStats(conn, st, pktType, tcp, payloadLen, timestampNs) + t.updateFinFlag(conn, st, pktType, tcp, payloadLen) + t.updateRstFlag(conn, st, pktType, tcp, payloadLen) + + stateChanged := st.tcpState != origState + if stateChanged { + ok := t.moveConn(conn.ConnectionTuple, st) + // if the map is full then we are unable to move the connection, report that + if !ok { + return ProcessResultMapFull, nil + } + } + + // if the connection is still established, we should update the connection map + if st.tcpState == connStatEstablished { + return ProcessResultStoreConn, nil + } + // if the connection just closed, store it in the tracer's closeCallback + if st.tcpState == connStatClosed && stateChanged { + return ProcessResultCloseConn, nil + } + return ProcessResultNone, nil +} - t.conns[conn.ConnectionTuple] = st - return nil +func (t *TCPProcessor) getConn(tuple network.ConnectionTuple) *connectionState { + if st, ok := t.establishedConns[tuple]; ok { + return st + } + if st, ok := t.pendingConns[tuple]; ok { + return st + } + // otherwise, create a fresh state object that will be stored by moveConn later + return &connectionState{} +} + +// RemoveConn clears a ConnectionTuple from its internal state. +func (t *TCPProcessor) RemoveConn(tuple network.ConnectionTuple) { + delete(t.pendingConns, tuple) + delete(t.establishedConns, tuple) +} + +// moveConn moves a connection to the correct map based on its tcpState. +// If it had to drop the connection because the target map was full, it returns false. +func (t *TCPProcessor) moveConn(tuple network.ConnectionTuple, st *connectionState) bool { + t.RemoveConn(tuple) + + switch st.tcpState { + // For this case, simply let closed connections disappear. Process() will return + // ProcessResultCloseConn letting the ebpfless tracer know the connection has closed. + case connStatClosed: + case connStatAttempted: + ok := WriteMapWithSizeLimit(t.pendingConns, tuple, st, maxPendingConns) + if !ok { + statsTelemetry.droppedPendingConns.Inc() + } + return ok + case connStatEstablished: + maxTrackedConns := int(t.cfg.MaxTrackedConnections) + ok := WriteMapWithSizeLimit(t.establishedConns, tuple, st, maxTrackedConns) + if !ok { + statsTelemetry.droppedEstablishedConns.Inc() + } + return ok + } + return true +} + +// CleanupExpiredPendingConns iterates through pendingConns and removes those that +// have existed too long - in normal TCP, they should become established right away. +// +// This is only required for pendingConns because the tracer already has logic to remove +// established connections (connections that have ConnectionStats) +func (t *TCPProcessor) CleanupExpiredPendingConns(timestampNs uint64) { + for tuple, st := range t.pendingConns { + timeoutTime := st.lastUpdateEpoch + pendingConnTimeoutNs + + if timeoutTime <= timestampNs { + delete(t.pendingConns, tuple) + + statsTelemetry.expiredPendingConns.Inc() + } + } } diff --git a/pkg/network/tracer/connection/ebpfless/tcp_processor_test.go b/pkg/network/tracer/connection/ebpfless/tcp_processor_test.go index 8656a73463d36..b7d525bce1531 100644 --- a/pkg/network/tracer/connection/ebpfless/tcp_processor_test.go +++ b/pkg/network/tracer/connection/ebpfless/tcp_processor_test.go @@ -8,9 +8,11 @@ package ebpfless import ( + "github.com/DataDog/datadog-agent/pkg/network/config" "net" "syscall" "testing" + "time" "golang.org/x/sys/unix" @@ -166,22 +168,24 @@ func (pb packetBuilder) outgoing(payloadLen uint16, relSeq, relAck uint32, flags } func newTCPTestFixture(t *testing.T) *tcpTestFixture { + cfg := config.New() return &tcpTestFixture{ t: t, - tcp: NewTCPProcessor(), + tcp: NewTCPProcessor(cfg), conn: nil, } } -func (fixture *tcpTestFixture) runPkt(pkt testCapture) { +func (fixture *tcpTestFixture) runPkt(pkt testCapture) ProcessResult { if fixture.conn == nil { fixture.conn = makeTCPStates(pkt) } - err := fixture.tcp.Process(fixture.conn, pkt.timestampNs, pkt.pktType, pkt.ipv4, pkt.ipv6, pkt.tcp) + result, err := fixture.tcp.Process(fixture.conn, pkt.timestampNs, pkt.pktType, pkt.ipv4, pkt.ipv6, pkt.tcp) require.NoError(fixture.t, err) + return result } -func (fixture *tcpTestFixture) runPkts(packets []testCapture) { //nolint:unused // TODO +func (fixture *tcpTestFixture) runPkts(packets []testCapture) { for _, pkt := range packets { fixture.runPkt(pkt) } @@ -197,7 +201,7 @@ func (fixture *tcpTestFixture) runAgainstState(packets []testCapture, expected [ fixture.runPkt(pkt) connTuple := fixture.conn.ConnectionTuple - actual := fixture.tcp.conns[connTuple].tcpState + actual := fixture.tcp.getConn(connTuple).tcpState actualStrs = append(actualStrs, labelForState(actual)) } require.Equal(fixture.t, expectedStrs, actualStrs) @@ -255,6 +259,9 @@ func testBasicHandshake(t *testing.T, pb packetBuilder) { } require.Equal(t, expectedStats, f.conn.Monotonic) + + require.Empty(t, f.tcp.pendingConns) + require.Empty(t, f.tcp.establishedConns) } var lowerSeq uint32 = 2134452051 @@ -322,6 +329,9 @@ func testReversedBasicHandshake(t *testing.T, pb packetBuilder) { TCPClosed: 1, } require.Equal(t, expectedStats, f.conn.Monotonic) + + require.Empty(t, f.tcp.pendingConns) + require.Empty(t, f.tcp.establishedConns) } func TestReversedBasicHandshake(t *testing.T) { @@ -614,9 +624,8 @@ func TestConnReset(t *testing.T) { require.Equal(t, expectedStats, f.conn.Monotonic) } -func TestConnectTwice(t *testing.T) { - // same as TestImmediateFin but everything happens twice - +func TestProcessResult(t *testing.T) { + // same as TestImmediateFin but checks ProcessResult pb := newPacketBuilder(lowerSeq, higherSeq) basicHandshake := []testCapture{ pb.incoming(0, 0, 0, SYN), @@ -628,40 +637,20 @@ func TestConnectTwice(t *testing.T) { pb.outgoing(0, 2, 2, ACK), } - expectedClientStates := []connStatus{ - connStatAttempted, - connStatAttempted, - connStatEstablished, - // active close begins here - connStatEstablished, - connStatEstablished, - connStatClosed, + processResults := []ProcessResult{ + ProcessResultNone, + ProcessResultNone, + ProcessResultStoreConn, + ProcessResultStoreConn, + ProcessResultStoreConn, + ProcessResultCloseConn, } f := newTCPTestFixture(t) - f.runAgainstState(basicHandshake, expectedClientStates) - state := f.tcp.conns[f.conn.ConnectionTuple] - // make sure the TCP state was erased after the connection was closed - require.Equal(t, connectionState{ - tcpState: connStatClosed, - }, state) - - // second connection here - f.runAgainstState(basicHandshake, expectedClientStates) - - require.Empty(t, f.conn.TCPFailures) - - expectedStats := network.StatCounters{ - SentBytes: 0, - RecvBytes: 0, - SentPackets: 3 * 2, - RecvPackets: 3 * 2, - Retransmits: 0, - TCPEstablished: 1 * 2, - TCPClosed: 1 * 2, + for i, pkt := range basicHandshake { + require.Equal(t, processResults[i], f.runPkt(pkt), "packet #%d has the wrong ProcessResult", i) } - require.Equal(t, expectedStats, f.conn.Monotonic) } func TestSimultaneousClose(t *testing.T) { @@ -775,3 +764,54 @@ func TestOpenCloseConn(t *testing.T) { f.runPkt(pb.incoming(0, 0, 0, SYN)) require.False(t, f.conn.IsClosed) } +func TestPreexistingConn(t *testing.T) { + pb := newPacketBuilder(lowerSeq, higherSeq) + + f := newTCPTestFixture(t) + + capture := []testCapture{ + // just sending data, no SYN + pb.outgoing(1, 10, 10, ACK), + pb.incoming(1, 10, 11, ACK), + // active close after sending no data + pb.outgoing(0, 11, 11, FIN|ACK), + pb.incoming(0, 11, 12, FIN|ACK), + pb.outgoing(0, 12, 12, ACK), + } + f.runPkts(capture) + + require.Empty(t, f.conn.TCPFailures) + + expectedStats := network.StatCounters{ + SentBytes: 1, + RecvBytes: 1, + SentPackets: 3, + RecvPackets: 2, + Retransmits: 0, + TCPEstablished: 0, // we missed when it established + TCPClosed: 1, + } + require.Equal(t, expectedStats, f.conn.Monotonic) +} + +func TestPendingConnExpiry(t *testing.T) { + now := uint64(time.Now().UnixNano()) + + pb := newPacketBuilder(lowerSeq, higherSeq) + pkt := pb.outgoing(0, 0, 0, SYN) + pkt.timestampNs = now + + f := newTCPTestFixture(t) + + f.runPkt(pkt) + require.Len(t, f.tcp.pendingConns, 1) + + // if no time has passed, should not remove the connection + f.tcp.CleanupExpiredPendingConns(now) + require.Len(t, f.tcp.pendingConns, 1) + + // if too much time has passed, should remove the connection + tenSecNs := uint64((10 * time.Second).Nanoseconds()) + f.tcp.CleanupExpiredPendingConns(now + tenSecNs) + require.Empty(t, f.tcp.pendingConns) +} diff --git a/pkg/network/tracer/connection/ebpfless/tcp_utils.go b/pkg/network/tracer/connection/ebpfless/tcp_utils.go index 1969fd85a5bc1..7a30737e734ae 100644 --- a/pkg/network/tracer/connection/ebpfless/tcp_utils.go +++ b/pkg/network/tracer/connection/ebpfless/tcp_utils.go @@ -21,18 +21,42 @@ import ( const ebpflessModuleName = "ebpfless_network_tracer" +// ProcessResult represents what the ebpfless tracer should do with ConnectionStats after processing a packet +type ProcessResult uint8 + +const ( + // ProcessResultNone - the updated ConnectionStats should NOT be stored in the connection map. + // Usually, this is because the connection is not established yet. + ProcessResultNone ProcessResult = iota + // ProcessResultStoreConn - the updated ConnectionStats should be stored in the connection map. + // This happens when the connection is established. + ProcessResultStoreConn + // ProcessResultCloseConn - this connection is done and its ConnectionStats should be passed + // to the ebpfless tracer's closed connection handler. + ProcessResultCloseConn + // ProcessResultMapFull - this connection can't be tracked because the TCPProcessor's connection + // map is full. This connection should be removed from the tracer as well. + ProcessResultMapFull +) + var statsTelemetry = struct { - missedTCPConnections telemetry.Counter - missingTCPFlags telemetry.Counter - tcpSynAndFin telemetry.Counter - tcpRstAndSyn telemetry.Counter - tcpRstAndFin telemetry.Counter + expiredPendingConns telemetry.Counter + droppedPendingConns telemetry.Counter + droppedEstablishedConns telemetry.Counter + missedTCPHandshakes telemetry.Counter + missingTCPFlags telemetry.Counter + tcpSynAndFin telemetry.Counter + tcpRstAndSyn telemetry.Counter + tcpRstAndFin telemetry.Counter }{ - telemetry.NewCounter(ebpflessModuleName, "missed_tcp_connections", []string{}, "Counter measuring the number of TCP connections where we missed the SYN handshake"), - telemetry.NewCounter(ebpflessModuleName, "missing_tcp_flags", []string{}, "Counter measuring packets encountered with none of SYN, FIN, ACK, RST set"), - telemetry.NewCounter(ebpflessModuleName, "tcp_syn_and_fin", []string{}, "Counter measuring packets encountered with SYN+FIN together"), - telemetry.NewCounter(ebpflessModuleName, "tcp_rst_and_syn", []string{}, "Counter measuring packets encountered with RST+SYN together"), - telemetry.NewCounter(ebpflessModuleName, "tcp_rst_and_fin", []string{}, "Counter measuring packets encountered with RST+FIN together"), + expiredPendingConns: telemetry.NewCounter(ebpflessModuleName, "expired_pending_conns", nil, "Counter measuring the number of TCP connections which expired because it took too long to complete the handshake"), + droppedPendingConns: telemetry.NewCounter(ebpflessModuleName, "dropped_pending_conns", nil, "Counter measuring the number of TCP connections which were dropped during the handshake (because the map was full)"), + droppedEstablishedConns: telemetry.NewCounter(ebpflessModuleName, "dropped_established_conns", nil, "Counter measuring the number of TCP connections which were dropped while established (because the map was full)"), + missedTCPHandshakes: telemetry.NewCounter(ebpflessModuleName, "missed_tcp_handshakes", nil, "Counter measuring the number of TCP connections where we missed the SYN handshake"), + missingTCPFlags: telemetry.NewCounter(ebpflessModuleName, "missing_tcp_flags", nil, "Counter measuring packets encountered with none of SYN, FIN, ACK, RST set"), + tcpSynAndFin: telemetry.NewCounter(ebpflessModuleName, "tcp_syn_and_fin", nil, "Counter measuring packets encountered with SYN+FIN together"), + tcpRstAndSyn: telemetry.NewCounter(ebpflessModuleName, "tcp_rst_and_syn", nil, "Counter measuring packets encountered with RST+SYN together"), + tcpRstAndFin: telemetry.NewCounter(ebpflessModuleName, "tcp_rst_and_fin", nil, "Counter measuring packets encountered with RST+FIN together"), } const tcpSeqMidpoint = 0x80000000 @@ -54,9 +78,16 @@ var connStatusLabels = []string{ type synState uint8 const ( + // synStateNone - Nothing seen yet (initial state) synStateNone synState = iota + // synStateSent - We have seen the SYN but not its ACK synStateSent + // synStateAcked - SYN is ACK'd for this side of the connection. + // If both sides are synStateAcked, the connection is established. synStateAcked + // synStateMissed is effectively the same as synStateAcked but represents + // capturing a preexisting connection where we didn't get to see the SYN. + synStateMissed ) func (ss *synState) update(synFlag, ackFlag bool) { @@ -68,13 +99,20 @@ func (ss *synState) update(synFlag, ackFlag bool) { if *ss == synStateSent && ackFlag { *ss = synStateAcked } + + // this allows synStateMissed to recover via SYN in order to pass TestUnusualAckSyn + if *ss == synStateMissed && synFlag { + *ss = synStateAcked + } // if we see ACK'd traffic but missed the SYN, assume the connection started before // the datadog-agent starts. if *ss == synStateNone && ackFlag { - statsTelemetry.missedTCPConnections.Inc() - *ss = synStateAcked + *ss = synStateMissed } } +func (ss *synState) isSynAcked() bool { + return *ss == synStateAcked || *ss == synStateMissed +} func labelForState(tcpState connStatus) string { idx := int(tcpState) diff --git a/pkg/network/tracer/connection/ebpfless_tracer.go b/pkg/network/tracer/connection/ebpfless_tracer.go index 8bb0a54f170ec..3eb5a03344b2a 100644 --- a/pkg/network/tracer/connection/ebpfless_tracer.go +++ b/pkg/network/tracer/connection/ebpfless_tracer.go @@ -40,9 +40,11 @@ const ( var ( ebpfLessTracerTelemetry = struct { - skippedPackets telemetry.Counter + skippedPackets telemetry.Counter + droppedConnections telemetry.Counter }{ telemetry.NewCounter(ebpfLessTelemetryPrefix, "skipped_packets", []string{"reason"}, "Counter measuring skipped packets"), + telemetry.NewCounter(ebpfLessTelemetryPrefix, "dropped_connections", nil, "Counter measuring dropped connections"), } ) @@ -81,7 +83,7 @@ func newEbpfLessTracer(cfg *config.Config) (*ebpfLessTracer, error) { exit: make(chan struct{}), scratchConn: &network.ConnectionStats{}, udp: &udpProcessor{}, - tcp: ebpfless.NewTCPProcessor(), + tcp: ebpfless.NewTCPProcessor(cfg), conns: make(map[network.ConnectionTuple]*network.ConnectionStats, cfg.MaxTrackedConnections), boundPorts: ebpfless.NewBoundPorts(cfg), cookieHasher: newCookieHasher(), @@ -96,7 +98,7 @@ func newEbpfLessTracer(cfg *config.Config) (*ebpfLessTracer, error) { } // Start begins collecting network connection data. -func (t *ebpfLessTracer) Start(_ func(*network.ConnectionStats)) error { +func (t *ebpfLessTracer) Start(closeCallback func(*network.ConnectionStats)) error { if err := t.boundPorts.Start(); err != nil { return fmt.Errorf("could not update bound ports: %w", err) } @@ -123,7 +125,7 @@ func (t *ebpfLessTracer) Start(_ func(*network.ConnectionStats)) error { return nil } - if err := t.processConnection(pktType, &ip4, &ip6, &udp, &tcp, decoded); err != nil { + if err := t.processConnection(pktType, &ip4, &ip6, &udp, &tcp, decoded, closeCallback); err != nil { log.Warnf("could not process packet: %s", err) } @@ -147,21 +149,24 @@ func (t *ebpfLessTracer) processConnection( udp *layers.UDP, tcp *layers.TCP, decoded []gopacket.LayerType, + closeCallback func(*network.ConnectionStats), ) error { t.scratchConn.Source, t.scratchConn.Dest = util.Address{}, util.Address{} t.scratchConn.SPort, t.scratchConn.DPort = 0, 0 t.scratchConn.TCPFailures = make(map[uint16]uint32) - var udpPresent, tcpPresent bool + var ip4Present, ip6Present, 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 + ip4Present = true case layers.LayerTypeIPv6: t.scratchConn.Source = util.AddressFromNetIP(ip6.SrcIP) t.scratchConn.Dest = util.AddressFromNetIP(ip6.DstIP) t.scratchConn.Family = network.AFINET6 + ip6Present = true case layers.LayerTypeTCP: t.scratchConn.SPort = uint16(tcp.SrcPort) t.scratchConn.DPort = uint16(tcp.DstPort) @@ -175,15 +180,15 @@ func (t *ebpfLessTracer) processConnection( } } - // check if have all the basic pieces + // check if we 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) + flipSourceDest(t.scratchConn, pktType) t.m.Lock() defer t.m.Unlock() @@ -201,21 +206,25 @@ func (t *ebpfLessTracer) processConnection( if ts, err = ddebpf.NowNanoseconds(); err != nil { return fmt.Errorf("error getting last updated timestamp for connection: %w", err) } + conn.LastUpdateEpoch = uint64(ts) - if ip4 == nil && ip6 == nil { + if !ip4Present && !ip6Present { return nil } + + var result ebpfless.ProcessResult switch conn.Type { case network.UDP: - if (ip4 != nil && !t.config.CollectUDPv4Conns) || (ip6 != nil && !t.config.CollectUDPv6Conns) { + if (ip4Present && !t.config.CollectUDPv4Conns) || (ip6Present && !t.config.CollectUDPv6Conns) { return nil } + result = ebpfless.ProcessResultStoreConn err = t.udp.process(conn, pktType, udp) case network.TCP: - if (ip4 != nil && !t.config.CollectTCPv4Conns) || (ip6 != nil && !t.config.CollectTCPv6Conns) { + if (ip4Present && !t.config.CollectTCPv4Conns) || (ip6Present && !t.config.CollectTCPv6Conns) { return nil } - err = t.tcp.Process(conn, uint64(ts), pktType, ip4, ip6, tcp) + result, err = t.tcp.Process(conn, uint64(ts), pktType, ip4, ip6, tcp) default: err = fmt.Errorf("unsupported connection type %d", conn.Type) } @@ -224,14 +233,30 @@ func (t *ebpfLessTracer) processConnection( return fmt.Errorf("error processing connection: %w", err) } - if conn.Type == network.UDP || conn.Monotonic.TCPEstablished > 0 { - conn.LastUpdateEpoch = uint64(ts) - t.conns[t.scratchConn.ConnectionTuple] = conn - } - log.TraceFunc(func() string { return fmt.Sprintf("connection: %s", conn) }) + + switch result { + case ebpfless.ProcessResultNone: + case ebpfless.ProcessResultStoreConn: + maxTrackedConns := int(t.config.MaxTrackedConnections) + ok := ebpfless.WriteMapWithSizeLimit(t.conns, conn.ConnectionTuple, conn, maxTrackedConns) + if !ok { + // we don't have enough space to add this connection, remove its TCP state tracking + if conn.Type == network.TCP { + t.tcp.RemoveConn(conn.ConnectionTuple) + } + ebpfLessTracerTelemetry.droppedConnections.Inc() + } + case ebpfless.ProcessResultCloseConn: + delete(t.conns, conn.ConnectionTuple) + closeCallback(conn) + case ebpfless.ProcessResultMapFull: + delete(t.conns, conn.ConnectionTuple) + ebpfLessTracerTelemetry.droppedConnections.Inc() + } + return nil } @@ -278,6 +303,12 @@ func (t *ebpfLessTracer) GetConnections(buffer *network.ConnectionBuffer, filter t.m.Lock() defer t.m.Unlock() + // use GetConnections to periodically cleanup pending connections + err := t.cleanupPendingConns() + if err != nil { + return err + } + if len(t.conns) == 0 { return nil } @@ -296,17 +327,35 @@ func (t *ebpfLessTracer) GetConnections(buffer *network.ConnectionBuffer, filter return nil } +// cleanupPendingConns removes pending connections from the TCP tracer. +// For more information, refer to CleanupExpiredPendingConns +func (t *ebpfLessTracer) cleanupPendingConns() error { + ts, err := ddebpf.NowNanoseconds() + if err != nil { + return fmt.Errorf("error getting last updated timestamp for connection: %w", err) + } + t.tcp.CleanupExpiredPendingConns(uint64(ts)) + return nil +} + // FlushPending forces any closed connections waiting for batching to be processed immediately. func (t *ebpfLessTracer) FlushPending() {} +func (t *ebpfLessTracer) remove(conn *network.ConnectionStats) error { + delete(t.conns, conn.ConnectionTuple) + if conn.Type == network.TCP { + t.tcp.RemoveConn(conn.ConnectionTuple) + } + return nil +} + // 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, conn.ConnectionTuple) - return nil + return t.remove(conn) } // GetMap returns the underlying named map. This is useful if any maps are shared with other eBPF components. diff --git a/pkg/network/tracer/tracer_linux_test.go b/pkg/network/tracer/tracer_linux_test.go index d90928d560da8..46f33ac7fa405 100644 --- a/pkg/network/tracer/tracer_linux_test.go +++ b/pkg/network/tracer/tracer_linux_test.go @@ -109,7 +109,7 @@ func (s *TracerSuite) TestTCPRemoveEntries() { defer c2.Close() assert.EventuallyWithT(t, func(ct *assert.CollectT) { - conn, ok := findConnection(c2.LocalAddr(), c2.RemoteAddr(), getConnections(t, tr)) + conn, ok := findConnection(c2.LocalAddr(), c2.RemoteAddr(), getConnections(ct, tr)) if !assert.True(ct, ok) { return } @@ -123,9 +123,9 @@ func (s *TracerSuite) TestTCPRemoveEntries() { }, 3*time.Second, 100*time.Millisecond) // Make sure the first connection got cleaned up - assert.Eventually(t, func() bool { - _, ok := findConnection(c.LocalAddr(), c.RemoteAddr(), getConnections(t, tr)) - return !ok + assert.EventuallyWithT(t, func(ct *assert.CollectT) { + _, ok := findConnection(c.LocalAddr(), c.RemoteAddr(), getConnections(ct, tr)) + require.False(ct, ok) }, 5*time.Second, 100*time.Millisecond) } @@ -735,10 +735,10 @@ func (s *TracerSuite) TestGatewayLookupEnabled() { dnsServerAddr := &net.UDPAddr{IP: dnsAddr, Port: 53} var conn *network.ConnectionStats - require.Eventually(t, func() bool { + require.EventuallyWithT(t, func(ct *assert.CollectT) { var ok bool - conn, ok = findConnection(dnsClientAddr, dnsServerAddr, getConnections(t, tr)) - return ok + conn, ok = findConnection(dnsClientAddr, dnsServerAddr, getConnections(ct, tr)) + require.True(ct, ok, "connection not found") }, 3*time.Second, 100*time.Millisecond) require.NotNil(t, conn.Via, "connection is missing via: %s", conn) @@ -791,10 +791,10 @@ func (s *TracerSuite) TestGatewayLookupSubnetLookupError() { dnsClientAddr := &net.UDPAddr{IP: net.ParseIP(clientIP), Port: clientPort} dnsServerAddr := &net.UDPAddr{IP: destAddr, Port: 53} var c *network.ConnectionStats - require.Eventually(t, func() bool { + require.EventuallyWithT(t, func(ct *assert.CollectT) { var ok bool - c, ok = findConnection(dnsClientAddr, dnsServerAddr, getConnections(t, tr)) - return ok + c, ok = findConnection(dnsClientAddr, dnsServerAddr, getConnections(ct, tr)) + require.True(ct, ok, "connection not found") }, 3*time.Second, 100*time.Millisecond, "connection not found") require.Nil(t, c.Via) @@ -804,10 +804,10 @@ func (s *TracerSuite) TestGatewayLookupSubnetLookupError() { }, 6*time.Second, 100*time.Millisecond, "failed to send dns query") dnsClientAddr = &net.UDPAddr{IP: net.ParseIP(clientIP), Port: clientPort} - require.Eventually(t, func() bool { + require.EventuallyWithT(t, func(ct *assert.CollectT) { var ok bool - c, ok = findConnection(dnsClientAddr, dnsServerAddr, getConnections(t, tr)) - return ok + c, ok = findConnection(dnsClientAddr, dnsServerAddr, getConnections(ct, tr)) + require.True(ct, ok, "connection not found") }, 3*time.Second, 100*time.Millisecond, "connection not found") require.Nil(t, c.Via) @@ -1529,25 +1529,25 @@ func testUDPReusePort(t *testing.T, udpnet string, ip string) { assert.EventuallyWithT(t, func(ct *assert.CollectT) { //nolint:revive // TODO // use t instead of ct because getConnections uses require (not assert), and we get a better error message that way - connections := getConnections(t, tr) + connections := getConnections(ct, tr) incoming, ok := findConnection(c.RemoteAddr(), c.LocalAddr(), connections) - if assert.True(t, ok, "unable to find incoming connection") { - assert.Equal(t, network.INCOMING, incoming.Direction) + if assert.True(ct, ok, "unable to find incoming connection") { + assert.Equal(ct, network.INCOMING, incoming.Direction) // make sure the inverse values are seen for the other message - assert.Equal(t, serverMessageSize, int(incoming.Monotonic.SentBytes), "incoming sent") - assert.Equal(t, clientMessageSize, int(incoming.Monotonic.RecvBytes), "incoming recv") - assert.True(t, incoming.IntraHost, "incoming intrahost") + assert.Equal(ct, serverMessageSize, int(incoming.Monotonic.SentBytes), "incoming sent") + assert.Equal(ct, clientMessageSize, int(incoming.Monotonic.RecvBytes), "incoming recv") + assert.True(ct, incoming.IntraHost, "incoming intrahost") } outgoing, ok := findConnection(c.LocalAddr(), c.RemoteAddr(), connections) - if assert.True(t, ok, "unable to find outgoing connection") { - assert.Equal(t, network.OUTGOING, outgoing.Direction) + if assert.True(ct, ok, "unable to find outgoing connection") { + assert.Equal(ct, network.OUTGOING, outgoing.Direction) - assert.Equal(t, clientMessageSize, int(outgoing.Monotonic.SentBytes), "outgoing sent") - assert.Equal(t, serverMessageSize, int(outgoing.Monotonic.RecvBytes), "outgoing recv") - assert.True(t, outgoing.IntraHost, "outgoing intrahost") + assert.Equal(ct, clientMessageSize, int(outgoing.Monotonic.SentBytes), "outgoing sent") + assert.Equal(ct, serverMessageSize, int(outgoing.Monotonic.RecvBytes), "outgoing recv") + assert.True(ct, outgoing.IntraHost, "outgoing intrahost") } }, 3*time.Second, 100*time.Millisecond) @@ -1660,8 +1660,8 @@ func (s *TracerSuite) TestSendfileRegression() { t.Logf("looking for connections %+v <-> %+v", c.LocalAddr(), c.RemoteAddr()) var outConn, inConn *network.ConnectionStats - assert.Eventually(t, func() bool { - conns := getConnections(t, tr) + assert.EventuallyWithT(t, func(ct *assert.CollectT) { + conns := getConnections(ct, tr) t.Log(conns) if outConn == nil { outConn = network.FirstConnection(conns, network.ByType(connType), network.ByFamily(family), network.ByTuple(c.LocalAddr(), c.RemoteAddr())) @@ -1669,7 +1669,8 @@ func (s *TracerSuite) TestSendfileRegression() { if inConn == nil { inConn = network.FirstConnection(conns, network.ByType(connType), network.ByFamily(family), network.ByTuple(c.RemoteAddr(), c.LocalAddr())) } - return outConn != nil && inConn != nil + require.NotNil(ct, outConn) + require.NotNil(ct, inConn) }, 3*time.Second, 100*time.Millisecond, "couldn't find connections used by sendfile(2)") if assert.NotNil(t, outConn, "couldn't find outgoing connection used by sendfile(2)") { @@ -1979,16 +1980,16 @@ func (s *TracerSuite) TestPreexistingConnectionDirection() { t := s.T() // Start the client and server before we enable the system probe to test that the tracer picks // up the pre-existing connection - server := tracertestutil.NewTCPServer(func(c net.Conn) { r := bufio.NewReader(c) for { if _, err := r.ReadBytes(byte('\n')); err != nil { assert.ErrorIs(t, err, io.EOF, "exited server loop with error that is not EOF") - return + break } _, _ = c.Write(genPayload(serverMessageSize)) } + c.Close() }) t.Cleanup(server.Shutdown) require.NoError(t, server.Run()) @@ -2023,37 +2024,55 @@ func (s *TracerSuite) TestPreexistingConnectionDirection() { } require.NotNil(collect, outgoing) require.NotNil(collect, incoming) - }, 3*time.Second, 100*time.Millisecond, "could not find connection incoming and outgoing connections") + if !assert.True(collect, incoming != nil && outgoing != nil) { + return + } - m := outgoing.Monotonic - assert.Equal(t, clientMessageSize, int(m.SentBytes)) - assert.Equal(t, serverMessageSize, int(m.RecvBytes)) - 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) + m := outgoing.Monotonic + assert.Equal(collect, clientMessageSize, int(m.SentBytes)) + // ebpfless RecvBytes is based off acknowledgements, so it can miss the first + // packet in a pre-existing connection + if !tr.config.EnableEbpfless { + assert.Equal(collect, serverMessageSize, int(m.RecvBytes)) + } + if !tr.config.EnableEbpfless { + assert.Equal(collect, os.Getpid(), int(outgoing.Pid)) + } + assert.Equal(collect, addrPort(server.Address()), int(outgoing.DPort)) + assert.Equal(collect, c.LocalAddr().(*net.TCPAddr).Port, int(outgoing.SPort)) + assert.Equal(collect, network.OUTGOING, outgoing.Direction) + + m = incoming.Monotonic + // ebpfless RecvBytes is based off acknowledgements, so it can miss the first + // packet in a pre-existing connection + if !tr.config.EnableEbpfless { + assert.Equal(collect, clientMessageSize, int(m.RecvBytes)) + } + assert.Equal(collect, serverMessageSize, int(m.SentBytes)) + if !tr.config.EnableEbpfless { + assert.Equal(collect, os.Getpid(), int(incoming.Pid)) + } + assert.Equal(collect, addrPort(server.Address()), int(incoming.SPort)) + assert.Equal(collect, c.LocalAddr().(*net.TCPAddr).Port, int(incoming.DPort)) + assert.Equal(collect, network.INCOMING, incoming.Direction) + }, 3*time.Second, 100*time.Millisecond, "could not find connection incoming and outgoing connections") - m = incoming.Monotonic - assert.Equal(t, clientMessageSize, int(m.RecvBytes)) - assert.Equal(t, serverMessageSize, int(m.SentBytes)) - 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) } func (s *TracerSuite) TestPreexistingEmptyIncomingConnectionDirection() { t := s.T() + + // The ebpf tracer uses this to ensure it drops pre-existing connections + // that close empty (with no data), because they are difficult to track. + // However, in ebpfless they are easy to track, so disable this test. + // For more context, see PR #31100 + skipOnEbpflessNotSupported(t, testConfig()) + t.Run("ringbuf_enabled", func(t *testing.T) { if features.HaveMapType(ebpf.RingBuf) != nil { t.Skip("skipping test as ringbuffers are not supported on this kernel") } c := testConfig() - skipOnEbpflessNotSupported(t, c) c.NPMRingbuffersEnabled = true testPreexistingEmptyIncomingConnectionDirection(t, c) }) @@ -2415,7 +2434,7 @@ LOOP: require.NoError(t, c.Close(), "error closing client connection") require.EventuallyWithT(t, func(collect *assert.CollectT) { - conn, found := findConnection(c.LocalAddr(), srv.Addr(), getConnections(t, tr)) + conn, found := findConnection(c.LocalAddr(), srv.Addr(), getConnections(collect, tr)) require.True(collect, found, "could not find connection") require.True(collect, conn.IsClosed, "connection should be closed") // after closing the client connection, the duration should be diff --git a/pkg/network/tracer/tracer_test.go b/pkg/network/tracer/tracer_test.go index 710e5eb142253..d50f4f299690c 100644 --- a/pkg/network/tracer/tracer_test.go +++ b/pkg/network/tracer/tracer_test.go @@ -1130,6 +1130,7 @@ func (s *TracerSuite) TestTCPEstablishedPreExistingConn() { c, err := net.DialTimeout("tcp", server.Address(), 50*time.Millisecond) require.NoError(t, err) laddr, raddr := c.LocalAddr(), c.RemoteAddr() + t.Logf("laddr=%s raddr=%s", laddr, raddr) // Ensure closed connections are flushed as soon as possible cfg := testConfig() diff --git a/pkg/network/usm/ebpf_ssl.go b/pkg/network/usm/ebpf_ssl.go index 64e452ea7fe45..4a7800de41d4b 100644 --- a/pkg/network/usm/ebpf_ssl.go +++ b/pkg/network/usm/ebpf_ssl.go @@ -237,7 +237,8 @@ var gnuTLSProbes = []manager.ProbesSelector{ } const ( - sslSockByCtxMap = "ssl_sock_by_ctx" + sslSockByCtxMap = "ssl_sock_by_ctx" + sslCtxByPIDTGIDMap = "ssl_ctx_by_pid_tgid" ) var ( @@ -271,7 +272,7 @@ var opensslSpec = &protocols.ProtocolSpec{ Name: "fd_by_ssl_bio", }, { - Name: "ssl_ctx_by_pid_tgid", + Name: sslCtxByPIDTGIDMap, }, }, Probes: []*manager.Probe{ @@ -491,6 +492,10 @@ func (o *sslProgram) ConfigureOptions(_ *manager.Manager, options *manager.Optio MaxEntries: o.cfg.MaxTrackedConnections, EditorFlag: manager.EditMaxEntries, } + options.MapSpecEditors[sslCtxByPIDTGIDMap] = manager.MapSpecEditor{ + MaxEntries: o.cfg.MaxTrackedConnections, + EditorFlag: manager.EditMaxEntries, + } } // PreStart is called before the start of the provided eBPF manager. @@ -552,7 +557,7 @@ func (o *sslProgram) DumpMaps(w io.Writer, mapName string, currentMap *ebpf.Map) spew.Fdump(w, key, value) } - case "ssl_ctx_by_pid_tgid": // maps/ssl_ctx_by_pid_tgid (BPF_MAP_TYPE_HASH), key C.__u64, value uintptr // C.void * + case sslCtxByPIDTGIDMap: // maps/ssl_ctx_by_pid_tgid (BPF_MAP_TYPE_HASH), key C.__u64, value uintptr // C.void * io.WriteString(w, "Map: '"+mapName+"', key: 'C.__u64', value: 'uintptr // C.void *'\n") iter := currentMap.Iterate() var key uint64 diff --git a/pkg/obfuscate/go.mod b/pkg/obfuscate/go.mod index 7085b75f3783d..b34df591521b5 100644 --- a/pkg/obfuscate/go.mod +++ b/pkg/obfuscate/go.mod @@ -3,7 +3,7 @@ module github.com/DataDog/datadog-agent/pkg/obfuscate go 1.22.0 require ( - github.com/DataDog/datadog-go/v5 v5.5.0 + github.com/DataDog/datadog-go/v5 v5.6.0 github.com/DataDog/go-sqllexer v0.0.17 github.com/outcaste-io/ristretto v0.2.3 github.com/stretchr/testify v1.10.0 diff --git a/pkg/obfuscate/go.sum b/pkg/obfuscate/go.sum index e36a2867eaba6..063bd88a07005 100644 --- a/pkg/obfuscate/go.sum +++ b/pkg/obfuscate/go.sum @@ -1,5 +1,5 @@ -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/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= github.com/DataDog/go-sqllexer v0.0.17 h1:u47fJAVg/+5DA74ZW3w0Qu+3qXHd3GtnA8ZBYixdPrM= github.com/DataDog/go-sqllexer v0.0.17/go.mod h1:KwkYhpFEVIq+BfobkTC1vfqm4gTi65skV/DpDBXtexc= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= diff --git a/pkg/process/util/containers/containers.go b/pkg/process/util/containers/containers.go index 2beafeced27f5..c5ad7cae1c9b3 100644 --- a/pkg/process/util/containers/containers.go +++ b/pkg/process/util/containers/containers.go @@ -120,7 +120,7 @@ func (p *containerProvider) GetContainers(cacheValidity time.Duration, previousC annotations = pod.Annotations } - if p.filter != nil && p.filter.IsExcluded(annotations, container.Name, container.Image.Name, container.Labels[kubernetes.CriContainerNamespaceLabel]) { + if p.filter != nil && p.filter.IsExcluded(annotations, container.Name, container.Image.RawName, container.Labels[kubernetes.CriContainerNamespaceLabel]) { continue } @@ -209,7 +209,7 @@ func (p *containerProvider) GetPidToCid(cacheValidity time.Duration) map[int]str annotations = pod.Annotations } - if p.filter != nil && p.filter.IsExcluded(annotations, container.Name, container.Image.Name, container.Labels[kubernetes.CriContainerNamespaceLabel]) { + if p.filter != nil && p.filter.IsExcluded(annotations, container.Name, container.Image.RawName, container.Labels[kubernetes.CriContainerNamespaceLabel]) { continue } diff --git a/pkg/proto/datadog/api/v1/api.proto b/pkg/proto/datadog/api/v1/api.proto index 1ffbfa02aa562..3e53e3aa7c773 100644 --- a/pkg/proto/datadog/api/v1/api.proto +++ b/pkg/proto/datadog/api/v1/api.proto @@ -51,6 +51,22 @@ service AgentSecure { }; }; + // Generates a container ID from Origin Info. + // can be called through the HTTP gateway, and entity will be returned as JSON: + // $ curl -H "authorization: Bearer $(cat /etc/datadog-agent/auth_token)" \ + // -XPOST -k -H "Content-Type: application/json" \ + // --data '{"externalDataInit": false,"externalDataPodUID": "54383382-cea3-49e3-9dda-325436ddd5b8","externalDataContainerName": "dd-trace-py"}' \ + // https://localhost:5001/v1/grpc/tagger/generate_container_id_from_origin_info + // { + // "containerID":"c9fd60251b5237467462dad48999815eb0025f367c6e1abe91e0bd787d5915fc" + // } + rpc TaggerGenerateContainerIDFromOriginInfo(datadog.model.v1.GenerateContainerIDFromOriginInfoRequest) returns (datadog.model.v1.GenerateContainerIDFromOriginInfoResponse) { + option (google.api.http) = { + post: "/v1/grpc/tagger/generate_container_id_from_origin_info" + body: "*" + }; + }; + // fetches an entity from the Tagger with the desired cardinality tags. // can be called through the HTTP gateway, and entity will be returned as JSON: // $ curl -H "authorization: Bearer $(cat /etc/datadog-agent/auth_token)" \ diff --git a/pkg/proto/datadog/model/v1/model.proto b/pkg/proto/datadog/model/v1/model.proto index 506f90fa95702..2d4f96d208483 100644 --- a/pkg/proto/datadog/model/v1/model.proto +++ b/pkg/proto/datadog/model/v1/model.proto @@ -73,6 +73,30 @@ message Entity { repeated string standardTags = 6; } +message GenerateContainerIDFromOriginInfoRequest { + // Nested message for the local data + message LocalData { + optional uint32 processID = 1; // Process ID of the container process on the host. + optional string containerID = 2; // Container ID send from the client. + optional uint64 inode = 3; // Cgroup inode of the container. + optional string podUID = 4; // Pod UID send from the client. + } + + // Nested message for the external data + message ExternalData { + optional bool init = 1; // Init is true if the container is an init container. + optional string containerName = 2; // Container name in the Kubernetes Pod spec. + optional string podUID = 3; // Pod UID in the Kubernetes Pod spec. + } + + optional LocalData localData = 1; // Local data for the container, generated by the client. + optional ExternalData externalData = 2; // External data for the container, generated by the Admission Controller. +} + +message GenerateContainerIDFromOriginInfoResponse { + string containerID = 1; +} + message FetchEntityRequest { EntityId id = 1; TagCardinality cardinality = 2; diff --git a/pkg/proto/pbgo/core/api.pb.go b/pkg/proto/pbgo/core/api.pb.go index 57de2030c617e..f99b9d0f48fbf 100644 --- a/pkg/proto/pbgo/core/api.pb.go +++ b/pkg/proto/pbgo/core/api.pb.go @@ -53,7 +53,7 @@ var file_datadog_api_v1_api_proto_rawDesc = []byte{ 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x76, 0x31, - 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x32, 0x80, 0x0d, 0x0a, 0x0b, 0x41, + 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x32, 0xe8, 0x0e, 0x0a, 0x0b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x8f, 0x01, 0x0a, 0x14, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, @@ -63,176 +63,194 @@ var file_datadog_api_v1_api_proto_rawDesc = []byte{ 0x61, 0x6d, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x30, 0x01, 0x12, 0x89, 0x01, 0x0a, - 0x11, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x12, 0x24, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, - 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, - 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x74, 0x63, - 0x68, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x22, 0x1c, 0x2f, 0x76, 0x31, 0x2f, - 0x67, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2f, 0x66, 0x65, 0x74, 0x63, - 0x68, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x9b, 0x01, 0x0a, 0x17, 0x44, 0x6f, 0x67, - 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x54, 0x72, 0x69, - 0x67, 0x67, 0x65, 0x72, 0x12, 0x27, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, - 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x54, - 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, - 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, - 0x01, 0x2a, 0x22, 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x6f, 0x67, - 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x2f, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x2f, 0x74, - 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x8c, 0x01, 0x0a, 0x17, 0x44, 0x6f, 0x67, 0x73, 0x74, - 0x61, 0x74, 0x73, 0x64, 0x53, 0x65, 0x74, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, - 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x1a, 0x25, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, - 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, - 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x6f, - 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x2f, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x8f, 0x01, 0x0a, 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x27, 0x2e, 0x64, 0x61, 0x74, - 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, - 0x70, 0x63, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x78, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x26, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x72, - 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x94, 0x01, 0x0a, 0x12, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x48, 0x41, 0x12, 0x27, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, - 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x28, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, - 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x73, 0x5f, 0x68, 0x61, 0x12, 0x7d, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x41, 0x12, 0x16, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x23, 0x3a, 0x01, 0x2a, 0x22, 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, - 0x63, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x68, 0x61, 0x12, 0xb3, 0x01, 0x0a, 0x1a, 0x57, 0x6f, 0x72, 0x6b, - 0x6c, 0x6f, 0x61, 0x64, 0x6d, 0x65, 0x74, 0x61, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x6e, - 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, - 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x6d, 0x65, 0x74, 0x61, 0x2e, 0x57, 0x6f, - 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x6d, 0x65, 0x74, 0x61, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, - 0x67, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x6d, 0x65, 0x74, 0x61, 0x2e, 0x57, - 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x6d, 0x65, 0x74, 0x61, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x77, - 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x6d, 0x65, 0x74, 0x61, 0x2f, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x30, 0x01, 0x12, 0xaf, 0x01, - 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, - 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, - 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, - 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x12, - 0x9b, 0x01, 0x0a, 0x19, 0x41, 0x75, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x32, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, - 0x61, 0x75, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2e, 0x41, 0x75, - 0x74, 0x6f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x61, - 0x75, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x30, 0x01, 0x32, 0xe6, 0x01, - 0x0a, 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x6f, 0x0a, - 0x10, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x73, 0x12, 0x2c, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x72, 0x65, 0x6d, 0x6f, - 0x74, 0x65, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2d, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x44, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, - 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x61, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, - 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x61, 0x72, 0x65, 0x46, 0x69, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x64, 0x61, 0x74, - 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x61, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x15, 0x5a, 0x13, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x67, 0x6f, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x30, 0x01, 0x12, 0xe5, 0x01, 0x0a, + 0x27, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x46, 0x72, 0x6f, 0x6d, 0x4f, 0x72, + 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3a, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, + 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x46, + 0x72, 0x6f, 0x6d, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x46, 0x72, 0x6f, 0x6d, 0x4f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x41, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3b, 0x3a, 0x01, 0x2a, 0x22, 0x36, 0x2f, 0x76, + 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2f, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, + 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x89, 0x01, 0x0a, 0x11, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x46, + 0x65, 0x74, 0x63, 0x68, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x24, 0x2e, 0x64, 0x61, 0x74, + 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, + 0x74, 0x63, 0x68, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x25, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, + 0x01, 0x2a, 0x22, 0x1c, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x61, 0x67, + 0x67, 0x65, 0x72, 0x2f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x12, 0x9b, 0x01, 0x0a, 0x17, 0x44, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x43, 0x61, + 0x70, 0x74, 0x75, 0x72, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x27, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, + 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x22, 0x22, 0x2f, 0x76, 0x31, 0x2f, + 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x2f, 0x63, + 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x8c, + 0x01, 0x0a, 0x17, 0x44, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x53, 0x65, 0x74, 0x54, + 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x64, 0x61, 0x74, + 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, + 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x25, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, + 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, 0x2f, 0x76, 0x31, + 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x2f, + 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x8f, 0x01, + 0x0a, 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x73, 0x12, 0x27, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x64, 0x61, + 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, 0x2a, + 0x22, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, + 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, + 0x78, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x64, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, + 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x94, 0x01, 0x0a, 0x12, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x48, 0x41, + 0x12, 0x27, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x64, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x01, 0x2a, 0x22, 0x20, + 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x5f, 0x68, 0x61, + 0x12, 0x7d, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x48, 0x41, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x3a, 0x01, 0x2a, 0x22, + 0x1e, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x68, 0x61, 0x12, + 0xb3, 0x01, 0x0a, 0x1a, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x6d, 0x65, 0x74, 0x61, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2f, + 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x6d, 0x65, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x6d, 0x65, + 0x74, 0x61, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x30, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x6d, 0x65, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x6d, + 0x65, 0x74, 0x61, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, + 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x6d, + 0x65, 0x74, 0x61, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x30, 0x01, 0x12, 0xaf, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x2e, + 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, + 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x76, 0x31, + 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x74, + 0x65, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x9b, 0x01, 0x0a, 0x19, 0x41, 0x75, 0x74, 0x6f, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x32, 0x2e, + 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, + 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x64, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x79, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x73, 0x30, 0x01, 0x32, 0xe6, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x6f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x2c, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x64, 0x6f, 0x67, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, + 0x67, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x61, + 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, + 0x67, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, + 0x74, 0x46, 0x6c, 0x61, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x72, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x61, 0x72, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x15, + 0x5a, 0x13, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x67, 0x6f, + 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_datadog_api_v1_api_proto_goTypes = []any{ - (*HostnameRequest)(nil), // 0: datadog.model.v1.HostnameRequest - (*StreamTagsRequest)(nil), // 1: datadog.model.v1.StreamTagsRequest - (*FetchEntityRequest)(nil), // 2: datadog.model.v1.FetchEntityRequest - (*CaptureTriggerRequest)(nil), // 3: datadog.model.v1.CaptureTriggerRequest - (*TaggerState)(nil), // 4: datadog.model.v1.TaggerState - (*ClientGetConfigsRequest)(nil), // 5: datadog.config.ClientGetConfigsRequest - (*empty.Empty)(nil), // 6: google.protobuf.Empty - (*WorkloadmetaStreamRequest)(nil), // 7: datadog.workloadmeta.WorkloadmetaStreamRequest - (*RegisterRemoteAgentRequest)(nil), // 8: datadog.remoteagent.RegisterRemoteAgentRequest - (*GetStatusDetailsRequest)(nil), // 9: datadog.remoteagent.GetStatusDetailsRequest - (*GetFlareFilesRequest)(nil), // 10: datadog.remoteagent.GetFlareFilesRequest - (*HostnameReply)(nil), // 11: datadog.model.v1.HostnameReply - (*StreamTagsResponse)(nil), // 12: datadog.model.v1.StreamTagsResponse - (*FetchEntityResponse)(nil), // 13: datadog.model.v1.FetchEntityResponse - (*CaptureTriggerResponse)(nil), // 14: datadog.model.v1.CaptureTriggerResponse - (*TaggerStateResponse)(nil), // 15: datadog.model.v1.TaggerStateResponse - (*ClientGetConfigsResponse)(nil), // 16: datadog.config.ClientGetConfigsResponse - (*GetStateConfigResponse)(nil), // 17: datadog.config.GetStateConfigResponse - (*WorkloadmetaStreamResponse)(nil), // 18: datadog.workloadmeta.WorkloadmetaStreamResponse - (*RegisterRemoteAgentResponse)(nil), // 19: datadog.remoteagent.RegisterRemoteAgentResponse - (*AutodiscoveryStreamResponse)(nil), // 20: datadog.autodiscovery.AutodiscoveryStreamResponse - (*GetStatusDetailsResponse)(nil), // 21: datadog.remoteagent.GetStatusDetailsResponse - (*GetFlareFilesResponse)(nil), // 22: datadog.remoteagent.GetFlareFilesResponse + (*HostnameRequest)(nil), // 0: datadog.model.v1.HostnameRequest + (*StreamTagsRequest)(nil), // 1: datadog.model.v1.StreamTagsRequest + (*GenerateContainerIDFromOriginInfoRequest)(nil), // 2: datadog.model.v1.GenerateContainerIDFromOriginInfoRequest + (*FetchEntityRequest)(nil), // 3: datadog.model.v1.FetchEntityRequest + (*CaptureTriggerRequest)(nil), // 4: datadog.model.v1.CaptureTriggerRequest + (*TaggerState)(nil), // 5: datadog.model.v1.TaggerState + (*ClientGetConfigsRequest)(nil), // 6: datadog.config.ClientGetConfigsRequest + (*empty.Empty)(nil), // 7: google.protobuf.Empty + (*WorkloadmetaStreamRequest)(nil), // 8: datadog.workloadmeta.WorkloadmetaStreamRequest + (*RegisterRemoteAgentRequest)(nil), // 9: datadog.remoteagent.RegisterRemoteAgentRequest + (*GetStatusDetailsRequest)(nil), // 10: datadog.remoteagent.GetStatusDetailsRequest + (*GetFlareFilesRequest)(nil), // 11: datadog.remoteagent.GetFlareFilesRequest + (*HostnameReply)(nil), // 12: datadog.model.v1.HostnameReply + (*StreamTagsResponse)(nil), // 13: datadog.model.v1.StreamTagsResponse + (*GenerateContainerIDFromOriginInfoResponse)(nil), // 14: datadog.model.v1.GenerateContainerIDFromOriginInfoResponse + (*FetchEntityResponse)(nil), // 15: datadog.model.v1.FetchEntityResponse + (*CaptureTriggerResponse)(nil), // 16: datadog.model.v1.CaptureTriggerResponse + (*TaggerStateResponse)(nil), // 17: datadog.model.v1.TaggerStateResponse + (*ClientGetConfigsResponse)(nil), // 18: datadog.config.ClientGetConfigsResponse + (*GetStateConfigResponse)(nil), // 19: datadog.config.GetStateConfigResponse + (*WorkloadmetaStreamResponse)(nil), // 20: datadog.workloadmeta.WorkloadmetaStreamResponse + (*RegisterRemoteAgentResponse)(nil), // 21: datadog.remoteagent.RegisterRemoteAgentResponse + (*AutodiscoveryStreamResponse)(nil), // 22: datadog.autodiscovery.AutodiscoveryStreamResponse + (*GetStatusDetailsResponse)(nil), // 23: datadog.remoteagent.GetStatusDetailsResponse + (*GetFlareFilesResponse)(nil), // 24: datadog.remoteagent.GetFlareFilesResponse } var file_datadog_api_v1_api_proto_depIdxs = []int32{ 0, // 0: datadog.api.v1.Agent.GetHostname:input_type -> datadog.model.v1.HostnameRequest 1, // 1: datadog.api.v1.AgentSecure.TaggerStreamEntities:input_type -> datadog.model.v1.StreamTagsRequest - 2, // 2: datadog.api.v1.AgentSecure.TaggerFetchEntity:input_type -> datadog.model.v1.FetchEntityRequest - 3, // 3: datadog.api.v1.AgentSecure.DogstatsdCaptureTrigger:input_type -> datadog.model.v1.CaptureTriggerRequest - 4, // 4: datadog.api.v1.AgentSecure.DogstatsdSetTaggerState:input_type -> datadog.model.v1.TaggerState - 5, // 5: datadog.api.v1.AgentSecure.ClientGetConfigs:input_type -> datadog.config.ClientGetConfigsRequest - 6, // 6: datadog.api.v1.AgentSecure.GetConfigState:input_type -> google.protobuf.Empty - 5, // 7: datadog.api.v1.AgentSecure.ClientGetConfigsHA:input_type -> datadog.config.ClientGetConfigsRequest - 6, // 8: datadog.api.v1.AgentSecure.GetConfigStateHA:input_type -> google.protobuf.Empty - 7, // 9: datadog.api.v1.AgentSecure.WorkloadmetaStreamEntities:input_type -> datadog.workloadmeta.WorkloadmetaStreamRequest - 8, // 10: datadog.api.v1.AgentSecure.RegisterRemoteAgent:input_type -> datadog.remoteagent.RegisterRemoteAgentRequest - 6, // 11: datadog.api.v1.AgentSecure.AutodiscoveryStreamConfig:input_type -> google.protobuf.Empty - 9, // 12: datadog.api.v1.RemoteAgent.GetStatusDetails:input_type -> datadog.remoteagent.GetStatusDetailsRequest - 10, // 13: datadog.api.v1.RemoteAgent.GetFlareFiles:input_type -> datadog.remoteagent.GetFlareFilesRequest - 11, // 14: datadog.api.v1.Agent.GetHostname:output_type -> datadog.model.v1.HostnameReply - 12, // 15: datadog.api.v1.AgentSecure.TaggerStreamEntities:output_type -> datadog.model.v1.StreamTagsResponse - 13, // 16: datadog.api.v1.AgentSecure.TaggerFetchEntity:output_type -> datadog.model.v1.FetchEntityResponse - 14, // 17: datadog.api.v1.AgentSecure.DogstatsdCaptureTrigger:output_type -> datadog.model.v1.CaptureTriggerResponse - 15, // 18: datadog.api.v1.AgentSecure.DogstatsdSetTaggerState:output_type -> datadog.model.v1.TaggerStateResponse - 16, // 19: datadog.api.v1.AgentSecure.ClientGetConfigs:output_type -> datadog.config.ClientGetConfigsResponse - 17, // 20: datadog.api.v1.AgentSecure.GetConfigState:output_type -> datadog.config.GetStateConfigResponse - 16, // 21: datadog.api.v1.AgentSecure.ClientGetConfigsHA:output_type -> datadog.config.ClientGetConfigsResponse - 17, // 22: datadog.api.v1.AgentSecure.GetConfigStateHA:output_type -> datadog.config.GetStateConfigResponse - 18, // 23: datadog.api.v1.AgentSecure.WorkloadmetaStreamEntities:output_type -> datadog.workloadmeta.WorkloadmetaStreamResponse - 19, // 24: datadog.api.v1.AgentSecure.RegisterRemoteAgent:output_type -> datadog.remoteagent.RegisterRemoteAgentResponse - 20, // 25: datadog.api.v1.AgentSecure.AutodiscoveryStreamConfig:output_type -> datadog.autodiscovery.AutodiscoveryStreamResponse - 21, // 26: datadog.api.v1.RemoteAgent.GetStatusDetails:output_type -> datadog.remoteagent.GetStatusDetailsResponse - 22, // 27: datadog.api.v1.RemoteAgent.GetFlareFiles:output_type -> datadog.remoteagent.GetFlareFilesResponse - 14, // [14:28] is the sub-list for method output_type - 0, // [0:14] is the sub-list for method input_type + 2, // 2: datadog.api.v1.AgentSecure.TaggerGenerateContainerIDFromOriginInfo:input_type -> datadog.model.v1.GenerateContainerIDFromOriginInfoRequest + 3, // 3: datadog.api.v1.AgentSecure.TaggerFetchEntity:input_type -> datadog.model.v1.FetchEntityRequest + 4, // 4: datadog.api.v1.AgentSecure.DogstatsdCaptureTrigger:input_type -> datadog.model.v1.CaptureTriggerRequest + 5, // 5: datadog.api.v1.AgentSecure.DogstatsdSetTaggerState:input_type -> datadog.model.v1.TaggerState + 6, // 6: datadog.api.v1.AgentSecure.ClientGetConfigs:input_type -> datadog.config.ClientGetConfigsRequest + 7, // 7: datadog.api.v1.AgentSecure.GetConfigState:input_type -> google.protobuf.Empty + 6, // 8: datadog.api.v1.AgentSecure.ClientGetConfigsHA:input_type -> datadog.config.ClientGetConfigsRequest + 7, // 9: datadog.api.v1.AgentSecure.GetConfigStateHA:input_type -> google.protobuf.Empty + 8, // 10: datadog.api.v1.AgentSecure.WorkloadmetaStreamEntities:input_type -> datadog.workloadmeta.WorkloadmetaStreamRequest + 9, // 11: datadog.api.v1.AgentSecure.RegisterRemoteAgent:input_type -> datadog.remoteagent.RegisterRemoteAgentRequest + 7, // 12: datadog.api.v1.AgentSecure.AutodiscoveryStreamConfig:input_type -> google.protobuf.Empty + 10, // 13: datadog.api.v1.RemoteAgent.GetStatusDetails:input_type -> datadog.remoteagent.GetStatusDetailsRequest + 11, // 14: datadog.api.v1.RemoteAgent.GetFlareFiles:input_type -> datadog.remoteagent.GetFlareFilesRequest + 12, // 15: datadog.api.v1.Agent.GetHostname:output_type -> datadog.model.v1.HostnameReply + 13, // 16: datadog.api.v1.AgentSecure.TaggerStreamEntities:output_type -> datadog.model.v1.StreamTagsResponse + 14, // 17: datadog.api.v1.AgentSecure.TaggerGenerateContainerIDFromOriginInfo:output_type -> datadog.model.v1.GenerateContainerIDFromOriginInfoResponse + 15, // 18: datadog.api.v1.AgentSecure.TaggerFetchEntity:output_type -> datadog.model.v1.FetchEntityResponse + 16, // 19: datadog.api.v1.AgentSecure.DogstatsdCaptureTrigger:output_type -> datadog.model.v1.CaptureTriggerResponse + 17, // 20: datadog.api.v1.AgentSecure.DogstatsdSetTaggerState:output_type -> datadog.model.v1.TaggerStateResponse + 18, // 21: datadog.api.v1.AgentSecure.ClientGetConfigs:output_type -> datadog.config.ClientGetConfigsResponse + 19, // 22: datadog.api.v1.AgentSecure.GetConfigState:output_type -> datadog.config.GetStateConfigResponse + 18, // 23: datadog.api.v1.AgentSecure.ClientGetConfigsHA:output_type -> datadog.config.ClientGetConfigsResponse + 19, // 24: datadog.api.v1.AgentSecure.GetConfigStateHA:output_type -> datadog.config.GetStateConfigResponse + 20, // 25: datadog.api.v1.AgentSecure.WorkloadmetaStreamEntities:output_type -> datadog.workloadmeta.WorkloadmetaStreamResponse + 21, // 26: datadog.api.v1.AgentSecure.RegisterRemoteAgent:output_type -> datadog.remoteagent.RegisterRemoteAgentResponse + 22, // 27: datadog.api.v1.AgentSecure.AutodiscoveryStreamConfig:output_type -> datadog.autodiscovery.AutodiscoveryStreamResponse + 23, // 28: datadog.api.v1.RemoteAgent.GetStatusDetails:output_type -> datadog.remoteagent.GetStatusDetailsResponse + 24, // 29: datadog.api.v1.RemoteAgent.GetFlareFiles:output_type -> datadog.remoteagent.GetFlareFilesResponse + 15, // [15:30] is the sub-list for method output_type + 0, // [0:15] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name @@ -375,6 +393,17 @@ type AgentSecureClient interface { // } // } TaggerStreamEntities(ctx context.Context, in *StreamTagsRequest, opts ...grpc.CallOption) (AgentSecure_TaggerStreamEntitiesClient, error) + // Generates a container ID from Origin Info. + // can be called through the HTTP gateway, and entity will be returned as JSON: + // + // $ curl -H "authorization: Bearer $(cat /etc/datadog-agent/auth_token)" \ + // -XPOST -k -H "Content-Type: application/json" \ + // --data '{"externalDataInit": false,"externalDataPodUID": "54383382-cea3-49e3-9dda-325436ddd5b8","externalDataContainerName": "dd-trace-py"}' \ + // https://localhost:5001/v1/grpc/tagger/generate_container_id_from_origin_info + // { + // "containerID":"c9fd60251b5237467462dad48999815eb0025f367c6e1abe91e0bd787d5915fc" + // } + TaggerGenerateContainerIDFromOriginInfo(ctx context.Context, in *GenerateContainerIDFromOriginInfoRequest, opts ...grpc.CallOption) (*GenerateContainerIDFromOriginInfoResponse, error) // fetches an entity from the Tagger with the desired cardinality tags. // can be called through the HTTP gateway, and entity will be returned as JSON: // @@ -477,6 +506,15 @@ func (x *agentSecureTaggerStreamEntitiesClient) Recv() (*StreamTagsResponse, err return m, nil } +func (c *agentSecureClient) TaggerGenerateContainerIDFromOriginInfo(ctx context.Context, in *GenerateContainerIDFromOriginInfoRequest, opts ...grpc.CallOption) (*GenerateContainerIDFromOriginInfoResponse, error) { + out := new(GenerateContainerIDFromOriginInfoResponse) + err := c.cc.Invoke(ctx, "/datadog.api.v1.AgentSecure/TaggerGenerateContainerIDFromOriginInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *agentSecureClient) TaggerFetchEntity(ctx context.Context, in *FetchEntityRequest, opts ...grpc.CallOption) (*FetchEntityResponse, error) { out := new(FetchEntityResponse) err := c.cc.Invoke(ctx, "/datadog.api.v1.AgentSecure/TaggerFetchEntity", in, out, opts...) @@ -637,6 +675,17 @@ type AgentSecureServer interface { // } // } TaggerStreamEntities(*StreamTagsRequest, AgentSecure_TaggerStreamEntitiesServer) error + // Generates a container ID from Origin Info. + // can be called through the HTTP gateway, and entity will be returned as JSON: + // + // $ curl -H "authorization: Bearer $(cat /etc/datadog-agent/auth_token)" \ + // -XPOST -k -H "Content-Type: application/json" \ + // --data '{"externalDataInit": false,"externalDataPodUID": "54383382-cea3-49e3-9dda-325436ddd5b8","externalDataContainerName": "dd-trace-py"}' \ + // https://localhost:5001/v1/grpc/tagger/generate_container_id_from_origin_info + // { + // "containerID":"c9fd60251b5237467462dad48999815eb0025f367c6e1abe91e0bd787d5915fc" + // } + TaggerGenerateContainerIDFromOriginInfo(context.Context, *GenerateContainerIDFromOriginInfoRequest) (*GenerateContainerIDFromOriginInfoResponse, error) // fetches an entity from the Tagger with the desired cardinality tags. // can be called through the HTTP gateway, and entity will be returned as JSON: // @@ -706,6 +755,9 @@ type UnimplementedAgentSecureServer struct { func (*UnimplementedAgentSecureServer) TaggerStreamEntities(*StreamTagsRequest, AgentSecure_TaggerStreamEntitiesServer) error { return status.Errorf(codes.Unimplemented, "method TaggerStreamEntities not implemented") } +func (*UnimplementedAgentSecureServer) TaggerGenerateContainerIDFromOriginInfo(context.Context, *GenerateContainerIDFromOriginInfoRequest) (*GenerateContainerIDFromOriginInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TaggerGenerateContainerIDFromOriginInfo not implemented") +} func (*UnimplementedAgentSecureServer) TaggerFetchEntity(context.Context, *FetchEntityRequest) (*FetchEntityResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method TaggerFetchEntity not implemented") } @@ -762,6 +814,24 @@ func (x *agentSecureTaggerStreamEntitiesServer) Send(m *StreamTagsResponse) erro return x.ServerStream.SendMsg(m) } +func _AgentSecure_TaggerGenerateContainerIDFromOriginInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GenerateContainerIDFromOriginInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentSecureServer).TaggerGenerateContainerIDFromOriginInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/datadog.api.v1.AgentSecure/TaggerGenerateContainerIDFromOriginInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentSecureServer).TaggerGenerateContainerIDFromOriginInfo(ctx, req.(*GenerateContainerIDFromOriginInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _AgentSecure_TaggerFetchEntity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(FetchEntityRequest) if err := dec(in); err != nil { @@ -952,6 +1022,10 @@ var _AgentSecure_serviceDesc = grpc.ServiceDesc{ ServiceName: "datadog.api.v1.AgentSecure", HandlerType: (*AgentSecureServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "TaggerGenerateContainerIDFromOriginInfo", + Handler: _AgentSecure_TaggerGenerateContainerIDFromOriginInfo_Handler, + }, { MethodName: "TaggerFetchEntity", Handler: _AgentSecure_TaggerFetchEntity_Handler, diff --git a/pkg/proto/pbgo/core/api.pb.gw.go b/pkg/proto/pbgo/core/api.pb.gw.go index 0fac62a1daa72..7be078c4eb534 100644 --- a/pkg/proto/pbgo/core/api.pb.gw.go +++ b/pkg/proto/pbgo/core/api.pb.gw.go @@ -77,6 +77,40 @@ func request_AgentSecure_TaggerStreamEntities_0(ctx context.Context, marshaler r } +func request_AgentSecure_TaggerGenerateContainerIDFromOriginInfo_0(ctx context.Context, marshaler runtime.Marshaler, client AgentSecureClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GenerateContainerIDFromOriginInfoRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.TaggerGenerateContainerIDFromOriginInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AgentSecure_TaggerGenerateContainerIDFromOriginInfo_0(ctx context.Context, marshaler runtime.Marshaler, server AgentSecureServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GenerateContainerIDFromOriginInfoRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.TaggerGenerateContainerIDFromOriginInfo(ctx, &protoReq) + return msg, metadata, err + +} + func request_AgentSecure_TaggerFetchEntity_0(ctx context.Context, marshaler runtime.Marshaler, client AgentSecureClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq FetchEntityRequest var metadata runtime.ServerMetadata @@ -444,6 +478,29 @@ func RegisterAgentSecureHandlerServer(ctx context.Context, mux *runtime.ServeMux return }) + mux.Handle("POST", pattern_AgentSecure_TaggerGenerateContainerIDFromOriginInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AgentSecure_TaggerGenerateContainerIDFromOriginInfo_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_AgentSecure_TaggerGenerateContainerIDFromOriginInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_AgentSecure_TaggerFetchEntity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -772,6 +829,26 @@ func RegisterAgentSecureHandlerClient(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("POST", pattern_AgentSecure_TaggerGenerateContainerIDFromOriginInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AgentSecure_TaggerGenerateContainerIDFromOriginInfo_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_AgentSecure_TaggerGenerateContainerIDFromOriginInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_AgentSecure_TaggerFetchEntity_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -978,6 +1055,8 @@ func RegisterAgentSecureHandlerClient(ctx context.Context, mux *runtime.ServeMux var ( pattern_AgentSecure_TaggerStreamEntities_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "grpc", "tagger", "stream_entities"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_AgentSecure_TaggerGenerateContainerIDFromOriginInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "grpc", "tagger", "generate_container_id_from_origin_info"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_AgentSecure_TaggerFetchEntity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v1", "grpc", "tagger", "fetch_entity"}, "", runtime.AssumeColonVerbOpt(true))) pattern_AgentSecure_DogstatsdCaptureTrigger_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v1", "grpc", "dogstatsd", "capture", "trigger"}, "", runtime.AssumeColonVerbOpt(true))) @@ -1002,6 +1081,8 @@ var ( var ( forward_AgentSecure_TaggerStreamEntities_0 = runtime.ForwardResponseStream + forward_AgentSecure_TaggerGenerateContainerIDFromOriginInfo_0 = runtime.ForwardResponseMessage + forward_AgentSecure_TaggerFetchEntity_0 = runtime.ForwardResponseMessage forward_AgentSecure_DogstatsdCaptureTrigger_0 = runtime.ForwardResponseMessage diff --git a/pkg/proto/pbgo/core/model.pb.go b/pkg/proto/pbgo/core/model.pb.go index 3f85da4236b7f..016a2cf53e260 100644 --- a/pkg/proto/pbgo/core/model.pb.go +++ b/pkg/proto/pbgo/core/model.pb.go @@ -628,6 +628,104 @@ func (x *Entity) GetStandardTags() []string { return nil } +type GenerateContainerIDFromOriginInfoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LocalData *GenerateContainerIDFromOriginInfoRequest_LocalData `protobuf:"bytes,1,opt,name=localData,proto3,oneof" json:"localData,omitempty"` // Local data for the container, generated by the client. + ExternalData *GenerateContainerIDFromOriginInfoRequest_ExternalData `protobuf:"bytes,2,opt,name=externalData,proto3,oneof" json:"externalData,omitempty"` // External data for the container, generated by the Admission Controller. +} + +func (x *GenerateContainerIDFromOriginInfoRequest) Reset() { + *x = GenerateContainerIDFromOriginInfoRequest{} + mi := &file_datadog_model_v1_model_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GenerateContainerIDFromOriginInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateContainerIDFromOriginInfoRequest) ProtoMessage() {} + +func (x *GenerateContainerIDFromOriginInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_datadog_model_v1_model_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GenerateContainerIDFromOriginInfoRequest.ProtoReflect.Descriptor instead. +func (*GenerateContainerIDFromOriginInfoRequest) Descriptor() ([]byte, []int) { + return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{9} +} + +func (x *GenerateContainerIDFromOriginInfoRequest) GetLocalData() *GenerateContainerIDFromOriginInfoRequest_LocalData { + if x != nil { + return x.LocalData + } + return nil +} + +func (x *GenerateContainerIDFromOriginInfoRequest) GetExternalData() *GenerateContainerIDFromOriginInfoRequest_ExternalData { + if x != nil { + return x.ExternalData + } + return nil +} + +type GenerateContainerIDFromOriginInfoResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContainerID string `protobuf:"bytes,1,opt,name=containerID,proto3" json:"containerID,omitempty"` +} + +func (x *GenerateContainerIDFromOriginInfoResponse) Reset() { + *x = GenerateContainerIDFromOriginInfoResponse{} + mi := &file_datadog_model_v1_model_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GenerateContainerIDFromOriginInfoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateContainerIDFromOriginInfoResponse) ProtoMessage() {} + +func (x *GenerateContainerIDFromOriginInfoResponse) ProtoReflect() protoreflect.Message { + mi := &file_datadog_model_v1_model_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GenerateContainerIDFromOriginInfoResponse.ProtoReflect.Descriptor instead. +func (*GenerateContainerIDFromOriginInfoResponse) Descriptor() ([]byte, []int) { + return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{10} +} + +func (x *GenerateContainerIDFromOriginInfoResponse) GetContainerID() string { + if x != nil { + return x.ContainerID + } + return "" +} + type FetchEntityRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -639,7 +737,7 @@ type FetchEntityRequest struct { func (x *FetchEntityRequest) Reset() { *x = FetchEntityRequest{} - mi := &file_datadog_model_v1_model_proto_msgTypes[9] + mi := &file_datadog_model_v1_model_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -651,7 +749,7 @@ func (x *FetchEntityRequest) String() string { func (*FetchEntityRequest) ProtoMessage() {} func (x *FetchEntityRequest) ProtoReflect() protoreflect.Message { - mi := &file_datadog_model_v1_model_proto_msgTypes[9] + mi := &file_datadog_model_v1_model_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -664,7 +762,7 @@ func (x *FetchEntityRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchEntityRequest.ProtoReflect.Descriptor instead. func (*FetchEntityRequest) Descriptor() ([]byte, []int) { - return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{9} + return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{11} } func (x *FetchEntityRequest) GetId() *EntityId { @@ -693,7 +791,7 @@ type FetchEntityResponse struct { func (x *FetchEntityResponse) Reset() { *x = FetchEntityResponse{} - mi := &file_datadog_model_v1_model_proto_msgTypes[10] + mi := &file_datadog_model_v1_model_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -705,7 +803,7 @@ func (x *FetchEntityResponse) String() string { func (*FetchEntityResponse) ProtoMessage() {} func (x *FetchEntityResponse) ProtoReflect() protoreflect.Message { - mi := &file_datadog_model_v1_model_proto_msgTypes[10] + mi := &file_datadog_model_v1_model_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -718,7 +816,7 @@ func (x *FetchEntityResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchEntityResponse.ProtoReflect.Descriptor instead. func (*FetchEntityResponse) Descriptor() ([]byte, []int) { - return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{10} + return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{12} } func (x *FetchEntityResponse) GetId() *EntityId { @@ -753,7 +851,7 @@ type EntityId struct { func (x *EntityId) Reset() { *x = EntityId{} - mi := &file_datadog_model_v1_model_proto_msgTypes[11] + mi := &file_datadog_model_v1_model_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -765,7 +863,7 @@ func (x *EntityId) String() string { func (*EntityId) ProtoMessage() {} func (x *EntityId) ProtoReflect() protoreflect.Message { - mi := &file_datadog_model_v1_model_proto_msgTypes[11] + mi := &file_datadog_model_v1_model_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -778,7 +876,7 @@ func (x *EntityId) ProtoReflect() protoreflect.Message { // Deprecated: Use EntityId.ProtoReflect.Descriptor instead. func (*EntityId) Descriptor() ([]byte, []int) { - return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{11} + return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{13} } func (x *EntityId) GetPrefix() string { @@ -812,7 +910,7 @@ type UnixDogstatsdMsg struct { func (x *UnixDogstatsdMsg) Reset() { *x = UnixDogstatsdMsg{} - mi := &file_datadog_model_v1_model_proto_msgTypes[12] + mi := &file_datadog_model_v1_model_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -824,7 +922,7 @@ func (x *UnixDogstatsdMsg) String() string { func (*UnixDogstatsdMsg) ProtoMessage() {} func (x *UnixDogstatsdMsg) ProtoReflect() protoreflect.Message { - mi := &file_datadog_model_v1_model_proto_msgTypes[12] + mi := &file_datadog_model_v1_model_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -837,7 +935,7 @@ func (x *UnixDogstatsdMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use UnixDogstatsdMsg.ProtoReflect.Descriptor instead. func (*UnixDogstatsdMsg) Descriptor() ([]byte, []int) { - return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{12} + return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{14} } func (x *UnixDogstatsdMsg) GetTimestamp() int64 { @@ -893,7 +991,7 @@ type TaggerState struct { func (x *TaggerState) Reset() { *x = TaggerState{} - mi := &file_datadog_model_v1_model_proto_msgTypes[13] + mi := &file_datadog_model_v1_model_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -905,7 +1003,7 @@ func (x *TaggerState) String() string { func (*TaggerState) ProtoMessage() {} func (x *TaggerState) ProtoReflect() protoreflect.Message { - mi := &file_datadog_model_v1_model_proto_msgTypes[13] + mi := &file_datadog_model_v1_model_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -918,7 +1016,7 @@ func (x *TaggerState) ProtoReflect() protoreflect.Message { // Deprecated: Use TaggerState.ProtoReflect.Descriptor instead. func (*TaggerState) Descriptor() ([]byte, []int) { - return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{13} + return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{15} } func (x *TaggerState) GetState() map[string]*Entity { @@ -945,7 +1043,7 @@ type TaggerStateResponse struct { func (x *TaggerStateResponse) Reset() { *x = TaggerStateResponse{} - mi := &file_datadog_model_v1_model_proto_msgTypes[14] + mi := &file_datadog_model_v1_model_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -957,7 +1055,7 @@ func (x *TaggerStateResponse) String() string { func (*TaggerStateResponse) ProtoMessage() {} func (x *TaggerStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_datadog_model_v1_model_proto_msgTypes[14] + mi := &file_datadog_model_v1_model_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -970,7 +1068,7 @@ func (x *TaggerStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TaggerStateResponse.ProtoReflect.Descriptor instead. func (*TaggerStateResponse) Descriptor() ([]byte, []int) { - return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{14} + return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{16} } func (x *TaggerStateResponse) GetLoaded() bool { @@ -980,6 +1078,138 @@ func (x *TaggerStateResponse) GetLoaded() bool { return false } +// Nested message for the local data +type GenerateContainerIDFromOriginInfoRequest_LocalData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ProcessID *uint32 `protobuf:"varint,1,opt,name=processID,proto3,oneof" json:"processID,omitempty"` // Process ID of the container process on the host. + ContainerID *string `protobuf:"bytes,2,opt,name=containerID,proto3,oneof" json:"containerID,omitempty"` // Container ID send from the client. + Inode *uint64 `protobuf:"varint,3,opt,name=inode,proto3,oneof" json:"inode,omitempty"` // Cgroup inode of the container. + PodUID *string `protobuf:"bytes,4,opt,name=podUID,proto3,oneof" json:"podUID,omitempty"` // Pod UID send from the client. +} + +func (x *GenerateContainerIDFromOriginInfoRequest_LocalData) Reset() { + *x = GenerateContainerIDFromOriginInfoRequest_LocalData{} + mi := &file_datadog_model_v1_model_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GenerateContainerIDFromOriginInfoRequest_LocalData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateContainerIDFromOriginInfoRequest_LocalData) ProtoMessage() {} + +func (x *GenerateContainerIDFromOriginInfoRequest_LocalData) ProtoReflect() protoreflect.Message { + mi := &file_datadog_model_v1_model_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GenerateContainerIDFromOriginInfoRequest_LocalData.ProtoReflect.Descriptor instead. +func (*GenerateContainerIDFromOriginInfoRequest_LocalData) Descriptor() ([]byte, []int) { + return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{9, 0} +} + +func (x *GenerateContainerIDFromOriginInfoRequest_LocalData) GetProcessID() uint32 { + if x != nil && x.ProcessID != nil { + return *x.ProcessID + } + return 0 +} + +func (x *GenerateContainerIDFromOriginInfoRequest_LocalData) GetContainerID() string { + if x != nil && x.ContainerID != nil { + return *x.ContainerID + } + return "" +} + +func (x *GenerateContainerIDFromOriginInfoRequest_LocalData) GetInode() uint64 { + if x != nil && x.Inode != nil { + return *x.Inode + } + return 0 +} + +func (x *GenerateContainerIDFromOriginInfoRequest_LocalData) GetPodUID() string { + if x != nil && x.PodUID != nil { + return *x.PodUID + } + return "" +} + +// Nested message for the external data +type GenerateContainerIDFromOriginInfoRequest_ExternalData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Init *bool `protobuf:"varint,1,opt,name=init,proto3,oneof" json:"init,omitempty"` // Init is true if the container is an init container. + ContainerName *string `protobuf:"bytes,2,opt,name=containerName,proto3,oneof" json:"containerName,omitempty"` // Container name as seen by the Admission Controller. + PodUID *string `protobuf:"bytes,3,opt,name=podUID,proto3,oneof" json:"podUID,omitempty"` // Pod UID as seen by the Admission Controller. +} + +func (x *GenerateContainerIDFromOriginInfoRequest_ExternalData) Reset() { + *x = GenerateContainerIDFromOriginInfoRequest_ExternalData{} + mi := &file_datadog_model_v1_model_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GenerateContainerIDFromOriginInfoRequest_ExternalData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateContainerIDFromOriginInfoRequest_ExternalData) ProtoMessage() {} + +func (x *GenerateContainerIDFromOriginInfoRequest_ExternalData) ProtoReflect() protoreflect.Message { + mi := &file_datadog_model_v1_model_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GenerateContainerIDFromOriginInfoRequest_ExternalData.ProtoReflect.Descriptor instead. +func (*GenerateContainerIDFromOriginInfoRequest_ExternalData) Descriptor() ([]byte, []int) { + return file_datadog_model_v1_model_proto_rawDescGZIP(), []int{9, 1} +} + +func (x *GenerateContainerIDFromOriginInfoRequest_ExternalData) GetInit() bool { + if x != nil && x.Init != nil { + return *x.Init + } + return false +} + +func (x *GenerateContainerIDFromOriginInfoRequest_ExternalData) GetContainerName() string { + if x != nil && x.ContainerName != nil { + return *x.ContainerName + } + return "" +} + +func (x *GenerateContainerIDFromOriginInfoRequest_ExternalData) GetPodUID() string { + if x != nil && x.PodUID != nil { + return *x.PodUID + } + return "" +} + var File_datadog_model_v1_model_proto protoreflect.FileDescriptor var file_datadog_model_v1_model_proto_rawDesc = []byte{ @@ -1055,70 +1285,115 @@ var file_datadog_model_v1_model_proto_rawDesc = []byte{ 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x54, 0x61, 0x67, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x54, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x54, - 0x61, 0x67, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x12, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, - 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x49, 0x64, 0x52, 0x02, 0x69, 0x64, 0x12, 0x42, 0x0a, 0x0b, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, - 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, 0x61, - 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x54, - 0x61, 0x67, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0b, 0x63, - 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x99, 0x01, 0x0a, 0x13, 0x46, - 0x65, 0x74, 0x63, 0x68, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, - 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x52, 0x02, 0x69, 0x64, 0x12, 0x42, - 0x0a, 0x0b, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, - 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, - 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0b, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, - 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22, 0x34, 0x0a, 0x08, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0xc2, 0x01, 0x0a, - 0x10, 0x55, 0x6e, 0x69, 0x78, 0x44, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x4d, 0x73, - 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, - 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x69, 0x7a, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, - 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x24, 0x0a, - 0x0d, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x72, 0x79, 0x53, - 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x72, 0x79, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x72, - 0x79, 0x22, 0x9f, 0x02, 0x0a, 0x0b, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, - 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x41, 0x0a, 0x06, 0x70, 0x69, 0x64, 0x4d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, + 0x61, 0x67, 0x73, 0x22, 0xff, 0x04, 0x0a, 0x28, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x46, 0x72, 0x6f, 0x6d, 0x4f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x67, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, + 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x46, 0x72, 0x6f, 0x6d, 0x4f, 0x72, + 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01, 0x12, 0x70, 0x0a, 0x0c, 0x65, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x47, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x46, 0x72, 0x6f, 0x6d, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x48, 0x01, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01, 0x1a, 0xc0, 0x01, 0x0a, 0x09, + 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x09, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x09, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x44, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x01, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, + 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x04, 0x48, 0x02, 0x52, 0x05, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1b, + 0x0a, 0x06, 0x70, 0x6f, 0x64, 0x55, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, + 0x52, 0x06, 0x70, 0x6f, 0x64, 0x55, 0x49, 0x44, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x44, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x69, 0x6e, + 0x6f, 0x64, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x70, 0x6f, 0x64, 0x55, 0x49, 0x44, 0x1a, 0x95, + 0x01, 0x0a, 0x0c, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x17, 0x0a, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, + 0x04, 0x69, 0x6e, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x29, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x01, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x70, 0x6f, 0x64, 0x55, 0x49, 0x44, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x06, 0x70, 0x6f, 0x64, 0x55, 0x49, 0x44, 0x88, 0x01, 0x01, + 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, + 0x70, 0x6f, 0x64, 0x55, 0x49, 0x44, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x44, 0x61, 0x74, 0x61, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x44, 0x61, 0x74, 0x61, 0x22, 0x4d, 0x0a, 0x29, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x46, 0x72, 0x6f, 0x6d, + 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, + 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x49, 0x44, 0x22, 0x84, 0x01, 0x0a, 0x12, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, + 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x49, 0x64, 0x52, 0x02, 0x69, 0x64, 0x12, 0x42, 0x0a, 0x0b, 0x63, 0x61, 0x72, 0x64, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, + 0x54, 0x61, 0x67, 0x43, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0b, + 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x99, 0x01, 0x0a, 0x13, + 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x42, 0x0a, 0x0b, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x43, 0x61, 0x72, 0x64, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0b, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22, 0x34, 0x0a, 0x08, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0xc2, 0x01, + 0x0a, 0x10, 0x55, 0x6e, 0x69, 0x78, 0x44, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x4d, + 0x73, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x10, 0x0a, 0x03, + 0x70, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x24, + 0x0a, 0x0d, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x72, 0x79, + 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x72, + 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x69, 0x6c, 0x6c, 0x61, + 0x72, 0x79, 0x22, 0x9f, 0x02, 0x0a, 0x0b, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x28, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x50, 0x69, 0x64, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x70, 0x69, - 0x64, 0x4d, 0x61, 0x70, 0x1a, 0x52, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, - 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x50, 0x69, 0x64, 0x4d, - 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0x2d, 0x0a, 0x13, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x6f, - 0x61, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6c, 0x6f, 0x61, 0x64, - 0x65, 0x64, 0x2a, 0x31, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x09, 0x0a, 0x05, 0x41, 0x44, 0x44, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x4f, - 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, - 0x54, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x35, 0x0a, 0x0e, 0x54, 0x61, 0x67, 0x43, 0x61, 0x72, 0x64, - 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x57, 0x10, 0x00, - 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x52, 0x43, 0x48, 0x45, 0x53, 0x54, 0x52, 0x41, 0x54, 0x4f, 0x52, - 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, 0x10, 0x02, 0x42, 0x15, 0x5a, 0x13, - 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x67, 0x6f, 0x2f, 0x63, - 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x70, 0x69, 0x64, 0x4d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x2e, 0x50, 0x69, 0x64, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x70, + 0x69, 0x64, 0x4d, 0x61, 0x70, 0x1a, 0x52, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x50, 0x69, 0x64, + 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2d, 0x0a, 0x13, 0x54, 0x61, 0x67, 0x67, 0x65, 0x72, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, + 0x6f, 0x61, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6c, 0x6f, 0x61, + 0x64, 0x65, 0x64, 0x2a, 0x31, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x44, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, + 0x4f, 0x44, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, + 0x45, 0x54, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x35, 0x0a, 0x0e, 0x54, 0x61, 0x67, 0x43, 0x61, 0x72, + 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x4f, 0x57, 0x10, + 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x52, 0x43, 0x48, 0x45, 0x53, 0x54, 0x52, 0x41, 0x54, 0x4f, + 0x52, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x49, 0x47, 0x48, 0x10, 0x02, 0x42, 0x15, 0x5a, + 0x13, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x67, 0x6f, 0x2f, + 0x63, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1134,27 +1409,31 @@ func file_datadog_model_v1_model_proto_rawDescGZIP() []byte { } var file_datadog_model_v1_model_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_datadog_model_v1_model_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_datadog_model_v1_model_proto_msgTypes = make([]protoimpl.MessageInfo, 21) var file_datadog_model_v1_model_proto_goTypes = []any{ - (EventType)(0), // 0: datadog.model.v1.EventType - (TagCardinality)(0), // 1: datadog.model.v1.TagCardinality - (*HostnameRequest)(nil), // 2: datadog.model.v1.HostnameRequest - (*HostnameReply)(nil), // 3: datadog.model.v1.HostnameReply - (*CaptureTriggerRequest)(nil), // 4: datadog.model.v1.CaptureTriggerRequest - (*CaptureTriggerResponse)(nil), // 5: datadog.model.v1.CaptureTriggerResponse - (*StreamTagsRequest)(nil), // 6: datadog.model.v1.StreamTagsRequest - (*StreamTagsResponse)(nil), // 7: datadog.model.v1.StreamTagsResponse - (*StreamTagsEvent)(nil), // 8: datadog.model.v1.StreamTagsEvent - (*DeprecatedFilter)(nil), // 9: datadog.model.v1.DeprecatedFilter - (*Entity)(nil), // 10: datadog.model.v1.Entity - (*FetchEntityRequest)(nil), // 11: datadog.model.v1.FetchEntityRequest - (*FetchEntityResponse)(nil), // 12: datadog.model.v1.FetchEntityResponse - (*EntityId)(nil), // 13: datadog.model.v1.EntityId - (*UnixDogstatsdMsg)(nil), // 14: datadog.model.v1.UnixDogstatsdMsg - (*TaggerState)(nil), // 15: datadog.model.v1.TaggerState - (*TaggerStateResponse)(nil), // 16: datadog.model.v1.TaggerStateResponse - nil, // 17: datadog.model.v1.TaggerState.StateEntry - nil, // 18: datadog.model.v1.TaggerState.PidMapEntry + (EventType)(0), // 0: datadog.model.v1.EventType + (TagCardinality)(0), // 1: datadog.model.v1.TagCardinality + (*HostnameRequest)(nil), // 2: datadog.model.v1.HostnameRequest + (*HostnameReply)(nil), // 3: datadog.model.v1.HostnameReply + (*CaptureTriggerRequest)(nil), // 4: datadog.model.v1.CaptureTriggerRequest + (*CaptureTriggerResponse)(nil), // 5: datadog.model.v1.CaptureTriggerResponse + (*StreamTagsRequest)(nil), // 6: datadog.model.v1.StreamTagsRequest + (*StreamTagsResponse)(nil), // 7: datadog.model.v1.StreamTagsResponse + (*StreamTagsEvent)(nil), // 8: datadog.model.v1.StreamTagsEvent + (*DeprecatedFilter)(nil), // 9: datadog.model.v1.DeprecatedFilter + (*Entity)(nil), // 10: datadog.model.v1.Entity + (*GenerateContainerIDFromOriginInfoRequest)(nil), // 11: datadog.model.v1.GenerateContainerIDFromOriginInfoRequest + (*GenerateContainerIDFromOriginInfoResponse)(nil), // 12: datadog.model.v1.GenerateContainerIDFromOriginInfoResponse + (*FetchEntityRequest)(nil), // 13: datadog.model.v1.FetchEntityRequest + (*FetchEntityResponse)(nil), // 14: datadog.model.v1.FetchEntityResponse + (*EntityId)(nil), // 15: datadog.model.v1.EntityId + (*UnixDogstatsdMsg)(nil), // 16: datadog.model.v1.UnixDogstatsdMsg + (*TaggerState)(nil), // 17: datadog.model.v1.TaggerState + (*TaggerStateResponse)(nil), // 18: datadog.model.v1.TaggerStateResponse + (*GenerateContainerIDFromOriginInfoRequest_LocalData)(nil), // 19: datadog.model.v1.GenerateContainerIDFromOriginInfoRequest.LocalData + (*GenerateContainerIDFromOriginInfoRequest_ExternalData)(nil), // 20: datadog.model.v1.GenerateContainerIDFromOriginInfoRequest.ExternalData + nil, // 21: datadog.model.v1.TaggerState.StateEntry + nil, // 22: datadog.model.v1.TaggerState.PidMapEntry } var file_datadog_model_v1_model_proto_depIdxs = []int32{ 1, // 0: datadog.model.v1.StreamTagsRequest.cardinality:type_name -> datadog.model.v1.TagCardinality @@ -1163,19 +1442,21 @@ var file_datadog_model_v1_model_proto_depIdxs = []int32{ 8, // 3: datadog.model.v1.StreamTagsResponse.events:type_name -> datadog.model.v1.StreamTagsEvent 0, // 4: datadog.model.v1.StreamTagsEvent.type:type_name -> datadog.model.v1.EventType 10, // 5: datadog.model.v1.StreamTagsEvent.entity:type_name -> datadog.model.v1.Entity - 13, // 6: datadog.model.v1.Entity.id:type_name -> datadog.model.v1.EntityId - 13, // 7: datadog.model.v1.FetchEntityRequest.id:type_name -> datadog.model.v1.EntityId - 1, // 8: datadog.model.v1.FetchEntityRequest.cardinality:type_name -> datadog.model.v1.TagCardinality - 13, // 9: datadog.model.v1.FetchEntityResponse.id:type_name -> datadog.model.v1.EntityId - 1, // 10: datadog.model.v1.FetchEntityResponse.cardinality:type_name -> datadog.model.v1.TagCardinality - 17, // 11: datadog.model.v1.TaggerState.state:type_name -> datadog.model.v1.TaggerState.StateEntry - 18, // 12: datadog.model.v1.TaggerState.pidMap:type_name -> datadog.model.v1.TaggerState.PidMapEntry - 10, // 13: datadog.model.v1.TaggerState.StateEntry.value:type_name -> datadog.model.v1.Entity - 14, // [14:14] is the sub-list for method output_type - 14, // [14:14] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name + 15, // 6: datadog.model.v1.Entity.id:type_name -> datadog.model.v1.EntityId + 19, // 7: datadog.model.v1.GenerateContainerIDFromOriginInfoRequest.localData:type_name -> datadog.model.v1.GenerateContainerIDFromOriginInfoRequest.LocalData + 20, // 8: datadog.model.v1.GenerateContainerIDFromOriginInfoRequest.externalData:type_name -> datadog.model.v1.GenerateContainerIDFromOriginInfoRequest.ExternalData + 15, // 9: datadog.model.v1.FetchEntityRequest.id:type_name -> datadog.model.v1.EntityId + 1, // 10: datadog.model.v1.FetchEntityRequest.cardinality:type_name -> datadog.model.v1.TagCardinality + 15, // 11: datadog.model.v1.FetchEntityResponse.id:type_name -> datadog.model.v1.EntityId + 1, // 12: datadog.model.v1.FetchEntityResponse.cardinality:type_name -> datadog.model.v1.TagCardinality + 21, // 13: datadog.model.v1.TaggerState.state:type_name -> datadog.model.v1.TaggerState.StateEntry + 22, // 14: datadog.model.v1.TaggerState.pidMap:type_name -> datadog.model.v1.TaggerState.PidMapEntry + 10, // 15: datadog.model.v1.TaggerState.StateEntry.value:type_name -> datadog.model.v1.Entity + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name } func init() { file_datadog_model_v1_model_proto_init() } @@ -1183,13 +1464,16 @@ func file_datadog_model_v1_model_proto_init() { if File_datadog_model_v1_model_proto != nil { return } + file_datadog_model_v1_model_proto_msgTypes[9].OneofWrappers = []any{} + file_datadog_model_v1_model_proto_msgTypes[17].OneofWrappers = []any{} + file_datadog_model_v1_model_proto_msgTypes[18].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_datadog_model_v1_model_proto_rawDesc, NumEnums: 2, - NumMessages: 17, + NumMessages: 21, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/proto/pbgo/mocks/core/api_mockgen.pb.go b/pkg/proto/pbgo/mocks/core/api_mockgen.pb.go index 7d7798b724aaa..a28d85a34a874 100644 --- a/pkg/proto/pbgo/mocks/core/api_mockgen.pb.go +++ b/pkg/proto/pbgo/mocks/core/api_mockgen.pb.go @@ -299,6 +299,26 @@ func (mr *MockAgentSecureClientMockRecorder) TaggerFetchEntity(ctx, in interface return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaggerFetchEntity", reflect.TypeOf((*MockAgentSecureClient)(nil).TaggerFetchEntity), varargs...) } +// TaggerGenerateContainerIDFromOriginInfo mocks base method. +func (m *MockAgentSecureClient) TaggerGenerateContainerIDFromOriginInfo(ctx context.Context, in *core.GenerateContainerIDFromOriginInfoRequest, opts ...grpc.CallOption) (*core.GenerateContainerIDFromOriginInfoResponse, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "TaggerGenerateContainerIDFromOriginInfo", varargs...) + ret0, _ := ret[0].(*core.GenerateContainerIDFromOriginInfoResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TaggerGenerateContainerIDFromOriginInfo indicates an expected call of TaggerGenerateContainerIDFromOriginInfo. +func (mr *MockAgentSecureClientMockRecorder) TaggerGenerateContainerIDFromOriginInfo(ctx, in interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaggerGenerateContainerIDFromOriginInfo", reflect.TypeOf((*MockAgentSecureClient)(nil).TaggerGenerateContainerIDFromOriginInfo), varargs...) +} + // TaggerStreamEntities mocks base method. func (m *MockAgentSecureClient) TaggerStreamEntities(ctx context.Context, in *core.StreamTagsRequest, opts ...grpc.CallOption) (core.AgentSecure_TaggerStreamEntitiesClient, error) { m.ctrl.T.Helper() @@ -865,6 +885,21 @@ func (mr *MockAgentSecureServerMockRecorder) TaggerFetchEntity(arg0, arg1 interf return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaggerFetchEntity", reflect.TypeOf((*MockAgentSecureServer)(nil).TaggerFetchEntity), arg0, arg1) } +// TaggerGenerateContainerIDFromOriginInfo mocks base method. +func (m *MockAgentSecureServer) TaggerGenerateContainerIDFromOriginInfo(arg0 context.Context, arg1 *core.GenerateContainerIDFromOriginInfoRequest) (*core.GenerateContainerIDFromOriginInfoResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TaggerGenerateContainerIDFromOriginInfo", arg0, arg1) + ret0, _ := ret[0].(*core.GenerateContainerIDFromOriginInfoResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TaggerGenerateContainerIDFromOriginInfo indicates an expected call of TaggerGenerateContainerIDFromOriginInfo. +func (mr *MockAgentSecureServerMockRecorder) TaggerGenerateContainerIDFromOriginInfo(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaggerGenerateContainerIDFromOriginInfo", reflect.TypeOf((*MockAgentSecureServer)(nil).TaggerGenerateContainerIDFromOriginInfo), arg0, arg1) +} + // TaggerStreamEntities mocks base method. func (m *MockAgentSecureServer) TaggerStreamEntities(arg0 *core.StreamTagsRequest, arg1 core.AgentSecure_TaggerStreamEntitiesServer) error { m.ctrl.T.Helper() diff --git a/pkg/security/agent/client.go b/pkg/security/agent/client.go index 81e2cf630b549..bb0c1714bd039 100644 --- a/pkg/security/agent/client.go +++ b/pkg/security/agent/client.go @@ -35,7 +35,7 @@ type SecurityModuleClientWrapper interface { DumpProcessCache(withArgs bool, format string) (string, error) GenerateActivityDump(request *api.ActivityDumpParams) (*api.ActivityDumpMessage, error) ListActivityDumps() (*api.ActivityDumpListMessage, error) - StopActivityDump(name, containerid string) (*api.ActivityDumpStopMessage, error) + StopActivityDump(name, container, cgroup string) (*api.ActivityDumpStopMessage, error) GenerateEncoding(request *api.TranscodingRequestParams) (*api.TranscodingRequestMessage, error) DumpNetworkNamespace(snapshotInterfaces bool) (*api.DumpNetworkNamespaceMessage, error) GetConfig() (*api.SecurityConfigMessage, error) @@ -81,10 +81,11 @@ func (c *RuntimeSecurityClient) GenerateActivityDump(request *api.ActivityDumpPa } // StopActivityDump stops an active dump if it exists -func (c *RuntimeSecurityClient) StopActivityDump(name, containerid string) (*api.ActivityDumpStopMessage, error) { +func (c *RuntimeSecurityClient) StopActivityDump(name, container, cgroup string) (*api.ActivityDumpStopMessage, error) { return c.apiClient.StopActivityDump(context.Background(), &api.ActivityDumpStopParams{ Name: name, - ContainerID: containerid, + ContainerID: container, + CGroupID: cgroup, }) } diff --git a/pkg/security/agent/mocks/security_module_client_wrapper.go b/pkg/security/agent/mocks/security_module_client_wrapper.go index 227b6c2072121..c31eae478f235 100644 --- a/pkg/security/agent/mocks/security_module_client_wrapper.go +++ b/pkg/security/agent/mocks/security_module_client_wrapper.go @@ -463,9 +463,9 @@ func (_m *SecurityModuleClientWrapper) SaveSecurityProfile(name string, tag stri return r0, r1 } -// StopActivityDump provides a mock function with given fields: name, containerid -func (_m *SecurityModuleClientWrapper) StopActivityDump(name string, containerid string) (*api.ActivityDumpStopMessage, error) { - ret := _m.Called(name, containerid) +// StopActivityDump provides a mock function with given fields: name, container, cgroup +func (_m *SecurityModuleClientWrapper) StopActivityDump(name string, container string, cgroup string) (*api.ActivityDumpStopMessage, error) { + ret := _m.Called(name, container, cgroup) if len(ret) == 0 { panic("no return value specified for StopActivityDump") @@ -473,19 +473,19 @@ func (_m *SecurityModuleClientWrapper) StopActivityDump(name string, containerid var r0 *api.ActivityDumpStopMessage var r1 error - if rf, ok := ret.Get(0).(func(string, string) (*api.ActivityDumpStopMessage, error)); ok { - return rf(name, containerid) + if rf, ok := ret.Get(0).(func(string, string, string) (*api.ActivityDumpStopMessage, error)); ok { + return rf(name, container, cgroup) } - if rf, ok := ret.Get(0).(func(string, string) *api.ActivityDumpStopMessage); ok { - r0 = rf(name, containerid) + if rf, ok := ret.Get(0).(func(string, string, string) *api.ActivityDumpStopMessage); ok { + r0 = rf(name, container, cgroup) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*api.ActivityDumpStopMessage) } } - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(name, containerid) + if rf, ok := ret.Get(1).(func(string, string, string) error); ok { + r1 = rf(name, container, cgroup) } else { r1 = ret.Error(1) } diff --git a/pkg/security/ebpf/c/include/helpers/activity_dump.h b/pkg/security/ebpf/c/include/helpers/activity_dump.h index 82ed6834e10fb..c0f8d246006bf 100644 --- a/pkg/security/ebpf/c/include/helpers/activity_dump.h +++ b/pkg/security/ebpf/c/include/helpers/activity_dump.h @@ -53,7 +53,7 @@ __attribute__((always_inline)) struct cgroup_tracing_event_t *get_cgroup_tracing return evt; } -__attribute__((always_inline)) bool reserve_traced_cgroup_spot(container_id_t cgroup, u64 now, u64 cookie, struct activity_dump_config *config) { +__attribute__((always_inline)) bool reserve_traced_cgroup_spot(struct cgroup_context_t *cgroup, u64 now, u64 cookie, struct activity_dump_config *config) { // insert dump config defaults u32 defaults_key = 0; struct activity_dump_config *defaults = bpf_map_lookup_elem(&activity_dump_config_defaults, &defaults_key); @@ -72,7 +72,9 @@ __attribute__((always_inline)) bool reserve_traced_cgroup_spot(container_id_t cg return false; } - ret = bpf_map_update_elem(&traced_cgroups, &cgroup[0], &cookie, BPF_NOEXIST); + struct path_key_t path_key; + path_key = cgroup->cgroup_file; + ret = bpf_map_update_elem(&traced_cgroups, &path_key, &cookie, BPF_NOEXIST); if (ret < 0) { // we didn't get a lock, skip this cgroup for now and go back to it later bpf_map_delete_elem(&activity_dumps_config, &cookie); @@ -80,15 +82,15 @@ __attribute__((always_inline)) bool reserve_traced_cgroup_spot(container_id_t cg } // we're tracing a new cgroup, update its wait list timeout - bpf_map_update_elem(&cgroup_wait_list, &cgroup[0], &config->wait_list_timestamp, BPF_ANY); + bpf_map_update_elem(&cgroup_wait_list, &path_key, &config->wait_list_timestamp, BPF_ANY); return true; } -__attribute__((always_inline)) u64 trace_new_cgroup(void *ctx, u64 now, container_id_t container_id, struct cgroup_context_t *cgroup) { +__attribute__((always_inline)) u64 trace_new_cgroup(void *ctx, u64 now, struct container_context_t *container) { u64 cookie = rand64(); struct activity_dump_config config = {}; - if (!reserve_traced_cgroup_spot(container_id, now, cookie, &config)) { + if (!reserve_traced_cgroup_spot(&container->cgroup_context, now, cookie, &config)) { // we're already tracing too many cgroups concurrently, ignore this one for now return 0; } @@ -100,35 +102,38 @@ __attribute__((always_inline)) u64 trace_new_cgroup(void *ctx, u64 now, containe return 0; } - if ((cgroup->cgroup_flags & 0b111) == CGROUP_MANAGER_SYSTEMD) { + if ((container->cgroup_context.cgroup_flags & 0b111) == CGROUP_MANAGER_SYSTEMD) { return 0; } - copy_container_id(container_id, evt->container.container_id); - evt->container.cgroup_context = *cgroup; + copy_container_id(container->container_id, evt->container.container_id); + evt->container.cgroup_context = container->cgroup_context; evt->cookie = cookie; evt->config = config; send_event_ptr(ctx, EVENT_CGROUP_TRACING, evt); - // return cookie return cookie; } +__attribute__((always_inline)) u64 is_cgroup_activity_dumps_supported(struct cgroup_context_t *cgroup) { + return (cgroup->cgroup_flags != 0) && ((cgroup->cgroup_flags&0b111) != CGROUP_MANAGER_SYSTEMD); +} + __attribute__((always_inline)) u64 should_trace_new_process_cgroup(void *ctx, u64 now, u32 pid, struct container_context_t *container) { // should we start tracing this cgroup ? - container_id_t container_id; - bpf_probe_read(&container_id, sizeof(container_id), &container->container_id[0]); + struct cgroup_context_t cgroup_context; + bpf_probe_read(&cgroup_context, sizeof(cgroup_context), &container->cgroup_context); - if (is_cgroup_activity_dumps_enabled() && container_id[0] != 0) { + if (is_cgroup_activity_dumps_enabled() && is_cgroup_activity_dumps_supported(&cgroup_context)) { // is this cgroup traced ? - u64 *cookie = bpf_map_lookup_elem(&traced_cgroups, &container_id[0]); + u64 *cookie = bpf_map_lookup_elem(&traced_cgroups, &cgroup_context.cgroup_file); if (cookie) { u64 cookie_val = *cookie; struct activity_dump_config *config = bpf_map_lookup_elem(&activity_dumps_config, &cookie_val); if (config == NULL) { // delete expired cgroup entry - bpf_map_delete_elem(&traced_cgroups, &container_id[0]); + bpf_map_delete_elem(&traced_cgroups, &cgroup_context.cgroup_file); return 0; } @@ -144,7 +149,7 @@ __attribute__((always_inline)) u64 should_trace_new_process_cgroup(void *ctx, u6 if (now > config->end_timestamp) { // delete expired cgroup entry - bpf_map_delete_elem(&traced_cgroups, &container_id[0]); + bpf_map_delete_elem(&traced_cgroups, &cgroup_context.cgroup_file); // delete config bpf_map_delete_elem(&activity_dumps_config, &cookie_val); return 0; @@ -156,11 +161,11 @@ __attribute__((always_inline)) u64 should_trace_new_process_cgroup(void *ctx, u6 } else { // have we seen this cgroup before ? - u64 *wait_timeout = bpf_map_lookup_elem(&cgroup_wait_list, &container_id[0]); + u64 *wait_timeout = bpf_map_lookup_elem(&cgroup_wait_list, &cgroup_context.cgroup_file); if (wait_timeout) { if (now > *wait_timeout) { // delete expired wait_list entry - bpf_map_delete_elem(&cgroup_wait_list, &container_id[0]); + bpf_map_delete_elem(&cgroup_wait_list, &cgroup_context.cgroup_file); } // this cgroup is on the wait list, do not start tracing it @@ -168,7 +173,7 @@ __attribute__((always_inline)) u64 should_trace_new_process_cgroup(void *ctx, u6 } // can we start tracing this cgroup ? - u64 cookie_val = trace_new_cgroup(ctx, now, container_id, &container->cgroup_context); + u64 cookie_val = trace_new_cgroup(ctx, now, container); if (cookie_val == 0) { return 0; } diff --git a/pkg/security/ebpf/c/include/maps.h b/pkg/security/ebpf/c/include/maps.h index 2019c630c6f4c..d6ab3ceb74dfb 100644 --- a/pkg/security/ebpf/c/include/maps.h +++ b/pkg/security/ebpf/c/include/maps.h @@ -29,8 +29,8 @@ BPF_ARRAY_MAP(syscall_ctx, char[MAX_SYSCALL_CTX_SIZE], MAX_SYSCALL_CTX_ENTRIES) BPF_HASH_MAP(activity_dumps_config, u64, struct activity_dump_config, 1) // max entries will be overridden at runtime BPF_HASH_MAP(activity_dump_config_defaults, u32, struct activity_dump_config, 1) -BPF_HASH_MAP(traced_cgroups, container_id_t, u64, 1) // max entries will be overridden at runtime -BPF_HASH_MAP(cgroup_wait_list, container_id_t, u64, 1) // max entries will be overridden at runtime +BPF_HASH_MAP(traced_cgroups, struct path_key_t, u64, 1) // max entries will be overridden at runtime +BPF_HASH_MAP(cgroup_wait_list, struct path_key_t, u64, 1) // max entries will be overridden at runtime BPF_HASH_MAP(traced_pids, u32, u64, 8192) // max entries will be overridden at runtime BPF_HASH_MAP(basename_approvers, struct basename_t, struct event_mask_filter_t, 255) BPF_HASH_MAP(register_netdevice_cache, u64, struct register_netdevice_cache_t, 1024) diff --git a/pkg/security/probe/field_handlers_ebpf.go b/pkg/security/probe/field_handlers_ebpf.go index 36acd3a33d5a2..b76b70a76b833 100644 --- a/pkg/security/probe/field_handlers_ebpf.go +++ b/pkg/security/probe/field_handlers_ebpf.go @@ -20,7 +20,6 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/resolvers" sprocess "github.com/DataDog/datadog-agent/pkg/security/resolvers/process" "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" - "github.com/DataDog/datadog-agent/pkg/security/seclog" "github.com/DataDog/datadog-agent/pkg/security/secl/args" "github.com/DataDog/datadog-agent/pkg/security/secl/model" @@ -516,11 +515,9 @@ func (fh *EBPFFieldHandlers) ResolveCGroupID(ev *model.Event, e *model.CGroupCon return string(entry.CGroup.CGroupID) } - if err := fh.resolvers.ResolveCGroup(entry, e.CGroupFile, e.CGroupFlags); err != nil { - seclog.Debugf("Failed to resolve cgroup: %s", err) + if cgroupContext, err := fh.resolvers.ResolveCGroupContext(e.CGroupFile, e.CGroupFlags); err == nil { + *e = *cgroupContext } - - e.CGroupID = entry.CGroup.CGroupID } } diff --git a/pkg/security/probe/probe_ebpf.go b/pkg/security/probe/probe_ebpf.go index ca55fb768bd5f..f06cbe8fa45ae 100644 --- a/pkg/security/probe/probe_ebpf.go +++ b/pkg/security/probe/probe_ebpf.go @@ -818,7 +818,18 @@ func (p *EBPFProbe) handleEvent(CPU int, data []byte) { return } - p.profileManagers.activityDumpManager.HandleCGroupTracingEvent(&event.CgroupTracing) + if cgroupContext, err := p.Resolvers.ResolveCGroupContext(event.CgroupTracing.CGroupContext.CGroupFile, containerutils.CGroupFlags(event.CgroupTracing.CGroupContext.CGroupFlags)); err != nil { + seclog.Debugf("Failed to resolve cgroup: %s", err) + } else { + event.CgroupTracing.CGroupContext = *cgroupContext + if cgroupContext.CGroupFlags.IsContainer() { + containerID, _ := containerutils.FindContainerID(cgroupContext.CGroupID) + event.CgroupTracing.ContainerContext.ContainerID = containerID + } + + p.profileManagers.activityDumpManager.HandleCGroupTracingEvent(&event.CgroupTracing) + } + return case model.CgroupWriteEventType: if _, err = event.CgroupWrite.UnmarshalBinary(data[offset:]); err != nil { @@ -828,10 +839,21 @@ func (p *EBPFProbe) handleEvent(CPU int, data []byte) { pce := p.Resolvers.ProcessResolver.Resolve(event.CgroupWrite.Pid, event.CgroupWrite.Pid, 0, false, newEntryCb) if pce != nil { - if err := p.Resolvers.ResolveCGroup(pce, event.CgroupWrite.File.PathKey, containerutils.CGroupFlags(event.CgroupWrite.CGroupFlags)); err != nil { + cgroupContext, err := p.Resolvers.ResolveCGroupContext(event.CgroupWrite.File.PathKey, containerutils.CGroupFlags(event.CgroupWrite.CGroupFlags)) + if err != nil { seclog.Debugf("Failed to resolve cgroup: %s", err) + } else { + pce.Process.CGroup = *cgroupContext + pce.CGroup = *cgroupContext + + if cgroupContext.CGroupFlags.IsContainer() { + containerID, _ := containerutils.FindContainerID(cgroupContext.CGroupID) + pce.ContainerID = containerID + pce.Process.ContainerID = containerID + } } } + return case model.UnshareMountNsEventType: if _, err = event.UnshareMountNS.UnmarshalBinary(data[offset:]); err != nil { diff --git a/pkg/security/process_list/process_list.go b/pkg/security/process_list/process_list.go index 1fdb4a80bd70b..64c76705a553f 100644 --- a/pkg/security/process_list/process_list.go +++ b/pkg/security/process_list/process_list.go @@ -14,9 +14,8 @@ import ( "io" "sync" - cgroupModel "github.com/DataDog/datadog-agent/pkg/security/resolvers/cgroup/model" - "github.com/DataDog/datadog-agent/pkg/process/procutil" + cgroupModel "github.com/DataDog/datadog-agent/pkg/security/resolvers/cgroup/model" "github.com/DataDog/datadog-agent/pkg/security/secl/model" "github.com/DataDog/datadog-go/v5/statsd" "golang.org/x/exp/slices" diff --git a/pkg/security/process_list/process_resolver/process_resolver_test.go b/pkg/security/process_list/process_resolver/process_resolver_test.go index 600e0c03bc8a9..1c062c45c0f99 100644 --- a/pkg/security/process_list/process_resolver/process_resolver_test.go +++ b/pkg/security/process_list/process_resolver/process_resolver_test.go @@ -141,7 +141,8 @@ func isProcessOrExecPresent(pl *processlist.ProcessList, pc *ProcessResolver, ev func TestFork1st(t *testing.T) { pc := NewProcessResolver() - processList := processlist.NewProcessList(cgroupModel.WorkloadSelector{Image: "*", Tag: "*"}, + selector, _ := cgroupModel.NewWorkloadSelector("*", "*") + processList := processlist.NewProcessList(selector, []model.EventType{model.ExecEventType, model.ForkEventType, model.ExitEventType}, pc /* ,nil */, nil, nil) stats := testStats{} diff --git a/pkg/security/proto/api/api.pb.go b/pkg/security/proto/api/api.pb.go index 60cc167d246f9..e8fd80f24c5c8 100644 --- a/pkg/security/proto/api/api.pb.go +++ b/pkg/security/proto/api/api.pb.go @@ -1594,6 +1594,7 @@ type ActivityDumpParams struct { DifferentiateArgs bool `protobuf:"varint,2,opt,name=DifferentiateArgs,proto3" json:"DifferentiateArgs,omitempty"` Storage *StorageRequestParams `protobuf:"bytes,3,opt,name=Storage,proto3" json:"Storage,omitempty"` ContainerID string `protobuf:"bytes,4,opt,name=ContainerID,proto3" json:"ContainerID,omitempty"` + CGroupID string `protobuf:"bytes,5,opt,name=CGroupID,proto3" json:"CGroupID,omitempty"` } func (x *ActivityDumpParams) Reset() { @@ -1656,6 +1657,13 @@ func (x *ActivityDumpParams) GetContainerID() string { return "" } +func (x *ActivityDumpParams) GetCGroupID() string { + if x != nil { + return x.CGroupID + } + return "" +} + type MetadataMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1676,6 +1684,7 @@ type MetadataMessage struct { Timeout string `protobuf:"bytes,12,opt,name=Timeout,proto3" json:"Timeout,omitempty"` Size uint64 `protobuf:"varint,13,opt,name=Size,proto3" json:"Size,omitempty"` Serialization string `protobuf:"bytes,14,opt,name=Serialization,proto3" json:"Serialization,omitempty"` + CGroupID string `protobuf:"bytes,15,opt,name=CGroupID,proto3" json:"CGroupID,omitempty"` } func (x *MetadataMessage) Reset() { @@ -1809,6 +1818,13 @@ func (x *MetadataMessage) GetSerialization() string { return "" } +func (x *MetadataMessage) GetCGroupID() string { + if x != nil { + return x.CGroupID + } + return "" +} + type StorageRequestMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2091,6 +2107,7 @@ type ActivityDumpStopParams struct { Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` ContainerID string `protobuf:"bytes,2,opt,name=ContainerID,proto3" json:"ContainerID,omitempty"` + CGroupID string `protobuf:"bytes,3,opt,name=CGroupID,proto3" json:"CGroupID,omitempty"` } func (x *ActivityDumpStopParams) Reset() { @@ -2139,6 +2156,13 @@ func (x *ActivityDumpStopParams) GetContainerID() string { return "" } +func (x *ActivityDumpStopParams) GetCGroupID() string { + if x != nil { + return x.CGroupID + } + return "" +} + type ActivityDumpStopMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3298,7 +3322,7 @@ var file_pkg_security_proto_api_api_proto_rawDesc = []byte{ 0x0a, 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, - 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xb3, 0x01, 0x0a, 0x12, 0x41, + 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xcf, 0x01, 0x0a, 0x12, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x2c, 0x0a, 0x11, 0x44, @@ -3310,312 +3334,317 @@ var file_pkg_security_proto_api_api_proto_rawDesc = []byte{ 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, - 0x22, 0xcf, 0x03, 0x0a, 0x0f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x4b, 0x65, - 0x72, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x2c, 0x0a, 0x11, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x4c, 0x69, 0x6e, - 0x75, 0x78, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, - 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x2c, 0x0a, 0x11, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x74, - 0x65, 0x41, 0x72, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x44, 0x69, 0x66, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x74, 0x65, 0x41, 0x72, 0x67, 0x73, 0x12, 0x16, - 0x0a, 0x04, 0x43, 0x6f, 0x6d, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, - 0x52, 0x04, 0x43, 0x6f, 0x6d, 0x6d, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x49, 0x44, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, - 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x18, - 0x0a, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x69, 0x7a, 0x65, - 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x24, 0x0a, 0x0d, - 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0x79, 0x0a, 0x15, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x72, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x43, 0x6f, - 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x46, 0x69, 0x6c, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x22, 0xbe, 0x02, - 0x0a, 0x13, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, - 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, - 0x34, 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x53, 0x74, - 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1a, 0x0a, - 0x08, 0x44, 0x4e, 0x53, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x08, 0x44, 0x4e, 0x53, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x33, 0x0a, 0x05, 0x53, 0x74, 0x61, - 0x74, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, - 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x54, 0x72, 0x65, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0x18, - 0x0a, 0x16, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x5f, 0x0a, 0x17, 0x41, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x44, 0x75, 0x6d, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, - 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x44, 0x75, - 0x6d, 0x70, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x4e, 0x0a, 0x16, 0x41, 0x63, 0x74, - 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x22, 0x2f, 0x0a, 0x17, 0x41, 0x63, 0x74, - 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x6f, 0x70, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x7b, 0x0a, 0x18, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, - 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x10, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x46, 0x69, - 0x6c, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x07, - 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x67, 0x0a, 0x19, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x34, 0x0a, 0x07, 0x53, 0x74, - 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x5d, 0x0a, 0x19, - 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x44, 0x75, 0x6d, - 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x52, 0x04, 0x44, 0x75, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x3f, 0x0a, 0x17, 0x57, - 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x54, 0x61, - 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x54, 0x61, 0x67, 0x22, 0x87, 0x01, 0x0a, - 0x1b, 0x4c, 0x61, 0x73, 0x74, 0x41, 0x6e, 0x6f, 0x6d, 0x61, 0x6c, 0x79, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2c, 0x0a, 0x11, 0x49, 0x73, 0x53, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x11, 0x49, 0x73, 0x53, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x47, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x54, - 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x54, 0x61, 0x67, 0x73, 0x22, - 0xec, 0x01, 0x0a, 0x18, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x54, 0x72, 0x65, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x11, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x46, 0x69, - 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x44, 0x4e, 0x53, 0x4e, 0x6f, - 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x53, 0x6f, 0x63, 0x6b, - 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x10, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, - 0x61, 0x74, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x41, - 0x70, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x6e, - 0x0a, 0x10, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x6e, 0x6f, 0x6d, 0x61, - 0x6c, 0x79, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6c, - 0x61, 0x73, 0x74, 0x41, 0x6e, 0x6f, 0x6d, 0x61, 0x6c, 0x79, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x2e, - 0x0a, 0x13, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x9b, - 0x02, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x72, 0x73, - 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x69, - 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, - 0x73, 0x65, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, - 0x53, 0x65, 0x65, 0x6e, 0x12, 0x58, 0x0a, 0x10, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, - 0x67, 0x73, 0x1a, 0x58, 0x0a, 0x13, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa0, 0x06, 0x0a, - 0x16, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x4c, 0x6f, 0x61, 0x64, 0x65, - 0x64, 0x49, 0x6e, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0e, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x49, 0x6e, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x12, - 0x38, 0x0a, 0x17, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x49, 0x6e, 0x4b, 0x65, 0x72, 0x6e, 0x65, - 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x17, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x49, 0x6e, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x38, 0x0a, 0x08, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, - 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x0d, 0x4c, 0x61, 0x73, - 0x74, 0x41, 0x6e, 0x6f, 0x6d, 0x61, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x41, 0x6e, 0x6f, 0x6d, 0x61, - 0x6c, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x4c, 0x61, 0x73, 0x74, 0x41, 0x6e, 0x6f, 0x6d, - 0x61, 0x6c, 0x69, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x09, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x06, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, - 0x03, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x33, 0x0a, - 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x54, 0x72, 0x65, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x53, 0x74, 0x61, - 0x74, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x47, 0x6c, 0x6f, - 0x62, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x5b, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, - 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x1a, - 0x5e, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x3f, 0x0a, 0x19, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x22, 0x0a, 0x0c, - 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0c, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, - 0x22, 0x6b, 0x0a, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x37, - 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x55, 0x0a, - 0x19, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, - 0x53, 0x61, 0x76, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x38, 0x0a, 0x08, 0x53, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x22, 0x46, 0x0a, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x32, 0x8a, 0x0a, 0x0a, - 0x0e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, - 0x3f, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x13, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, - 0x12, 0x57, 0x0a, 0x10, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, - 0x61, 0x63, 0x68, 0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x50, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x1a, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, - 0x44, 0x75, 0x6d, 0x70, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x61, 0x63, 0x68, 0x65, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x09, 0x47, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1a, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x30, 0x0a, 0x09, 0x47, 0x65, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x0b, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0b, - 0x52, 0x75, 0x6e, 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x52, 0x75, 0x6e, 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x1a, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, - 0x74, 0x79, 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x10, 0x47, 0x65, 0x74, - 0x52, 0x75, 0x6c, 0x65, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x53, 0x65, 0x74, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x22, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, - 0x12, 0x4f, 0x0a, 0x0e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x20, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x00, 0x12, 0x5b, 0x0a, 0x14, 0x44, 0x75, 0x6d, 0x70, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x44, 0x75, 0x6d, 0x70, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x49, - 0x0a, 0x0e, 0x44, 0x75, 0x6d, 0x70, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, - 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x44, 0x69, 0x73, 0x63, 0x61, - 0x72, 0x64, 0x65, 0x72, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1a, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0c, 0x44, 0x75, 0x6d, - 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, - 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x50, - 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, - 0x6d, 0x70, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x43, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x44, 0x22, 0xeb, 0x03, 0x0a, + 0x0f, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x22, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x41, 0x67, 0x65, 0x6e, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4b, + 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x11, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x44, 0x69, + 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x72, + 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x12, + 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x11, + 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x74, 0x65, 0x41, 0x72, 0x67, + 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x74, 0x69, 0x61, 0x74, 0x65, 0x41, 0x72, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x43, 0x6f, + 0x6d, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x43, 0x6f, + 0x6d, 0x6d, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, + 0x44, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, + 0x0a, 0x08, 0x43, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x44, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x43, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x44, 0x22, 0x79, 0x0a, 0x15, 0x53, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, + 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x46, 0x69, 0x6c, 0x65, 0x22, 0xbe, 0x02, 0x0a, 0x13, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x48, 0x6f, 0x73, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, + 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x44, 0x4e, 0x53, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x44, 0x4e, 0x53, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x12, 0x33, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x54, + 0x72, 0x65, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, - 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, - 0x12, 0x4f, 0x0a, 0x10, 0x53, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, - 0x44, 0x75, 0x6d, 0x70, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, - 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x6f, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x00, 0x12, 0x55, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, - 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x22, 0x5f, 0x0a, 0x17, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x44, + 0x75, 0x6d, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x44, 0x75, 0x6d, 0x70, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x22, 0x6a, 0x0a, 0x16, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, + 0x70, 0x53, 0x74, 0x6f, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, + 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x44, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x44, 0x22, 0x2f, 0x0a, + 0x17, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x6f, + 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x7b, + 0x0a, 0x18, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x41, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, + 0x6d, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x52, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x67, 0x0a, 0x19, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x34, + 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x53, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, - 0x75, 0x6d, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x22, 0x00, 0x30, 0x01, 0x12, 0x59, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x75, - 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1f, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, - 0x58, 0x0a, 0x13, 0x53, 0x61, 0x76, 0x65, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x18, 0x5a, 0x16, 0x70, 0x6b, 0x67, - 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0x5d, 0x0a, 0x19, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, + 0x04, 0x44, 0x75, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x04, 0x44, 0x75, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x44, + 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, + 0x3f, 0x0a, 0x17, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x54, 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x54, 0x61, 0x67, + 0x22, 0x87, 0x01, 0x0a, 0x1b, 0x4c, 0x61, 0x73, 0x74, 0x41, 0x6e, 0x6f, 0x6d, 0x61, 0x6c, 0x79, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2c, 0x0a, 0x11, + 0x49, 0x73, 0x53, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x49, 0x73, 0x53, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x47, 0x0a, 0x0f, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x12, + 0x12, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x54, + 0x61, 0x67, 0x73, 0x22, 0xec, 0x01, 0x0a, 0x18, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x54, 0x72, 0x65, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x2c, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x73, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, + 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, + 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x44, 0x4e, 0x53, 0x4e, 0x6f, 0x64, + 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x44, + 0x4e, 0x53, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x10, + 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x4e, 0x6f, + 0x64, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x41, 0x70, 0x70, 0x72, + 0x6f, 0x78, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0f, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x53, 0x69, + 0x7a, 0x65, 0x22, 0x6e, 0x0a, 0x10, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, + 0x6e, 0x6f, 0x6d, 0x61, 0x6c, 0x79, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x41, 0x6e, 0x6f, 0x6d, 0x61, 0x6c, 0x79, 0x4e, 0x61, + 0x6e, 0x6f, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x22, 0x9b, 0x02, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, + 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x12, 0x58, 0x0a, 0x10, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0x58, 0x0a, 0x13, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0xa0, 0x06, 0x0a, 0x16, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x4c, + 0x6f, 0x61, 0x64, 0x65, 0x64, 0x49, 0x6e, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0e, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x49, 0x6e, 0x4b, 0x65, 0x72, + 0x6e, 0x65, 0x6c, 0x12, 0x38, 0x0a, 0x17, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x49, 0x6e, 0x4b, + 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x49, 0x6e, 0x4b, 0x65, + 0x72, 0x6e, 0x65, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x38, 0x0a, + 0x08, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x53, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0a, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x4a, 0x0a, + 0x0d, 0x4c, 0x61, 0x73, 0x74, 0x41, 0x6e, 0x6f, 0x6d, 0x61, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x41, + 0x6e, 0x6f, 0x6d, 0x61, 0x6c, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x4c, 0x61, 0x73, 0x74, + 0x41, 0x6e, 0x6f, 0x6d, 0x61, 0x6c, 0x69, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x09, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, + 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, + 0x01, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x07, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x07, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x04, 0x54, 0x61, 0x67, + 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x54, 0x61, 0x67, + 0x73, 0x12, 0x33, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x54, + 0x72, 0x65, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x12, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x47, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x5b, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x30, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x72, + 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x73, 0x1a, 0x5e, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x3f, 0x0a, 0x19, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x22, 0x6b, 0x0a, 0x1a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x22, 0x55, 0x0a, 0x19, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x38, + 0x0a, 0x08, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, + 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x46, 0x0a, 0x1a, 0x53, 0x65, 0x63, 0x75, + 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x61, 0x76, 0x65, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, + 0x46, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x46, 0x69, 0x6c, 0x65, + 0x32, 0x8a, 0x0a, 0x0a, 0x0e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x12, 0x3f, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x12, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, + 0x72, 0x69, 0x74, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x00, 0x30, 0x01, 0x12, 0x57, 0x0a, 0x10, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, + 0x75, 0x6d, 0x70, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, + 0x72, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x3f, 0x0a, + 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x30, + 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x1a, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x00, + 0x12, 0x4b, 0x0a, 0x0b, 0x52, 0x75, 0x6e, 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74, 0x12, + 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x75, 0x6e, 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65, 0x73, + 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, + 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x65, 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, + 0x10, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x53, + 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x22, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x53, 0x65, 0x74, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, + 0x6f, 0x61, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x14, 0x44, 0x75, 0x6d, 0x70, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x20, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x00, 0x12, 0x49, 0x0a, 0x0e, 0x44, 0x75, 0x6d, 0x70, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, + 0x64, 0x65, 0x72, 0x73, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x44, + 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x65, 0x72, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, + 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x75, 0x6d, 0x70, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, + 0x64, 0x65, 0x72, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, + 0x0c, 0x44, 0x75, 0x6d, 0x70, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x17, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x00, 0x12, 0x50, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x10, 0x53, 0x74, 0x6f, 0x70, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x6f, 0x70, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x6f, 0x70, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, + 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x15, + 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x44, 0x75, 0x6d, 0x70, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x59, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x13, 0x53, 0x61, 0x76, 0x65, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x53, 0x61, 0x76, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x53, 0x61, 0x76, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x18, 0x5a, + 0x16, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/security/proto/api/api.proto b/pkg/security/proto/api/api.proto index dc3e16fecb4b2..7032834f238c3 100644 --- a/pkg/security/proto/api/api.proto +++ b/pkg/security/proto/api/api.proto @@ -147,6 +147,7 @@ message ActivityDumpParams { bool DifferentiateArgs = 2; StorageRequestParams Storage = 3; string ContainerID = 4; + string CGroupID = 5; } message MetadataMessage { @@ -165,6 +166,7 @@ message MetadataMessage { string Timeout = 12; uint64 Size = 13; string Serialization = 14; + string CGroupID = 15; } message StorageRequestMessage { @@ -196,6 +198,7 @@ message ActivityDumpListMessage { message ActivityDumpStopParams { string Name = 1; string ContainerID = 2; + string CGroupID = 3; } message ActivityDumpStopMessage { diff --git a/pkg/security/proto/api/api_vtproto.pb.go b/pkg/security/proto/api/api_vtproto.pb.go index 462ad4782938c..8ebccda5994a0 100644 --- a/pkg/security/proto/api/api_vtproto.pb.go +++ b/pkg/security/proto/api/api_vtproto.pb.go @@ -1468,6 +1468,13 @@ func (m *ActivityDumpParams) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.CGroupID) > 0 { + i -= len(m.CGroupID) + copy(dAtA[i:], m.CGroupID) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.CGroupID))) + i-- + dAtA[i] = 0x2a + } if len(m.ContainerID) > 0 { i -= len(m.ContainerID) copy(dAtA[i:], m.ContainerID) @@ -1535,6 +1542,13 @@ func (m *MetadataMessage) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.CGroupID) > 0 { + i -= len(m.CGroupID) + copy(dAtA[i:], m.CGroupID) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.CGroupID))) + i-- + dAtA[i] = 0x7a + } if len(m.Serialization) > 0 { i -= len(m.Serialization) copy(dAtA[i:], m.Serialization) @@ -1927,6 +1941,13 @@ func (m *ActivityDumpStopParams) MarshalToSizedBufferVT(dAtA []byte) (int, error i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.CGroupID) > 0 { + i -= len(m.CGroupID) + copy(dAtA[i:], m.CGroupID) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.CGroupID))) + i-- + dAtA[i] = 0x1a + } if len(m.ContainerID) > 0 { i -= len(m.ContainerID) copy(dAtA[i:], m.ContainerID) @@ -3396,6 +3417,10 @@ func (m *ActivityDumpParams) SizeVT() (n int) { if l > 0 { n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + l = len(m.CGroupID) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -3460,6 +3485,10 @@ func (m *MetadataMessage) SizeVT() (n int) { if l > 0 { n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + l = len(m.CGroupID) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -3585,6 +3614,10 @@ func (m *ActivityDumpStopParams) SizeVT() (n int) { if l > 0 { n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + l = len(m.CGroupID) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -7212,6 +7245,38 @@ func (m *ActivityDumpParams) UnmarshalVT(dAtA []byte) error { } m.ContainerID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CGroupID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CGroupID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -7686,6 +7751,38 @@ func (m *MetadataMessage) UnmarshalVT(dAtA []byte) error { } m.Serialization = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CGroupID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CGroupID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -8485,6 +8582,38 @@ func (m *ActivityDumpStopParams) UnmarshalVT(dAtA []byte) error { } m.ContainerID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CGroupID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CGroupID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/pkg/security/resolvers/process/resolver_ebpf.go b/pkg/security/resolvers/process/resolver_ebpf.go index dc5694dd55647..5bcccdb52c540 100644 --- a/pkg/security/resolvers/process/resolver_ebpf.go +++ b/pkg/security/resolvers/process/resolver_ebpf.go @@ -852,7 +852,7 @@ func (p *EBPFResolver) resolveFromKernelMaps(pid, tid uint32, inode uint64, newE // is no insurance that the parent of this process is still running, we can't use our user space cache to check if // the parent is in a container. In other words, we have to fall back to /proc to query the container ID of the // process. - if entry.ContainerID == "" || entry.CGroup.CGroupFile.Inode == 0 { + if entry.CGroup.CGroupFile.Inode == 0 { if containerID, cgroup, err := p.containerResolver.GetContainerContext(pid); err == nil { entry.CGroup.Merge(&cgroup) entry.ContainerID = containerID diff --git a/pkg/security/resolvers/resolvers_ebpf.go b/pkg/security/resolvers/resolvers_ebpf.go index 91e1392502840..b8899bbd99adf 100644 --- a/pkg/security/resolvers/resolvers_ebpf.go +++ b/pkg/security/resolvers/resolvers_ebpf.go @@ -217,35 +217,25 @@ func (r *EBPFResolvers) Start(ctx context.Context) error { return r.NamespaceResolver.Start(ctx) } -// ResolveCGroup resolves the path of cgroup for a process cache entry -func (r *EBPFResolvers) ResolveCGroup(pce *model.ProcessCacheEntry, pathKey model.PathKey, cgroupFlags containerutils.CGroupFlags) error { +// ResolveCGroupContext resolves the cgroup context from a cgroup path key +func (r *EBPFResolvers) ResolveCGroupContext(pathKey model.PathKey, cgroupFlags containerutils.CGroupFlags) (*model.CGroupContext, error) { path, err := r.DentryResolver.Resolve(pathKey, true) - if err == nil && path != "" { - cgroup := filepath.Dir(string(path)) - if cgroup == "/" { - cgroup = path - } - - cgroupFlags := containerutils.CGroupFlags(cgroupFlags) - cgroupContext := model.CGroupContext{ - CGroupID: containerutils.CGroupID(cgroup), - CGroupFlags: containerutils.CGroupFlags(cgroupFlags), - CGroupFile: pathKey, - } + if err != nil { + return nil, fmt.Errorf("failed to resolve cgroup file %v: %w", pathKey, err) + } - pce.Process.CGroup = cgroupContext - pce.CGroup = cgroupContext + cgroup := filepath.Dir(string(path)) + if cgroup == "/" { + cgroup = path + } - if cgroupFlags.IsContainer() { - containerID, _ := containerutils.FindContainerID(cgroupContext.CGroupID) - pce.ContainerID = containerID - pce.Process.ContainerID = containerID - } - } else { - return fmt.Errorf("failed to resolve cgroup file %v: %w", pathKey, err) + cgroupContext := &model.CGroupContext{ + CGroupID: containerutils.CGroupID(cgroup), + CGroupFlags: containerutils.CGroupFlags(cgroupFlags), + CGroupFile: pathKey, } - return nil + return cgroupContext, nil } // Snapshot collects data on the current state of the system to populate user space and kernel space caches. diff --git a/pkg/security/secl/compiler/eval/eval_test.go b/pkg/security/secl/compiler/eval/eval_test.go index 0674e4ef744b1..6a217e8877444 100644 --- a/pkg/security/secl/compiler/eval/eval_test.go +++ b/pkg/security/secl/compiler/eval/eval_test.go @@ -1006,8 +1006,9 @@ func TestRegisterPartial(t *testing.T) { func TestOptimizer(t *testing.T) { event := &testEvent{ process: testProcess{ - uid: 44, - gid: 44, + uid: 44, + gid: 44, + name: "aaa", }, } @@ -1018,10 +1019,11 @@ func TestOptimizer(t *testing.T) { Expr string Evaluated func() bool }{ - {Expr: `process.list[A].key == 44 && process.gid == 55`, Evaluated: func() bool { return event.listEvaluated }}, + {Expr: `process.list.key == 44 && process.gid == 55`, Evaluated: func() bool { return event.listEvaluated }}, {Expr: `process.gid == 55 && process.list[A].key == 44`, Evaluated: func() bool { return event.listEvaluated }}, {Expr: `process.uid in [66, 77, 88] && process.gid == 55`, Evaluated: func() bool { return event.uidEvaluated }}, {Expr: `process.gid == 55 && process.uid in [66, 77, 88]`, Evaluated: func() bool { return event.uidEvaluated }}, + {Expr: `process.list.value == "AA" && process.name == "zzz"`, Evaluated: func() bool { return event.listEvaluated }}, } for _, test := range tests { diff --git a/pkg/security/secl/compiler/eval/operators.go b/pkg/security/secl/compiler/eval/operators.go index 9f39ff3e3550e..9fd97b9a98177 100644 --- a/pkg/security/secl/compiler/eval/operators.go +++ b/pkg/security/secl/compiler/eval/operators.go @@ -352,7 +352,6 @@ func StringEquals(a *StringEvaluator, b *StringEvaluator, state *State) (*BoolEv return &BoolEvaluator{ Value: op(ea, eb), - Weight: a.Weight + InArrayWeight*len(eb), isDeterministic: isDc, }, nil } @@ -366,7 +365,7 @@ func StringEquals(a *StringEvaluator, b *StringEvaluator, state *State) (*BoolEv return &BoolEvaluator{ EvalFnc: evalFnc, - Weight: a.Weight + InArrayWeight*len(eb), + Weight: a.Weight, isDeterministic: isDc, }, nil } diff --git a/pkg/security/secl/model/unmarshallers_linux.go b/pkg/security/secl/model/unmarshallers_linux.go index d6bdfb32fa825..7c38d3127e1ba 100644 --- a/pkg/security/secl/model/unmarshallers_linux.go +++ b/pkg/security/secl/model/unmarshallers_linux.go @@ -972,7 +972,7 @@ func (e *CgroupTracingEvent) UnmarshalBinary(data []byte) (int, error) { } cursor := read - read, err = UnmarshalBinary(data, &e.CGroupContext) + read, err = UnmarshalBinary(data[cursor:], &e.CGroupContext) if err != nil { return 0, err } diff --git a/pkg/security/security_profile/activity_tree/metadata/metadata.go b/pkg/security/security_profile/activity_tree/metadata/metadata.go index 2e9ea31a3da09..882e7fb69f5c0 100644 --- a/pkg/security/security_profile/activity_tree/metadata/metadata.go +++ b/pkg/security/security_profile/activity_tree/metadata/metadata.go @@ -8,7 +8,12 @@ // Package metadata holds metadata related files package metadata -import "time" +import ( + "time" + + "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" + "github.com/DataDog/datadog-agent/pkg/security/secl/model" +) // Metadata is used to provide context about the activity dump or the profile type Metadata struct { @@ -18,13 +23,13 @@ type Metadata struct { LinuxDistribution string `json:"linux_distribution"` Arch string `json:"arch"` - Name string `json:"name"` - ProtobufVersion string `json:"protobuf_version"` - DifferentiateArgs bool `json:"differentiate_args"` - ContainerID string `json:"-"` - ContainerFlags uint64 `json:"-"` - Start time.Time `json:"start"` - End time.Time `json:"end"` - Size uint64 `json:"activity_dump_size,omitempty"` - Serialization string `json:"serialization,omitempty"` + Name string `json:"name"` + ProtobufVersion string `json:"protobuf_version"` + DifferentiateArgs bool `json:"differentiate_args"` + ContainerID containerutils.ContainerID `json:"-"` + CGroupContext model.CGroupContext `json:"-"` + Start time.Time `json:"start"` + End time.Time `json:"end"` + Size uint64 `json:"activity_dump_size,omitempty"` + Serialization string `json:"serialization,omitempty"` } diff --git a/pkg/security/security_profile/activity_tree/metadata/metadata_proto_dec_v1.go b/pkg/security/security_profile/activity_tree/metadata/metadata_proto_dec_v1.go index 6f1f8ad0588f1..e08f483efac61 100644 --- a/pkg/security/security_profile/activity_tree/metadata/metadata_proto_dec_v1.go +++ b/pkg/security/security_profile/activity_tree/metadata/metadata_proto_dec_v1.go @@ -11,6 +11,7 @@ package metadata import ( adproto "github.com/DataDog/agent-payload/v5/cws/dumpsv1" + "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" activity_tree "github.com/DataDog/datadog-agent/pkg/security/security_profile/activity_tree" ) @@ -30,7 +31,7 @@ func ProtoMetadataToMetadata(meta *adproto.Metadata) Metadata { Name: meta.Name, ProtobufVersion: meta.ProtobufVersion, DifferentiateArgs: meta.DifferentiateArgs, - ContainerID: meta.ContainerId, + ContainerID: containerutils.ContainerID(meta.ContainerId), Start: activity_tree.ProtoDecodeTimestamp(meta.Start), End: activity_tree.ProtoDecodeTimestamp(meta.End), Size: meta.Size, diff --git a/pkg/security/security_profile/activity_tree/metadata/metadata_proto_enc_v1.go b/pkg/security/security_profile/activity_tree/metadata/metadata_proto_enc_v1.go index 2b02ef4004720..e28b2ce901c63 100644 --- a/pkg/security/security_profile/activity_tree/metadata/metadata_proto_enc_v1.go +++ b/pkg/security/security_profile/activity_tree/metadata/metadata_proto_enc_v1.go @@ -29,7 +29,7 @@ func ToProto(meta *Metadata) *adproto.Metadata { Name: meta.Name, ProtobufVersion: meta.ProtobufVersion, DifferentiateArgs: meta.DifferentiateArgs, - ContainerId: meta.ContainerID, + ContainerId: string(meta.ContainerID), Start: activity_tree.TimestampToProto(&meta.Start), End: activity_tree.TimestampToProto(&meta.End), Size: meta.Size, diff --git a/pkg/security/security_profile/dump/activity_dump.go b/pkg/security/security_profile/dump/activity_dump.go index 80d1bb2ebe011..4df6a218cebe3 100644 --- a/pkg/security/security_profile/dump/activity_dump.go +++ b/pkg/security/security_profile/dump/activity_dump.go @@ -222,11 +222,14 @@ func NewActivityDumpFromMessage(msg *api.ActivityDumpMessage) (*ActivityDump, er Name: metadata.GetName(), ProtobufVersion: metadata.GetProtobufVersion(), DifferentiateArgs: metadata.GetDifferentiateArgs(), - ContainerID: metadata.GetContainerID(), - Start: startTime, - End: startTime.Add(timeout), - Size: metadata.GetSize(), - Arch: metadata.GetArch(), + ContainerID: containerutils.ContainerID(metadata.GetContainerID()), + CGroupContext: model.CGroupContext{ + CGroupID: containerutils.CGroupID(metadata.GetCGroupID()), + }, + Start: startTime, + End: startTime.Add(timeout), + Size: metadata.GetSize(), + Arch: metadata.GetArch(), } ad.LoadConfig = NewActivityDumpLoadConfig( []model.EventType{}, @@ -265,14 +268,26 @@ func (ad *ActivityDump) GetWorkloadSelector() *cgroupModel.WorkloadSelector { if ad.selector != nil && ad.selector.IsReady() { return ad.selector } - imageTag := utils.GetTagValue("image_tag", ad.Tags) - selector, err := cgroupModel.NewWorkloadSelector(utils.GetTagValue("image_name", ad.Tags), imageTag) - if err != nil { - return nil + + var selector cgroupModel.WorkloadSelector + var err error + if ad.ContainerID != "" { + imageTag := utils.GetTagValue("image_tag", ad.Tags) + selector, err = cgroupModel.NewWorkloadSelector(utils.GetTagValue("image_name", ad.Tags), imageTag) + if err != nil { + return nil + } + } else if ad.CGroupContext.CGroupID != "" { + selector, err = cgroupModel.NewWorkloadSelector(utils.GetTagValue("service", ad.Tags), utils.GetTagValue("version", ad.Tags)) + if err != nil { + return nil + } + } + ad.selector = &selector - // Once per workload, when tags are resolved and the firs time we successfully get the selector, tag all the existing nodes - ad.ActivityTree.TagAllNodes(imageTag) + // Once per workload, when tags are resolved and the first time we successfully get the selector, tag all the existing nodes + ad.ActivityTree.TagAllNodes(selector.Image) return ad.selector } @@ -354,7 +369,7 @@ func (ad *ActivityDump) nameMatches(name string) bool { } // containerIDMatches returns true if the ActivityDump container ID matches the provided container ID -func (ad *ActivityDump) containerIDMatches(containerID string) bool { +func (ad *ActivityDump) containerIDMatches(containerID containerutils.ContainerID) bool { return ad.Metadata.ContainerID == containerID } @@ -365,7 +380,13 @@ func (ad *ActivityDump) MatchesSelector(entry *model.ProcessCacheEntry) bool { } if len(ad.Metadata.ContainerID) > 0 { - if !ad.containerIDMatches(string(entry.ContainerID)) { + if !ad.containerIDMatches(entry.ContainerID) { + return false + } + } + + if len(ad.Metadata.CGroupContext.CGroupID) > 0 { + if entry.CGroup.CGroupID != ad.Metadata.CGroupContext.CGroupID { return false } } @@ -395,13 +416,13 @@ func (ad *ActivityDump) enable() error { } } - if len(ad.Metadata.ContainerID) > 0 { + if !ad.Metadata.CGroupContext.CGroupFile.IsNull() { // insert container ID in traced_cgroups map (it might already exist, do not update in that case) - if err := ad.adm.tracedCgroupsMap.Update(ad.Metadata.ContainerID, ad.LoadConfigCookie, ebpf.UpdateNoExist); err != nil { + if err := ad.adm.tracedCgroupsMap.Update(ad.Metadata.CGroupContext.CGroupFile, ad.LoadConfigCookie, ebpf.UpdateNoExist); err != nil { if !errors.Is(err, ebpf.ErrKeyExist) { // delete activity dump load config _ = ad.adm.activityDumpsConfigMap.Delete(ad.LoadConfigCookie) - return fmt.Errorf("couldn't push activity dump container ID %s: %w", ad.Metadata.ContainerID, err) + return fmt.Errorf("couldn't push activity dump cgroup ID %s: %w", ad.Metadata.CGroupContext.CGroupID, err) } } } @@ -448,12 +469,10 @@ func (ad *ActivityDump) disable() error { } // remove container ID from kernel space - if len(ad.Metadata.ContainerID) > 0 { - containerIDB := make([]byte, model.ContainerIDLen) - copy(containerIDB, ad.Metadata.ContainerID) - err := ad.adm.tracedCgroupsMap.Delete(containerIDB) + if !ad.Metadata.CGroupContext.CGroupFile.IsNull() { + err := ad.adm.tracedCgroupsMap.Delete(ad.Metadata.CGroupContext.CGroupFile) if err != nil && !errors.Is(err, ebpf.ErrKeyNotExist) { - return fmt.Errorf("couldn't delete activity dump filter containerID(%s): %v", ad.Metadata.ContainerID, err) + return fmt.Errorf("couldn't delete activity dump filter cgroup %s: %v", ad.Metadata.CGroupContext.CGroupID, err) } } return nil @@ -575,6 +594,9 @@ func (ad *ActivityDump) getSelectorStr() string { if len(ad.Metadata.ContainerID) > 0 { tags = append(tags, fmt.Sprintf("container_id:%s", ad.Metadata.ContainerID)) } + if len(ad.Metadata.CGroupContext.CGroupID) > 0 { + tags = append(tags, fmt.Sprintf("cgroup_id:%s", ad.Metadata.CGroupContext.CGroupID)) + } if len(ad.Tags) > 0 { for _, tag := range ad.Tags { if !strings.HasPrefix(tag, "container_id") { @@ -614,6 +636,8 @@ func (ad *ActivityDump) ResolveTags() error { return ad.resolveTags() } +const systemdSystemDir = "/usr/lib/systemd/system" + // resolveTags thread unsafe version ot ResolveTags func (ad *ActivityDump) resolveTags() error { selector := ad.GetWorkloadSelector() @@ -621,10 +645,26 @@ func (ad *ActivityDump) resolveTags() error { return nil } - var err error - ad.Tags, err = ad.adm.resolvers.TagsResolver.ResolveWithErr(containerutils.ContainerID(ad.Metadata.ContainerID)) - if err != nil { - return fmt.Errorf("failed to resolve %s: %w", ad.Metadata.ContainerID, err) + if len(ad.Metadata.ContainerID) > 0 { + var err error + if ad.Tags, err = ad.adm.resolvers.TagsResolver.ResolveWithErr(containerutils.ContainerID(ad.Metadata.ContainerID)); err != nil { + return fmt.Errorf("failed to resolve %s: %w", ad.Metadata.ContainerID, err) + } + } else if len(ad.Metadata.CGroupContext.CGroupID) > 0 { + systemdService := filepath.Base(string(ad.Metadata.CGroupContext.CGroupID)) + serviceVersion := "" + servicePath := filepath.Join(systemdSystemDir, systemdService) + + if ad.adm.resolvers.SBOMResolver != nil { + if pkg := ad.adm.resolvers.SBOMResolver.ResolvePackage("", &model.FileEvent{PathnameStr: servicePath}); pkg != nil { + serviceVersion = pkg.Version + } + } + + ad.Tags = []string{ + "service:" + systemdService, + "version:" + serviceVersion, + } } return nil @@ -655,7 +695,8 @@ func (ad *ActivityDump) ToSecurityActivityDumpMessage() *api.ActivityDumpMessage Name: ad.Metadata.Name, ProtobufVersion: ad.Metadata.ProtobufVersion, DifferentiateArgs: ad.Metadata.DifferentiateArgs, - ContainerID: ad.Metadata.ContainerID, + ContainerID: string(ad.Metadata.ContainerID), + CGroupID: string(ad.Metadata.CGroupContext.CGroupID), Start: ad.Metadata.Start.Format(time.RFC822), Timeout: ad.LoadConfig.Timeout.String(), Size: ad.Metadata.Size, diff --git a/pkg/security/security_profile/dump/load_controller.go b/pkg/security/security_profile/dump/load_controller.go index 3d0148f168232..ae8767bcfd153 100644 --- a/pkg/security/security_profile/dump/load_controller.go +++ b/pkg/security/security_profile/dump/load_controller.go @@ -85,6 +85,7 @@ func (lc *ActivityDumpLoadController) PushCurrentConfig() error { func (lc *ActivityDumpLoadController) NextPartialDump(ad *ActivityDump) *ActivityDump { newDump := NewActivityDump(ad.adm) newDump.Metadata.ContainerID = ad.Metadata.ContainerID + newDump.Metadata.CGroupContext = ad.Metadata.CGroupContext newDump.Metadata.DifferentiateArgs = ad.Metadata.DifferentiateArgs newDump.Tags = ad.Tags newDump.selector = ad.selector diff --git a/pkg/security/security_profile/dump/manager.go b/pkg/security/security_profile/dump/manager.go index b37a2c7264f1a..079f45c13bc21 100644 --- a/pkg/security/security_profile/dump/manager.go +++ b/pkg/security/security_profile/dump/manager.go @@ -35,6 +35,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/resolvers" cgroupModel "github.com/DataDog/datadog-agent/pkg/security/resolvers/cgroup/model" "github.com/DataDog/datadog-agent/pkg/security/resolvers/tags" + "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" "github.com/DataDog/datadog-agent/pkg/security/secl/model" "github.com/DataDog/datadog-agent/pkg/security/seclog" activity_tree "github.com/DataDog/datadog-agent/pkg/security/security_profile/activity_tree" @@ -70,7 +71,7 @@ type ActivityDumpManager struct { tracedCgroupsMap *ebpf.Map cgroupWaitList *ebpf.Map activityDumpsConfigMap *ebpf.Map - ignoreFromSnapshot map[string]bool + ignoreFromSnapshot map[model.PathKey]bool dumpLimiter *lru.Cache[cgroupModel.WorkloadSelector, *atomic.Uint64] workloadDenyList []cgroupModel.WorkloadSelector @@ -148,13 +149,13 @@ func (adm *ActivityDumpManager) cleanup() { // cleanup cgroup_wait_list map iterator := adm.cgroupWaitList.Iterate() - containerIDB := make([]byte, model.ContainerIDLen) + cgroupFile := make([]byte, model.PathKeySize) var timestamp uint64 - for iterator.Next(&containerIDB, ×tamp) { + for iterator.Next(&cgroupFile, ×tamp) { if time.Now().After(adm.resolvers.TimeResolver.ResolveMonotonicTimestamp(timestamp)) { - if err := adm.cgroupWaitList.Delete(&containerIDB); err != nil { - seclog.Errorf("couldn't delete cgroup_wait_list entry for (%s): %v", string(containerIDB), err) + if err := adm.cgroupWaitList.Delete(&cgroupFile); err != nil { + seclog.Errorf("couldn't delete cgroup_wait_list entry for (%v): %v", cgroupFile, err) } } } @@ -170,7 +171,7 @@ func (adm *ActivityDumpManager) getExpiredDumps() []*ActivityDump { for _, ad := range adm.activeDumps { if time.Now().After(ad.Metadata.End) || ad.state == Stopped { expiredDumps = append(expiredDumps, ad) - delete(adm.ignoreFromSnapshot, ad.Metadata.ContainerID) + delete(adm.ignoreFromSnapshot, ad.Metadata.CGroupContext.CGroupFile) } else { newDumps = append(newDumps, ad) } @@ -304,7 +305,7 @@ func NewActivityDumpManager(config *config.Config, statsdClient statsd.ClientInt cgroupWaitList: cgroupWaitList, activityDumpsConfigMap: activityDumpsConfigMap, snapshotQueue: make(chan *ActivityDump, 100), - ignoreFromSnapshot: make(map[string]bool), + ignoreFromSnapshot: make(map[model.PathKey]bool), dumpLimiter: limiter, workloadDenyList: denyList, workloadDenyListHits: atomic.NewUint64(0), @@ -360,19 +361,35 @@ func (adm *ActivityDumpManager) insertActivityDump(newDump *ActivityDump) error for _, ad := range adm.activeDumps { if ad.Metadata.ContainerID == newDump.Metadata.ContainerID { // an activity dump is already active for this container ID, ignore - return nil + return fmt.Errorf("dump for container %s already running", ad.Metadata.ContainerID) } } } - // enable the new dump to start collecting events from kernel space - if err := newDump.enable(); err != nil { - return fmt.Errorf("couldn't insert new dump: %w", err) + if len(newDump.Metadata.CGroupContext.CGroupID) > 0 { + // check if the provided container ID is new + for _, ad := range adm.activeDumps { + if ad.Metadata.CGroupContext.CGroupID == newDump.Metadata.CGroupContext.CGroupID { + // an activity dump is already active for this container ID, ignore + return fmt.Errorf("dump for cgroup %s already running", ad.Metadata.CGroupContext.CGroupID) + } + } } // loop through the process cache entry tree and push traced pids if necessary pces := adm.newProcessCacheEntrySearcher(newDump) - adm.resolvers.ProcessResolver.Walk(pces.SearchTracedProcessCacheEntry) + adm.resolvers.ProcessResolver.Walk(func(entry *model.ProcessCacheEntry) { + if !pces.ad.MatchesSelector(entry) { + return + } + pces.ad.Metadata.CGroupContext = entry.CGroup + pces.SearchTracedProcessCacheEntry(entry) + }) + + // enable the new dump to start collecting events from kernel space + if err := newDump.enable(); err != nil { + return fmt.Errorf("couldn't insert new dump: %w", err) + } // Delay the activity dump snapshot to reduce the overhead on the main goroutine select { @@ -391,10 +408,10 @@ func (adm *ActivityDumpManager) insertActivityDump(newDump *ActivityDump) error } // handleDefaultDumpRequest starts dumping a new workload with the provided load configuration and the default dump configuration -func (adm *ActivityDumpManager) startDumpWithConfig(containerID string, containerFlags, cookie uint64, loadConfig model.ActivityDumpLoadConfig) error { +func (adm *ActivityDumpManager) startDumpWithConfig(containerID containerutils.ContainerID, cgroupContext model.CGroupContext, cookie uint64, loadConfig model.ActivityDumpLoadConfig) error { newDump := NewActivityDump(adm, func(ad *ActivityDump) { ad.Metadata.ContainerID = containerID - ad.Metadata.ContainerFlags = containerFlags + ad.Metadata.CGroupContext = cgroupContext ad.SetLoadConfig(cookie, loadConfig) if adm.config.RuntimeSecurity.ActivityDumpCgroupDifferentiateArgs { @@ -437,7 +454,7 @@ func (adm *ActivityDumpManager) HandleCGroupTracingEvent(event *model.CgroupTrac return } - if err := adm.startDumpWithConfig(string(event.ContainerContext.ContainerID), uint64(event.CGroupContext.CGroupFlags), event.ConfigCookie, event.Config); err != nil { + if err := adm.startDumpWithConfig(event.ContainerContext.ContainerID, event.CGroupContext, event.ConfigCookie, event.Config); err != nil { seclog.Warnf("%v", err) } } @@ -497,7 +514,7 @@ workloadLoop: } // if we're still here, we can start tracing this workload - if err := adm.startDumpWithConfig(string(workloads[0].ContainerID), uint64(workloads[0].CGroupFlags), utils.NewCookie(), *adm.loadController.getDefaultLoadConfig()); err != nil { + if err := adm.startDumpWithConfig(workloads[0].ContainerID, workloads[0].CGroupContext, utils.NewCookie(), *adm.loadController.getDefaultLoadConfig()); err != nil { if !errors.Is(err, unix.E2BIG) { seclog.Debugf("%v", err) break @@ -523,12 +540,32 @@ func (adm *ActivityDumpManager) ListActivityDumps(_ *api.ActivityDumpListParams) // DumpActivity handles an activity dump request func (adm *ActivityDumpManager) DumpActivity(params *api.ActivityDumpParams) (*api.ActivityDumpMessage, error) { + if params.GetContainerID() == "" && params.GetCGroupID() == "" { + errMsg := fmt.Errorf("you must specify one selector between containerID and cgroupID") + return &api.ActivityDumpMessage{Error: errMsg.Error()}, errMsg + } + adm.Lock() defer adm.Unlock() + var dumpDuration time.Duration + var err error + if params.Timeout != "" { + if dumpDuration, err = time.ParseDuration(params.Timeout); err != nil { + return nil, err + } + } else { + dumpDuration = adm.config.RuntimeSecurity.ActivityDumpCgroupDumpTimeout + } + + if params.Storage.LocalStorageDirectory == "" { + params.Storage.LocalStorageDirectory = adm.config.RuntimeSecurity.ActivityDumpLocalStorageDirectory + } + newDump := NewActivityDump(adm, func(ad *ActivityDump) { - ad.Metadata.ContainerID = params.GetContainerID() - dumpDuration, _ := time.ParseDuration(params.Timeout) + ad.Metadata.ContainerID = containerutils.ContainerID(params.GetContainerID()) + ad.Metadata.CGroupContext.CGroupID = containerutils.CGroupID(params.GetCGroupID()) + ad.SetTimeout(dumpDuration) if params.GetDifferentiateArgs() { @@ -560,15 +597,16 @@ func (adm *ActivityDumpManager) StopActivityDump(params *api.ActivityDumpStopPar adm.Lock() defer adm.Unlock() - if params.GetName() == "" && params.GetContainerID() == "" { - errMsg := fmt.Errorf("you must specify one selector between name and containerID") + if params.GetName() == "" && params.GetContainerID() == "" && params.GetCGroupID() == "" { + errMsg := fmt.Errorf("you must specify one selector between name, containerID and cgroupID") return &api.ActivityDumpStopMessage{Error: errMsg.Error()}, errMsg } toDelete := -1 for i, d := range adm.activeDumps { if (params.GetName() != "" && d.nameMatches(params.GetName())) || - (params.GetContainerID() != "" && d.containerIDMatches(params.GetContainerID())) { + (params.GetContainerID() != "" && d.containerIDMatches(containerutils.ContainerID(params.GetContainerID())) || + (params.GetCGroupID() != "" && string(d.Metadata.CGroupContext.CGroupID) == params.GetCGroupID())) { d.Finalize(true) seclog.Infof("tracing stopped for [%s]", d.GetSelectorStr()) toDelete = i @@ -593,8 +631,10 @@ func (adm *ActivityDumpManager) StopActivityDump(params *api.ActivityDumpStopPar var errMsg error if params.GetName() != "" { errMsg = fmt.Errorf("the activity dump manager does not contain any ActivityDump with the following name: %s", params.GetName()) - } else /* if params.GetContainerID() != "" */ { + } else if params.GetContainerID() != "" { errMsg = fmt.Errorf("the activity dump manager does not contain any ActivityDump with the following containerID: %s", params.GetContainerID()) + } else /* if params.GetCGroupID() != "" */ { + errMsg = fmt.Errorf("the activity dump manager does not contain any ActivityDump with the following cgroup ID: %s", params.GetCGroupID()) } return &api.ActivityDumpStopMessage{Error: errMsg.Error()}, errMsg } @@ -786,13 +826,14 @@ func (adm *ActivityDumpManager) SendStats() error { func (adm *ActivityDumpManager) SnapshotTracedCgroups() { var err error var event model.CgroupTracingEvent - containerIDB := make([]byte, model.ContainerIDLen) + var cgroupFile model.PathKey + iterator := adm.tracedCgroupsMap.Iterate() seclog.Infof("snapshotting traced_cgroups map") - for iterator.Next(&containerIDB, &event.ConfigCookie) { + for iterator.Next(&cgroupFile, &event.ConfigCookie) { adm.Lock() - if adm.ignoreFromSnapshot[string(containerIDB)] { + if adm.ignoreFromSnapshot[cgroupFile] { adm.Unlock() continue } @@ -800,15 +841,8 @@ func (adm *ActivityDumpManager) SnapshotTracedCgroups() { if err = adm.activityDumpsConfigMap.Lookup(&event.ConfigCookie, &event.Config); err != nil { // this config doesn't exist anymore, remove expired entries - seclog.Errorf("config not found for (%s): %v", string(containerIDB), err) - _ = adm.tracedCgroupsMap.Delete(containerIDB) - continue - } - - if _, err = event.ContainerContext.UnmarshalBinary(containerIDB[:]); err != nil { - seclog.Errorf("couldn't unmarshal container ID from traced_cgroups key: %v", err) - // remove invalid entry - _ = adm.tracedCgroupsMap.Delete(containerIDB) + seclog.Errorf("config not found for (%v): %v", cgroupFile, err) + _ = adm.tracedCgroupsMap.Delete(cgroupFile) continue } @@ -879,7 +913,7 @@ func (adm *ActivityDumpManager) triggerLoadController() { } // remove container ID from the map of ignored container IDs for the snapshot - delete(adm.ignoreFromSnapshot, ad.Metadata.ContainerID) + delete(adm.ignoreFromSnapshot, ad.Metadata.CGroupContext.CGroupFile) adm.Unlock() } } @@ -902,7 +936,7 @@ func (adm *ActivityDumpManager) getOverweightDumps() []*ActivityDump { if dumpSize >= int64(adm.config.RuntimeSecurity.ActivityDumpMaxDumpSize()) { toDelete = append([]int{i}, toDelete...) dumps = append(dumps, ad) - adm.ignoreFromSnapshot[ad.Metadata.ContainerID] = true + adm.ignoreFromSnapshot[ad.Metadata.CGroupContext.CGroupFile] = true } } for _, i := range toDelete { diff --git a/pkg/security/security_profile/dump/manager_test.go b/pkg/security/security_profile/dump/manager_test.go index f16d599230fd6..d7075b4d62f42 100644 --- a/pkg/security/security_profile/dump/manager_test.go +++ b/pkg/security/security_profile/dump/manager_test.go @@ -17,6 +17,7 @@ import ( "github.com/DataDog/datadog-go/v5/statsd" "github.com/DataDog/datadog-agent/pkg/security/config" + "github.com/DataDog/datadog-agent/pkg/security/secl/model" activity_tree "github.com/DataDog/datadog-agent/pkg/security/security_profile/activity_tree" mtdt "github.com/DataDog/datadog-agent/pkg/security/security_profile/activity_tree/metadata" ) @@ -197,7 +198,7 @@ func TestActivityDumpManager_getExpiredDumps(t *testing.T) { adm := &ActivityDumpManager{ activeDumps: tt.fields.activeDumps, - ignoreFromSnapshot: make(map[string]bool), + ignoreFromSnapshot: make(map[model.PathKey]bool), } expiredDumps := adm.getExpiredDumps() @@ -474,7 +475,7 @@ func TestActivityDumpManager_getOverweightDumps(t *testing.T) { }, }, statsdClient: &statsd.NoOpClient{}, - ignoreFromSnapshot: make(map[string]bool), + ignoreFromSnapshot: make(map[model.PathKey]bool), } compareListOfDumps(t, adm.getOverweightDumps(), tt.overweightDumps) diff --git a/pkg/security/security_profile/tests/activity_tree_test.go b/pkg/security/security_profile/tests/activity_tree_test.go index a814932f385fd..7f100d75c18d1 100644 --- a/pkg/security/security_profile/tests/activity_tree_test.go +++ b/pkg/security/security_profile/tests/activity_tree_test.go @@ -687,7 +687,7 @@ func TestActivityTree_CreateProcessNode(t *testing.T) { if tt == dumpTree { dump := dump.NewEmptyActivityDump(nil) - dump.Metadata.ContainerID = contID + dump.Metadata.ContainerID = containerutils.ContainerID(contID) at = dump.ActivityTree } else /* profileTree */ { profile := profile.NewSecurityProfile(cgroupModel.WorkloadSelector{Image: "image", Tag: "tag"}, []model.EventType{model.ExecEventType, model.DNSEventType}, nil) diff --git a/pkg/security/tests/activity_dumps_test.go b/pkg/security/tests/activity_dumps_test.go index 0046251a969bd..07189c9a8d2ba 100644 --- a/pkg/security/tests/activity_dumps_test.go +++ b/pkg/security/tests/activity_dumps_test.go @@ -93,7 +93,7 @@ func TestActivityDumps(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -134,7 +134,7 @@ func TestActivityDumps(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -211,7 +211,7 @@ func TestActivityDumps(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -256,7 +256,7 @@ func TestActivityDumps(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -295,7 +295,7 @@ func TestActivityDumps(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -338,7 +338,7 @@ func TestActivityDumps(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -394,7 +394,7 @@ func TestActivityDumps(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } diff --git a/pkg/security/tests/cmdwrapper.go b/pkg/security/tests/cmdwrapper.go index 1d25a6b4a7664..ca91fb42dd9ec 100644 --- a/pkg/security/tests/cmdwrapper.go +++ b/pkg/security/tests/cmdwrapper.go @@ -11,6 +11,7 @@ package tests import ( "fmt" "os/exec" + "strconv" "strings" "testing" @@ -78,8 +79,10 @@ type dockerCmdWrapper struct { executable string mountSrc string mountDest string + pid int64 containerName string containerID string + cgroupID string image string } @@ -101,9 +104,24 @@ func (d *dockerCmdWrapper) start() ([]byte, error) { d.containerName = fmt.Sprintf("docker-wrapper-%s", utils.RandString(6)) cmd := exec.Command(d.executable, "run", "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined", "--rm", "--cap-add", "NET_ADMIN", "-d", "--name", d.containerName, "-v", d.mountSrc+":"+d.mountDest, d.image, "sleep", "1200") out, err := cmd.CombinedOutput() - if err == nil { - d.containerID = strings.TrimSpace(string(out)) + if err != nil { + return nil, err + } + + d.containerID = strings.TrimSpace(string(out)) + + cmd = exec.Command(d.executable, "inspect", "--format", "{{ .State.Pid }}", d.containerID) + out, err = cmd.CombinedOutput() + if err != nil { + return nil, err + } + + d.pid, _ = strconv.ParseInt(strings.TrimSpace(string(out)), 10, 64) + + if d.cgroupID, err = getPIDCGroup(uint32(d.pid)); err != nil { + return nil, err } + return out, err } diff --git a/pkg/security/tests/main_linux.go b/pkg/security/tests/main_linux.go index c64b83fbc917d..bea7537bf4f91 100644 --- a/pkg/security/tests/main_linux.go +++ b/pkg/security/tests/main_linux.go @@ -129,6 +129,20 @@ func SkipIfNotAvailable(t *testing.T) { } } +// getPIDCGroup returns the path of the first cgroup found for a PID +func getPIDCGroup(pid uint32) (string, error) { + cgroups, err := utils.GetProcControlGroups(pid, pid) + if err != nil { + return "", err + } + + if len(cgroups) == 0 { + return "", fmt.Errorf("failed to find cgroup for pid %d", pid) + } + + return cgroups[0].Path, nil +} + func preTestsHook() { if trace { args := slices.DeleteFunc(os.Args, func(arg string) bool { diff --git a/pkg/security/tests/main_windows.go b/pkg/security/tests/main_windows.go index 945126ae6c59c..4cc1f88754218 100644 --- a/pkg/security/tests/main_windows.go +++ b/pkg/security/tests/main_windows.go @@ -8,6 +8,13 @@ // Package tests holds tests related files package tests +import "errors" + +// getPIDCGroup returns the path of the first cgroup found for a PID +func getPIDCGroup(pid uint32) (string, error) { + return "", errors.New("cgroups are not supported on Windows") +} + func preTestsHook() {} func postTestsHook() {} diff --git a/pkg/security/tests/module_tester_linux.go b/pkg/security/tests/module_tester_linux.go index 54d262fdf599d..37a54cf6fee5b 100644 --- a/pkg/security/tests/module_tester_linux.go +++ b/pkg/security/tests/module_tester_linux.go @@ -43,6 +43,7 @@ import ( cgroupModel "github.com/DataDog/datadog-agent/pkg/security/resolvers/cgroup/model" rulesmodule "github.com/DataDog/datadog-agent/pkg/security/rules" "github.com/DataDog/datadog-agent/pkg/security/rules/bundled" + "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" "github.com/DataDog/datadog-agent/pkg/security/secl/model" "github.com/DataDog/datadog-agent/pkg/security/secl/rules" activity_tree "github.com/DataDog/datadog-agent/pkg/security/security_profile/activity_tree" @@ -1124,7 +1125,7 @@ func checkNetworkCompatibility(tb testing.TB) { }) } -func (tm *testModule) StopActivityDump(name, containerID string) error { +func (tm *testModule) StopActivityDump(name string) error { p, ok := tm.probe.PlatformProbe.(*sprobe.EBPFProbe) if !ok { return errors.New("not supported") @@ -1135,8 +1136,7 @@ func (tm *testModule) StopActivityDump(name, containerID string) error { return errors.New("no manager") } params := &api.ActivityDumpStopParams{ - Name: name, - ContainerID: containerID, + Name: name, } _, err := managers.StopActivityDump(params) if err != nil { @@ -1147,7 +1147,8 @@ func (tm *testModule) StopActivityDump(name, containerID string) error { type activityDumpIdentifier struct { Name string - ContainerID string + ContainerID containerutils.ContainerID + CGroupID containerutils.CGroupID Timeout string OutputFiles []string } @@ -1182,7 +1183,8 @@ func (tm *testModule) ListActivityDumps() ([]*activityDumpIdentifier, error) { dumps = append(dumps, &activityDumpIdentifier{ Name: dump.Metadata.Name, - ContainerID: dump.Metadata.ContainerID, + ContainerID: containerutils.ContainerID(dump.Metadata.ContainerID), + CGroupID: containerutils.CGroupID(dump.Metadata.CGroupID), Timeout: dump.Metadata.Timeout, OutputFiles: files, }) @@ -1252,6 +1254,7 @@ func (tm *testModule) StartADocker() (*dockerCmdWrapper, error) { } time.Sleep(1 * time.Second) // a quick sleep to ensure the dump has started + return docker, nil } @@ -1260,7 +1263,7 @@ func (tm *testModule) GetDumpFromDocker(dockerInstance *dockerCmdWrapper) (*acti if err != nil { return nil, err } - dump := findLearningContainerID(dumps, dockerInstance.containerID) + dump := findLearningContainerID(dumps, containerutils.ContainerID(dockerInstance.containerID)) if dump == nil { return nil, errors.New("ContainerID not found on activity dump list") } @@ -1281,7 +1284,7 @@ func (tm *testModule) StartADockerGetDump() (*dockerCmdWrapper, *activityDumpIde } //nolint:deadcode,unused -func findLearningContainerID(dumps []*activityDumpIdentifier, containerID string) *activityDumpIdentifier { +func findLearningContainerID(dumps []*activityDumpIdentifier, containerID containerutils.ContainerID) *activityDumpIdentifier { for _, dump := range dumps { if dump.ContainerID == containerID { return dump @@ -1538,7 +1541,7 @@ func (tm *testModule) StopAllActivityDumps() error { return nil } for _, dump := range dumps { - _ = tm.StopActivityDump(dump.Name, "") + _ = tm.StopActivityDump(dump.Name) } dumps, err = tm.ListActivityDumps() if err != nil { diff --git a/pkg/security/tests/security_profile_test.go b/pkg/security/tests/security_profile_test.go index 1c814ea196f5c..01faf63d61ed5 100644 --- a/pkg/security/tests/security_profile_test.go +++ b/pkg/security/tests/security_profile_test.go @@ -87,7 +87,7 @@ func TestSecurityProfile(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -97,7 +97,8 @@ func TestSecurityProfile(t *testing.T) { if sp.Metadata.Name != dump.Name { t.Errorf("Profile name %s != %s\n", sp.Metadata.Name, dump.Name) } - if sp.Metadata.ContainerID != dump.ContainerID { + if (sp.Metadata.ContainerID != dump.ContainerID) && + (sp.Metadata.CGroupContext.CGroupID != dump.CGroupID) { t.Errorf("Profile containerID %s != %s\n", sp.Metadata.ContainerID, dump.ContainerID) } @@ -105,7 +106,7 @@ func TestSecurityProfile(t *testing.T) { if ctx == nil { t.Errorf("No profile context found!") } else { - if !slices.Contains(ctx.Tags, "container_id:"+dump.ContainerID) { + if !slices.Contains(ctx.Tags, "container_id:"+string(dump.ContainerID)) { t.Errorf("Profile did not contains container_id tag: %v\n", ctx.Tags) } if !slices.Contains(ctx.Tags, "image_tag:latest") { @@ -140,7 +141,7 @@ func TestSecurityProfile(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -179,7 +180,7 @@ func TestSecurityProfile(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -267,7 +268,7 @@ func TestAnomalyDetection(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -299,7 +300,7 @@ func TestAnomalyDetection(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -332,7 +333,7 @@ func TestAnomalyDetection(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -368,7 +369,7 @@ func TestAnomalyDetection(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -443,7 +444,7 @@ func TestAnomalyDetectionWarmup(t *testing.T) { cmd.CombinedOutput() time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -605,7 +606,7 @@ func TestSecurityProfileReinsertionPeriod(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -639,7 +640,7 @@ func TestSecurityProfileReinsertionPeriod(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -669,7 +670,7 @@ func TestSecurityProfileReinsertionPeriod(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -706,7 +707,7 @@ func TestSecurityProfileReinsertionPeriod(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -840,7 +841,7 @@ func TestSecurityProfileAutoSuppression(t *testing.T) { } }) - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -981,7 +982,7 @@ func TestSecurityProfileDifferentiateArgs(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -1078,7 +1079,7 @@ func TestSecurityProfileLifeCycleExecs(t *testing.T) { t.Fatal(err) } - dockerInstanceV1, err := test.StartADocker() + dockerInstanceV1, dump, err := test.StartADockerGetDump() if err != nil { t.Fatal(err) } @@ -1091,7 +1092,7 @@ func TestSecurityProfileLifeCycleExecs(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump("", dockerInstanceV1.containerID) + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -1252,7 +1253,7 @@ func TestSecurityProfileLifeCycleDNS(t *testing.T) { t.Fatal(err) } - dockerInstanceV1, err := test.StartADocker() + dockerInstanceV1, dump, err := test.StartADockerGetDump() if err != nil { t.Fatal(err) } @@ -1265,7 +1266,7 @@ func TestSecurityProfileLifeCycleDNS(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump("", dockerInstanceV1.containerID) + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -1425,7 +1426,7 @@ func TestSecurityProfileLifeCycleSyscall(t *testing.T) { t.Fatal(err) } - dockerInstanceV1, err := test.StartADocker() + dockerInstanceV1, dump, err := test.StartADockerGetDump() if err != nil { t.Fatal(err) } @@ -1438,7 +1439,7 @@ func TestSecurityProfileLifeCycleSyscall(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events be added to the dump - err = test.StopActivityDump("", dockerInstanceV1.containerID) + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -1614,7 +1615,7 @@ func TestSecurityProfileLifeCycleEvictionProcess(t *testing.T) { t.Fatal(err) } - dockerInstanceV1, err := test.StartADocker() + dockerInstanceV1, dump, err := test.StartADockerGetDump() if err != nil { t.Fatal(err) } @@ -1627,7 +1628,7 @@ func TestSecurityProfileLifeCycleEvictionProcess(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump("", dockerInstanceV1.containerID) + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -1792,7 +1793,7 @@ func TestSecurityProfileLifeCycleEvictionDNS(t *testing.T) { t.Fatal(err) } - dockerInstanceV1, err := test.StartADocker() + dockerInstanceV1, dump, err := test.StartADockerGetDump() if err != nil { t.Fatal(err) } @@ -1805,7 +1806,7 @@ func TestSecurityProfileLifeCycleEvictionDNS(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump("", dockerInstanceV1.containerID) + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -1970,7 +1971,7 @@ func TestSecurityProfileLifeCycleEvictionProcessUnstable(t *testing.T) { t.Fatal(err) } - dockerInstanceV1, err := test.StartADocker() + dockerInstanceV1, dump, err := test.StartADockerGetDump() if err != nil { t.Fatal(err) } @@ -1983,7 +1984,7 @@ func TestSecurityProfileLifeCycleEvictionProcessUnstable(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump("", dockerInstanceV1.containerID) + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -2148,13 +2149,13 @@ func TestSecurityProfilePersistence(t *testing.T) { } defer test.Close() - dockerInstance1, err := test.StartADocker() + dockerInstance1, dump, err := test.StartADockerGetDump() if err != nil { t.Fatal(err) } defer dockerInstance1.stop() - err = test.StopActivityDump("", dockerInstance1.containerID) + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } diff --git a/pkg/security/tests/threat_score_test.go b/pkg/security/tests/threat_score_test.go index 2256847bc5f86..13d11ddc52451 100644 --- a/pkg/security/tests/threat_score_test.go +++ b/pkg/security/tests/threat_score_test.go @@ -100,7 +100,7 @@ func TestActivityDumpsThreatScore(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -150,7 +150,7 @@ func TestActivityDumpsThreatScore(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -191,7 +191,7 @@ func TestActivityDumpsThreatScore(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } @@ -236,7 +236,7 @@ func TestActivityDumpsThreatScore(t *testing.T) { } time.Sleep(1 * time.Second) // a quick sleep to let events to be added to the dump - err = test.StopActivityDump(dump.Name, "") + err = test.StopActivityDump(dump.Name) if err != nil { t.Fatal(err) } diff --git a/pkg/security/utils/cgroup.go b/pkg/security/utils/cgroup.go index b4a3de192d7de..5dbbb97c58af1 100644 --- a/pkg/security/utils/cgroup.go +++ b/pkg/security/utils/cgroup.go @@ -90,9 +90,10 @@ func GetProcContainerContext(tgid, pid uint32) (containerutils.ContainerID, mode return "", model.CGroupContext{}, err } - containerID, runtime := cgroups[0].GetContainerContext() + lastCgroup := len(cgroups) - 1 + containerID, runtime := cgroups[lastCgroup].GetContainerContext() cgroupContext := model.CGroupContext{ - CGroupID: containerutils.CGroupID(cgroups[0].Path), + CGroupID: containerutils.CGroupID(cgroups[lastCgroup].Path), CGroupFlags: runtime, } diff --git a/pkg/serializer/go.mod b/pkg/serializer/go.mod index 62d3ab7c2450c..ef22edcd67b2d 100644 --- a/pkg/serializer/go.mod +++ b/pkg/serializer/go.mod @@ -140,7 +140,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/klauspost/compress v1.17.11 // indirect diff --git a/pkg/serializer/go.sum b/pkg/serializer/go.sum index 240d357b106d4..0e4568db35dfe 100644 --- a/pkg/serializer/go.sum +++ b/pkg/serializer/go.sum @@ -118,8 +118,8 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/trace/api/api_test.go b/pkg/trace/api/api_test.go index 9a468dc164487..3f3b2c5b3a20b 100644 --- a/pkg/trace/api/api_test.go +++ b/pkg/trace/api/api_test.go @@ -1039,14 +1039,26 @@ func TestExpvar(t *testing.T) { } c := newTestReceiverConfig() - c.DebugServerPort = 5012 + c.DebugServerPort = 6789 info.InitInfo(c) + + // Starting a TLS httptest server to retrieve tlsCert + ts := httptest.NewTLSServer(http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {})) + tlsConfig := ts.TLS.Clone() + // Setting a client with the proper TLS configuration + client := ts.Client() + ts.Close() + + // Starting Debug Server s := NewDebugServer(c) + s.SetTLSConfig(tlsConfig) + + // Starting the Debug server s.Start() defer s.Stop() - resp, err := http.Get("http://127.0.0.1:5012/debug/vars") - assert.NoError(t, err) + resp, err := client.Get(fmt.Sprintf("https://127.0.0.1:%d/debug/vars", c.DebugServerPort)) + require.NoError(t, err) defer resp.Body.Close() t.Run("read-expvars", func(t *testing.T) { diff --git a/pkg/trace/api/debug_server.go b/pkg/trace/api/debug_server.go index 828d5357330eb..6fd2f39cc011a 100644 --- a/pkg/trace/api/debug_server.go +++ b/pkg/trace/api/debug_server.go @@ -9,6 +9,7 @@ package api import ( "context" + "crypto/tls" "expvar" "fmt" "net" @@ -29,9 +30,10 @@ const ( // DebugServer serves /debug/* endpoints type DebugServer struct { - conf *config.AgentConfig - server *http.Server - mux *http.ServeMux + conf *config.AgentConfig + server *http.Server + mux *http.ServeMux + tlsConfig *tls.Config } // NewDebugServer returns a debug server @@ -53,13 +55,14 @@ func (ds *DebugServer) Start() { WriteTimeout: defaultTimeout, Handler: ds.setupMux(), } - listener, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", ds.conf.DebugServerPort)) + listener, err := net.Listen("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(ds.conf.DebugServerPort))) if err != nil { log.Errorf("Error creating debug server listener: %s", err) return } + tlsListener := tls.NewListener(listener, ds.tlsConfig) go func() { - if err := ds.server.Serve(listener); err != nil && err != http.ErrServerClosed { + if err := ds.server.Serve(tlsListener); err != nil && err != http.ErrServerClosed { log.Errorf("Could not start debug server: %s. Debug server disabled.", err) } }() @@ -82,6 +85,11 @@ func (ds *DebugServer) AddRoute(route string, handler http.Handler) { ds.mux.Handle(route, handler) } +// SetTLSConfig adds the provided tls.Config to the internal http.Server +func (ds *DebugServer) SetTLSConfig(config *tls.Config) { + ds.tlsConfig = config +} + func (ds *DebugServer) setupMux() *http.ServeMux { ds.mux.HandleFunc("/debug/pprof/", pprof.Index) ds.mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) diff --git a/pkg/trace/go.mod b/pkg/trace/go.mod index 6fbe7317b66c5..fa1ca487a3dc8 100644 --- a/pkg/trace/go.mod +++ b/pkg/trace/go.mod @@ -20,7 +20,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/log v0.59.0 github.com/DataDog/datadog-agent/pkg/util/pointer v0.59.0 github.com/DataDog/datadog-agent/pkg/util/scrubber v0.59.0 - github.com/DataDog/datadog-go/v5 v5.5.0 + github.com/DataDog/datadog-go/v5 v5.6.0 github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.22.0 github.com/DataDog/sketches-go v1.4.6 github.com/Microsoft/go-winio v0.6.2 diff --git a/pkg/trace/go.sum b/pkg/trace/go.sum index 75f5a8bd8498a..4613790f7cc34 100644 --- a/pkg/trace/go.sum +++ b/pkg/trace/go.sum @@ -1,5 +1,5 @@ -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/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= github.com/DataDog/go-sqllexer v0.0.17 h1:u47fJAVg/+5DA74ZW3w0Qu+3qXHd3GtnA8ZBYixdPrM= github.com/DataDog/go-sqllexer v0.0.17/go.mod h1:KwkYhpFEVIq+BfobkTC1vfqm4gTi65skV/DpDBXtexc= github.com/DataDog/go-tuf v1.1.0-0.5.2 h1:4CagiIekonLSfL8GMHRHcHudo1fQnxELS9g4tiAupQ4= diff --git a/pkg/trace/info/info.go b/pkg/trace/info/info.go index df86c40587fdc..4198100ee6a5b 100644 --- a/pkg/trace/info/info.go +++ b/pkg/trace/info/info.go @@ -8,6 +8,7 @@ package info import ( "bytes" + "crypto/tls" "encoding/json" "expvar" // automatically publish `/debug/vars` on HTTP port "fmt" @@ -236,8 +237,9 @@ func getProgramBanner(version string) (string, string) { // If error is nil, means the program is running. // If not, it displays a pretty-printed message anyway (for support) func Info(w io.Writer, conf *config.AgentConfig) error { - url := fmt.Sprintf("http://127.0.0.1:%d/debug/vars", conf.DebugServerPort) - client := http.Client{Timeout: 3 * time.Second} + url := fmt.Sprintf("https://127.0.0.1:%d/debug/vars", conf.DebugServerPort) + tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} + client := http.Client{Timeout: 3 * time.Second, Transport: tr} resp, err := client.Get(url) if err != nil { // OK, here, we can't even make an http call on the agent port, diff --git a/pkg/trace/info/info_test.go b/pkg/trace/info/info_test.go index 01c369cac403e..25b7cb42b13ff 100644 --- a/pkg/trace/info/info_test.go +++ b/pkg/trace/info/info_test.go @@ -63,7 +63,7 @@ func (h *testServerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func testServer(t *testing.T, testFile string) *httptest.Server { t.Helper() - server := httptest.NewServer(&testServerHandler{t: t, testFile: testFile}) + server := httptest.NewTLSServer(&testServerHandler{t: t, testFile: testFile}) t.Logf("test server (serving fake yet valid data) listening on %s", server.URL) return server } @@ -94,7 +94,7 @@ func (h *testServerWarningHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ } func testServerWarning(t *testing.T) *httptest.Server { - server := httptest.NewServer(&testServerWarningHandler{t: t}) + server := httptest.NewTLSServer(&testServerWarningHandler{t: t}) t.Logf("test server (serving data containing worrying values) listening on %s", server.URL) return server } @@ -119,7 +119,7 @@ func (h *testServerErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques } func testServerError(t *testing.T) *httptest.Server { - server := httptest.NewServer(&testServerErrorHandler{t: t}) + server := httptest.NewTLSServer(&testServerErrorHandler{t: t}) t.Logf("test server (serving bad data to trigger errors) listening on %s", server.URL) return server } @@ -331,7 +331,7 @@ func TestError(t *testing.T) { assert.Equal(len(lines[1]), len(lines[2])) assert.Equal("", lines[3]) assert.Regexp(regexp.MustCompile(`^ Error: .*$`), lines[4]) - assert.Equal(fmt.Sprintf(" URL: http://127.0.0.1:%d/debug/vars", port), lines[5]) + assert.Equal(fmt.Sprintf(" URL: https://127.0.0.1:%d/debug/vars", port), lines[5]) assert.Equal("", lines[6]) assert.Equal("", lines[7]) } diff --git a/pkg/trace/stats/oteltest/go.mod b/pkg/trace/stats/oteltest/go.mod index dafb9c2cd7a8b..306e0217b22ad 100644 --- a/pkg/trace/stats/oteltest/go.mod +++ b/pkg/trace/stats/oteltest/go.mod @@ -6,7 +6,7 @@ require ( github.com/DataDog/datadog-agent/comp/otelcol/otlp/components/statsprocessor v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/proto v0.56.0-rc.3 github.com/DataDog/datadog-agent/pkg/trace v0.56.0-rc.3 - github.com/DataDog/datadog-go/v5 v5.5.0 + github.com/DataDog/datadog-go/v5 v5.6.0 github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.22.0 github.com/google/go-cmp v0.6.0 github.com/stretchr/testify v1.10.0 diff --git a/pkg/trace/stats/oteltest/go.sum b/pkg/trace/stats/oteltest/go.sum index 13b6ed7206fcd..25a9e6fccac3c 100644 --- a/pkg/trace/stats/oteltest/go.sum +++ b/pkg/trace/stats/oteltest/go.sum @@ -1,5 +1,5 @@ -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/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= github.com/DataDog/go-sqllexer v0.0.17 h1:u47fJAVg/+5DA74ZW3w0Qu+3qXHd3GtnA8ZBYixdPrM= github.com/DataDog/go-sqllexer v0.0.17/go.mod h1:KwkYhpFEVIq+BfobkTC1vfqm4gTi65skV/DpDBXtexc= github.com/DataDog/go-tuf v1.1.0-0.5.2 h1:4CagiIekonLSfL8GMHRHcHudo1fQnxELS9g4tiAupQ4= diff --git a/pkg/util/cloudproviders/gce/gce_no_tags.go b/pkg/util/cloudproviders/gce/gce_no_tags.go deleted file mode 100644 index 270cf77ce59ce..0000000000000 --- a/pkg/util/cloudproviders/gce/gce_no_tags.go +++ /dev/null @@ -1,17 +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. - -//go:build !gce - -package gce - -import "context" - -// GetTags gets the tags from the GCE api -func GetTags(_ context.Context) ([]string, error) { - tags := []string{} - - return tags, nil -} diff --git a/pkg/util/cloudproviders/gce/gce_tags.go b/pkg/util/cloudproviders/gce/gce_tags.go index 31c986277bc97..9440ba6ccc21b 100644 --- a/pkg/util/cloudproviders/gce/gce_tags.go +++ b/pkg/util/cloudproviders/gce/gce_tags.go @@ -3,8 +3,6 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build gce - package gce import ( diff --git a/pkg/util/cloudproviders/gce/gce_tags_test.go b/pkg/util/cloudproviders/gce/gce_tags_test.go index 06f15ed938f21..80a803e3cc687 100644 --- a/pkg/util/cloudproviders/gce/gce_tags_test.go +++ b/pkg/util/cloudproviders/gce/gce_tags_test.go @@ -3,8 +3,6 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build gce - package gce import ( diff --git a/pkg/util/containers/filter.go b/pkg/util/containers/filter.go index 1e2ab52934e77..63676bc59533d 100644 --- a/pkg/util/containers/filter.go +++ b/pkg/util/containers/filter.go @@ -112,6 +112,7 @@ func parseFilters(filters []string) (imageFilters, nameFilters, namespaceFilters for _, filter := range filters { switch { case strings.HasPrefix(filter, imageFilterPrefix): + filter = preprocessImageFilter(filter) r, err := filterToRegex(filter, imageFilterPrefix) if err != nil { filterErrs = append(filterErrs, err.Error()) @@ -145,6 +146,19 @@ func parseFilters(filters []string) (imageFilters, nameFilters, namespaceFilters return imageFilters, nameFilters, namespaceFilters, filterWarnings, nil } +// preprocessImageFilter modifies image filters having the format `name$`, where {name} doesn't include a colon (e.g. nginx$, ^nginx$), to +// `name:.*`. +// This is done so that image filters can still match even if the matched image contains the tag or digest. +func preprocessImageFilter(imageFilter string) string { + regexVal := strings.TrimPrefix(imageFilter, imageFilterPrefix) + if strings.HasSuffix(regexVal, "$") && !strings.Contains(regexVal, ":") { + mutatedRegexVal := regexVal[:len(regexVal)-1] + "(@sha256)?:.*" + return imageFilterPrefix + mutatedRegexVal + } + + return imageFilter +} + // filterToRegex checks a filter's regex func filterToRegex(filter string, filterPrefix string) (*regexp.Regexp, error) { pat := strings.TrimPrefix(filter, filterPrefix) @@ -327,7 +341,16 @@ func NewAutodiscoveryFilter(ft FilterType) (*Filter, error) { // based on the filters in the containerFilter instance. Consider also using // Note: exclude filters are not applied to empty container names, empty // images and empty namespaces. +// +// containerImage may or may not contain the image tag or image digest. (e.g. nginx:latest and nginx are both valid) func (cf Filter) IsExcluded(annotations map[string]string, containerName, containerImage, podNamespace string) bool { + + // If containerImage doesn't include the tag or digest, add a colon so that it + // can match image filters + if len(containerImage) > 0 && !strings.Contains(containerImage, ":") { + containerImage += ":" + } + if cf.isExcludedByAnnotation(annotations, containerName) { return true } diff --git a/pkg/util/containers/filter_test.go b/pkg/util/containers/filter_test.go index 1c1d768a4dfc0..ea33a72134f46 100644 --- a/pkg/util/containers/filter_test.go +++ b/pkg/util/containers/filter_test.go @@ -28,6 +28,14 @@ func TestFilter(t *testing.T) { c ctnDef ns string }{ + { + c: ctnDef{ + ID: "0", + Name: "container-with-sha", + Image: "docker-dd-agent@sha256:1892862abcdef61516516", + }, + ns: "default", + }, { c: ctnDef{ ID: "1", @@ -268,25 +276,33 @@ func TestFilter(t *testing.T) { expectedIDs []string }{ { - expectedIDs: []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, + expectedIDs: []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, }, { - excludeList: []string{"name:secret"}, + excludeList: []string{"image:^docker-dd-agent$"}, expectedIDs: []string{"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, }, + { + excludeList: []string{"image:^apache$"}, + expectedIDs: []string{"0", "1", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, + }, + { + excludeList: []string{"name:secret"}, + expectedIDs: []string{"0", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, + }, { excludeList: []string{"image:secret"}, - expectedIDs: []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, + expectedIDs: []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, }, { includeList: []string{}, excludeList: []string{"image:apache", "image:alpine"}, - expectedIDs: []string{"1", "3", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, + expectedIDs: []string{"0", "1", "3", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, }, { includeList: []string{"name:mysql"}, excludeList: []string{"name:dd"}, - expectedIDs: []string{"3", "5", "6", "7", "8", "9", "10", "11", "12", "13", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, + expectedIDs: []string{"0", "3", "5", "6", "7", "8", "9", "10", "11", "12", "13", "16", "17", "18", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, }, { excludeList: []string{"kube_namespace:.*"}, @@ -295,7 +311,7 @@ func TestFilter(t *testing.T) { }, { excludeList: []string{"kube_namespace:bar"}, - expectedIDs: []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, + expectedIDs: []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "19", "20", "23", "24", "25", "26", "27", "28", "29", "30", "31"}, }, { excludeList: []string{"name:.*"}, @@ -305,7 +321,17 @@ func TestFilter(t *testing.T) { { excludeList: []string{"image:.*"}, includeList: []string{"image:docker-dd-agent"}, - expectedIDs: []string{"1", "30"}, + expectedIDs: []string{"0", "1", "30"}, + }, + { + excludeList: []string{"image:.*"}, + includeList: []string{"image:^docker-dd-agent$"}, + expectedIDs: []string{"0", "1", "30"}, + }, + { + excludeList: []string{"image:.*"}, + includeList: []string{"image:^docker-dd-agent$"}, + expectedIDs: []string{"0", "1", "30"}, }, // Test kubernetes defaults { @@ -326,7 +352,7 @@ func TestFilter(t *testing.T) { pauseContainerUpstream, pauseContainerCDK, }, - expectedIDs: []string{"1", "2", "3", "4", "5", "14", "15", "29", "30", "31"}, + expectedIDs: []string{"0", "1", "2", "3", "4", "5", "14", "15", "29", "30", "31"}, }, } { t.Run("", func(t *testing.T) { @@ -624,6 +650,15 @@ func TestParseFilters(t *testing.T) { expectedErrMsg: nil, filterErrors: nil, }, + { + desc: "valid filters, image filter strict match without tag or digest", + filters: []string{"image:^nginx$", "name:xyz-.*", "kube_namespace:sandbox.*", "name:abc"}, + imageFilters: []*regexp.Regexp{regexp.MustCompile("^nginx(@sha256)?:.*")}, + nameFilters: []*regexp.Regexp{regexp.MustCompile("xyz-.*"), regexp.MustCompile("abc")}, + namespaceFilters: []*regexp.Regexp{regexp.MustCompile("sandbox.*")}, + expectedErrMsg: nil, + filterErrors: nil, + }, { desc: "invalid regex", filters: []string{"image:apache.*", "name:a(?=b)", "kube_namespace:sandbox.*", "name:abc"}, diff --git a/pkg/util/core.go b/pkg/util/coredump/core.go similarity index 81% rename from pkg/util/core.go rename to pkg/util/coredump/core.go index 77649ea1d53f3..64b4f35c3a12a 100644 --- a/pkg/util/core.go +++ b/pkg/util/coredump/core.go @@ -5,7 +5,7 @@ //go:build !windows -package util +package coredump import ( "fmt" @@ -16,8 +16,8 @@ import ( "github.com/DataDog/datadog-agent/pkg/config/model" ) -// SetupCoreDump enables core dumps and sets the core dump size limit based on configuration -func SetupCoreDump(cfg model.Reader) error { +// Setup enables core dumps and sets the core dump size limit based on configuration +func Setup(cfg model.Reader) error { if cfg.GetBool("go_core_dump") { debug.SetTraceback("crash") diff --git a/pkg/util/core_windows.go b/pkg/util/coredump/core_windows.go similarity index 73% rename from pkg/util/core_windows.go rename to pkg/util/coredump/core_windows.go index c11422c8aff2b..3e7d3915f7636 100644 --- a/pkg/util/core_windows.go +++ b/pkg/util/coredump/core_windows.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-2020 Datadog, Inc. -package util +package coredump import ( "fmt" @@ -11,8 +11,8 @@ import ( "github.com/DataDog/datadog-agent/pkg/config/model" ) -// SetupCoreDump enables core dumps and sets the core dump size limit based on configuration -func SetupCoreDump(cfg model.Reader) error { +// Setup enables core dumps and sets the core dump size limit based on configuration +func Setup(cfg model.Reader) error { if cfg.GetBool("go_core_dump") { return fmt.Errorf("Not supported on Windows") } diff --git a/pkg/util/coredump/docs.go b/pkg/util/coredump/docs.go new file mode 100644 index 0000000000000..43371b50e7dac --- /dev/null +++ b/pkg/util/coredump/docs.go @@ -0,0 +1,7 @@ +// 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-2020 Datadog, Inc. + +// Package coredump provides utils to enable core dumps and set core dump size limit +package coredump diff --git a/pkg/util/filesystem/go.mod b/pkg/util/filesystem/go.mod index 1a0effc2f07e8..292bb06f164b9 100644 --- a/pkg/util/filesystem/go.mod +++ b/pkg/util/filesystem/go.mod @@ -12,7 +12,7 @@ replace ( require ( github.com/DataDog/datadog-agent/pkg/util/log v0.59.1 github.com/DataDog/datadog-agent/pkg/util/winutil v0.59.1 - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb github.com/shirou/gopsutil/v4 v4.24.11 github.com/stretchr/testify v1.10.0 golang.org/x/sys v0.28.0 diff --git a/pkg/util/filesystem/go.sum b/pkg/util/filesystem/go.sum index 97cab95a8f162..14cc56a3421e8 100644 --- a/pkg/util/filesystem/go.sum +++ b/pkg/util/filesystem/go.sum @@ -7,8 +7,8 @@ github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI 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/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= 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= diff --git a/pkg/util/flavor/go.mod b/pkg/util/flavor/go.mod index 4b2095a3d95dd..91efb20fa615f 100644 --- a/pkg/util/flavor/go.mod +++ b/pkg/util/flavor/go.mod @@ -62,7 +62,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/pkg/util/flavor/go.sum b/pkg/util/flavor/go.sum index 3f00397cbc301..7fdf16db5981c 100644 --- a/pkg/util/flavor/go.sum +++ b/pkg/util/flavor/go.sum @@ -86,8 +86,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/util/grpc/auth.go b/pkg/util/grpc/auth.go index 382c4838919a6..fae83d5c22e8d 100644 --- a/pkg/util/grpc/auth.go +++ b/pkg/util/grpc/auth.go @@ -7,6 +7,7 @@ package grpc import ( "context" + "crypto/subtle" "errors" "fmt" @@ -45,7 +46,7 @@ func AuthInterceptor(verifier verifierFunc) grpc_auth.AuthFunc { // using the given token. func StaticAuthInterceptor(token string) grpc_auth.AuthFunc { return AuthInterceptor(func(reqToken string) (interface{}, error) { - if reqToken != token { + if subtle.ConstantTimeCompare([]byte(reqToken), []byte(token)) == 0 { return struct{}{}, errors.New("invalid session token") } diff --git a/pkg/util/grpc/go.mod b/pkg/util/grpc/go.mod index 46b4cce771519..9598ddb031dea 100644 --- a/pkg/util/grpc/go.mod +++ b/pkg/util/grpc/go.mod @@ -75,7 +75,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/pkg/util/grpc/go.sum b/pkg/util/grpc/go.sum index 6b1fd57ab75ad..f5e59fbfc1ba8 100644 --- a/pkg/util/grpc/go.sum +++ b/pkg/util/grpc/go.sum @@ -105,8 +105,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/util/http/go.mod b/pkg/util/http/go.mod index fd083ad63e413..74a5f34311844 100644 --- a/pkg/util/http/go.mod +++ b/pkg/util/http/go.mod @@ -64,7 +64,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/pkg/util/http/go.sum b/pkg/util/http/go.sum index 71817661e74a3..0ba8e47583917 100644 --- a/pkg/util/http/go.sum +++ b/pkg/util/http/go.sum @@ -86,8 +86,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/util/log/setup/go.mod b/pkg/util/log/setup/go.mod index 480a4c8b2e4cd..f2c45da509f53 100644 --- a/pkg/util/log/setup/go.mod +++ b/pkg/util/log/setup/go.mod @@ -63,7 +63,7 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect diff --git a/pkg/util/log/setup/go.sum b/pkg/util/log/setup/go.sum index 3f00397cbc301..7fdf16db5981c 100644 --- a/pkg/util/log/setup/go.sum +++ b/pkg/util/log/setup/go.sum @@ -86,8 +86,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqC github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/pkg/util/system/go.mod b/pkg/util/system/go.mod index b91b137b720c2..78e3380d124ed 100644 --- a/pkg/util/system/go.mod +++ b/pkg/util/system/go.mod @@ -30,7 +30,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/ebitengine/purego v0.8.1 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect diff --git a/pkg/util/system/go.sum b/pkg/util/system/go.sum index 5dc55f7f10161..47e0acb25ee1f 100644 --- a/pkg/util/system/go.sum +++ b/pkg/util/system/go.sum @@ -10,8 +10,8 @@ github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW 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/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= 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= diff --git a/pkg/util/trivy/containerd.go b/pkg/util/trivy/containerd.go index 94b8b7dab0f8b..d3ed7ddf3f84c 100644 --- a/pkg/util/trivy/containerd.go +++ b/pkg/util/trivy/containerd.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -//go:build trivy +//go:build trivy && containerd package trivy diff --git a/pkg/util/trivy/overlayfs.go b/pkg/util/trivy/overlayfs.go index 8c5a73cf8e3ea..f1f8e243983cc 100644 --- a/pkg/util/trivy/overlayfs.go +++ b/pkg/util/trivy/overlayfs.go @@ -23,7 +23,7 @@ import ( // whiteoutCharDev is defined as zero and is not const only for testing as it // is not allowed to mknod a 0/0 char dev in userns. -var whiteoutCharDev uint64 = 0 //nolint:revive +var whiteoutCharDev uint64 // = 0 var whiteout *fs.DirEntry diff --git a/pkg/util/trivy/trivy.go b/pkg/util/trivy/trivy.go index 07a15d58d93ac..63163ff3ae307 100644 --- a/pkg/util/trivy/trivy.go +++ b/pkg/util/trivy/trivy.go @@ -19,16 +19,13 @@ import ( "sort" "strings" "sync" - "time" "github.com/containerd/containerd/mount" - "github.com/containerd/containerd/namespaces" "github.com/DataDog/datadog-agent/comp/core/config" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/config/env" "github.com/DataDog/datadog-agent/pkg/sbom" - cutil "github.com/DataDog/datadog-agent/pkg/util/containerd" containersimage "github.com/DataDog/datadog-agent/pkg/util/containers/image" "github.com/DataDog/datadog-agent/pkg/util/crio" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -48,9 +45,6 @@ import ( "github.com/aquasecurity/trivy/pkg/scanner/ospkg" "github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/vulnerability" - "github.com/containerd/containerd" - "github.com/containerd/containerd/leases" - "github.com/containerd/errdefs" "github.com/docker/docker/client" // This is required to load sqlite based RPM databases @@ -58,21 +52,15 @@ import ( ) const ( - cleanupTimeout = 30 * time.Second - OSAnalyzers = "os" // OSAnalyzers defines an OS analyzer LanguagesAnalyzers = "languages" // LanguagesAnalyzers defines a language analyzer SecretAnalyzers = "secret" // SecretAnalyzers defines a secret analyzer ConfigFileAnalyzers = "config" // ConfigFileAnalyzers defines a configuration file analyzer - LicenseAnalyzers = "license" // LicenseAnalyzers defines a license analyzer TypeApkCommand = "apk-command" // TypeApkCommand defines a apk-command analyzer HistoryDockerfile = "history-dockerfile" // HistoryDockerfile defines a history-dockerfile analyzer TypeImageConfigSecret = "image-config-secret" // TypeImageConfigSecret defines a history-dockerfile analyzer ) -// ContainerdAccessor is a function that should return a containerd client -type ContainerdAccessor func() (cutil.ContainerdItf, error) - // collectorConfig allows to pass configuration type collectorConfig struct { clearCacheOnClose bool @@ -160,9 +148,6 @@ func DefaultDisabledCollectors(enabledAnalyzers []string) []analyzer.Type { if analyzersDisabled(ConfigFileAnalyzers) { disabledAnalyzers = append(disabledAnalyzers, analyzer.TypeConfigFiles...) } - if analyzersDisabled(LicenseAnalyzers) { - disabledAnalyzers = append(disabledAnalyzers, analyzer.TypeLicenseFile) - } if analyzersDisabled(TypeApkCommand) { disabledAnalyzers = append(disabledAnalyzers, analyzer.TypeApkCommand) } @@ -177,7 +162,9 @@ func DefaultDisabledCollectors(enabledAnalyzers []string) []analyzer.Type { analyzer.TypeRedHatContentManifestType, analyzer.TypeRedHatDockerfileType, analyzer.TypeSBOM, - analyzer.TypeUbuntuESM) + analyzer.TypeUbuntuESM, + analyzer.TypeLicenseFile, + ) return disabledAnalyzers } @@ -317,94 +304,6 @@ func (c *Collector) scanOverlayFS(ctx context.Context, layers []string, imgMeta return report, nil } -// ScanContainerdImageFromSnapshotter scans containerd image directly from the snapshotter -func (c *Collector) ScanContainerdImageFromSnapshotter(ctx context.Context, imgMeta *workloadmeta.ContainerImageMetadata, img containerd.Image, client cutil.ContainerdItf, scanOptions sbom.ScanOptions) (sbom.Report, error) { - // Computing duration of containerd lease - deadline, _ := ctx.Deadline() - expiration := deadline.Sub(time.Now().Add(cleanupTimeout)) - clClient := client.RawClient() - imageID := imgMeta.ID - - mounts, err := client.Mounts(ctx, expiration, imgMeta.Namespace, img) - if err != nil { - return nil, fmt.Errorf("unable to get mounts for image %s, err: %w", imgMeta.ID, err) - } - - layers := extractLayersFromOverlayFSMounts(mounts) - if len(layers) == 0 { - return nil, fmt.Errorf("unable to extract layers from overlayfs mounts %+v for image %s", mounts, imgMeta.ID) - } - - ctx = namespaces.WithNamespace(ctx, imgMeta.Namespace) - // Adding a lease to cleanup dandling snaphots at expiration - ctx, done, err := clClient.WithLease(ctx, - leases.WithID(imageID), - leases.WithExpiration(expiration), - leases.WithLabels(map[string]string{ - "containerd.io/gc.ref.snapshot." + containerd.DefaultSnapshotter: imageID, - }), - ) - if err != nil && !errdefs.IsAlreadyExists(err) { - return nil, fmt.Errorf("unable to get a lease, err: %w", err) - } - - report, err := c.scanOverlayFS(ctx, layers, imgMeta, scanOptions) - - if err := done(ctx); err != nil { - log.Warnf("Unable to cancel containerd lease with id: %s, err: %v", imageID, err) - } - - return report, err -} - -// ScanContainerdImage scans containerd image by exporting it and scanning the tarball -func (c *Collector) ScanContainerdImage(ctx context.Context, imgMeta *workloadmeta.ContainerImageMetadata, img containerd.Image, client cutil.ContainerdItf, scanOptions sbom.ScanOptions) (sbom.Report, error) { - fanalImage, cleanup, err := convertContainerdImage(ctx, client.RawClient(), imgMeta, img) - if cleanup != nil { - defer cleanup() - } - if err != nil { - return nil, fmt.Errorf("unable to convert containerd image, err: %w", err) - } - - return c.scanImage(ctx, fanalImage, imgMeta, scanOptions) -} - -// ScanContainerdImageFromFilesystem scans containerd image from file-system -func (c *Collector) ScanContainerdImageFromFilesystem(ctx context.Context, imgMeta *workloadmeta.ContainerImageMetadata, img containerd.Image, client cutil.ContainerdItf, scanOptions sbom.ScanOptions) (sbom.Report, error) { - //nolint:gosimple // TODO(CINT) Fix go simple linte - imagePath, err := os.MkdirTemp(os.TempDir(), fmt.Sprintf("containerd-image-*")) - if err != nil { - return nil, fmt.Errorf("unable to create temp dir, err: %w", err) - } - defer func() { - err := os.RemoveAll(imagePath) - if err != nil { - log.Errorf("Unable to remove temp dir: %s, err: %v", imagePath, err) - } - }() - - // Computing duration of containerd lease - deadline, _ := ctx.Deadline() - expiration := deadline.Sub(time.Now().Add(cleanupTimeout)) - - cleanUp, err := client.MountImage(ctx, expiration, imgMeta.Namespace, img, imagePath) - if err != nil { - return nil, fmt.Errorf("unable to mount containerd image, err: %w", err) - } - - defer func() { - cleanUpContext, cleanUpContextCancel := context.WithTimeout(context.Background(), cleanupTimeout) - err := cleanUp(cleanUpContext) - cleanUpContextCancel() - if err != nil { - log.Errorf("Unable to clean up mounted image, err: %v", err) - } - }() - - return c.scanFilesystem(ctx, os.DirFS("/"), imagePath, imgMeta, scanOptions) -} - // ScanCRIOImageFromOverlayFS scans the CRI-O image layers using OverlayFS. func (c *Collector) ScanCRIOImageFromOverlayFS(ctx context.Context, imgMeta *workloadmeta.ContainerImageMetadata, client crio.Client, scanOptions sbom.ScanOptions) (sbom.Report, error) { lowerDirs, err := client.GetCRIOImageLayers(imgMeta) diff --git a/pkg/util/trivy/trivy_containerd.go b/pkg/util/trivy/trivy_containerd.go new file mode 100644 index 0000000000000..bd036354c514d --- /dev/null +++ b/pkg/util/trivy/trivy_containerd.go @@ -0,0 +1,119 @@ +// 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 trivy && containerd + +// Package trivy holds the scan components +package trivy + +import ( + "context" + "fmt" + "os" + "time" + + workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + "github.com/DataDog/datadog-agent/pkg/sbom" + cutil "github.com/DataDog/datadog-agent/pkg/util/containerd" + "github.com/DataDog/datadog-agent/pkg/util/log" + "github.com/containerd/containerd" + "github.com/containerd/containerd/leases" + "github.com/containerd/containerd/namespaces" + "github.com/containerd/errdefs" +) + +const ( + cleanupTimeout = 30 * time.Second +) + +// ContainerdAccessor is a function that should return a containerd client +type ContainerdAccessor func() (cutil.ContainerdItf, error) + +// ScanContainerdImageFromSnapshotter scans containerd image directly from the snapshotter +func (c *Collector) ScanContainerdImageFromSnapshotter(ctx context.Context, imgMeta *workloadmeta.ContainerImageMetadata, img containerd.Image, client cutil.ContainerdItf, scanOptions sbom.ScanOptions) (sbom.Report, error) { + // Computing duration of containerd lease + deadline, _ := ctx.Deadline() + expiration := deadline.Sub(time.Now().Add(cleanupTimeout)) + clClient := client.RawClient() + imageID := imgMeta.ID + + mounts, err := client.Mounts(ctx, expiration, imgMeta.Namespace, img) + if err != nil { + return nil, fmt.Errorf("unable to get mounts for image %s, err: %w", imgMeta.ID, err) + } + + layers := extractLayersFromOverlayFSMounts(mounts) + if len(layers) == 0 { + return nil, fmt.Errorf("unable to extract layers from overlayfs mounts %+v for image %s", mounts, imgMeta.ID) + } + + ctx = namespaces.WithNamespace(ctx, imgMeta.Namespace) + // Adding a lease to cleanup dandling snaphots at expiration + ctx, done, err := clClient.WithLease(ctx, + leases.WithID(imageID), + leases.WithExpiration(expiration), + leases.WithLabels(map[string]string{ + "containerd.io/gc.ref.snapshot." + containerd.DefaultSnapshotter: imageID, + }), + ) + if err != nil && !errdefs.IsAlreadyExists(err) { + return nil, fmt.Errorf("unable to get a lease, err: %w", err) + } + + report, err := c.scanOverlayFS(ctx, layers, imgMeta, scanOptions) + + if err := done(ctx); err != nil { + log.Warnf("Unable to cancel containerd lease with id: %s, err: %v", imageID, err) + } + + return report, err +} + +// ScanContainerdImage scans containerd image by exporting it and scanning the tarball +func (c *Collector) ScanContainerdImage(ctx context.Context, imgMeta *workloadmeta.ContainerImageMetadata, img containerd.Image, client cutil.ContainerdItf, scanOptions sbom.ScanOptions) (sbom.Report, error) { + fanalImage, cleanup, err := convertContainerdImage(ctx, client.RawClient(), imgMeta, img) + if cleanup != nil { + defer cleanup() + } + if err != nil { + return nil, fmt.Errorf("unable to convert containerd image, err: %w", err) + } + + return c.scanImage(ctx, fanalImage, imgMeta, scanOptions) +} + +// ScanContainerdImageFromFilesystem scans containerd image from file-system +func (c *Collector) ScanContainerdImageFromFilesystem(ctx context.Context, imgMeta *workloadmeta.ContainerImageMetadata, img containerd.Image, client cutil.ContainerdItf, scanOptions sbom.ScanOptions) (sbom.Report, error) { + imagePath, err := os.MkdirTemp("", "containerd-image-*") + if err != nil { + return nil, fmt.Errorf("unable to create temp dir, err: %w", err) + } + defer func() { + err := os.RemoveAll(imagePath) + if err != nil { + log.Errorf("Unable to remove temp dir: %s, err: %v", imagePath, err) + } + }() + + // Computing duration of containerd lease + deadline, _ := ctx.Deadline() + expiration := deadline.Sub(time.Now().Add(cleanupTimeout)) + + cleanUp, err := client.MountImage(ctx, expiration, imgMeta.Namespace, img, imagePath) + if err != nil { + return nil, fmt.Errorf("unable to mount containerd image, err: %w", err) + } + + defer func() { + cleanUpContext, cleanUpContextCancel := context.WithTimeout(context.Background(), cleanupTimeout) + err := cleanUp(cleanUpContext) + cleanUpContextCancel() + if err != nil { + log.Errorf("Unable to clean up mounted image, err: %v", err) + } + }() + + return c.scanFilesystem(ctx, os.DirFS("/"), imagePath, imgMeta, scanOptions) +} diff --git a/release.json b/release.json index 24cb211dbbdc3..841e115eac8e4 100644 --- a/release.json +++ b/release.json @@ -3,7 +3,7 @@ "current_milestone": "7.62.0", "last_stable": { "6": "6.53.0", - "7": "7.59.1" + "7": "7.60.0" }, "nightly": { "INTEGRATIONS_CORE_VERSION": "master", diff --git a/releasenotes/notes/add-events-to-flare-b10cb7bf1aaf4d50.yaml b/releasenotes/notes/add-events-to-flare-b10cb7bf1aaf4d50.yaml new file mode 100644 index 0000000000000..9bff569f5f774 --- /dev/null +++ b/releasenotes/notes/add-events-to-flare-b10cb7bf1aaf4d50.yaml @@ -0,0 +1,11 @@ +# Each section from every release note are combined when the +# CHANGELOG.rst is rendered. So the text needs to be worded so that +# it does not depend on any information only available in another +# section. This may mean repeating some details, but each section +# must be readable independently of the other. +# +# Each section note must be formatted as reStructuredText. +--- +enhancements: + - | + On Windows, Agent flares now include event logs for .NET applications. diff --git a/releasenotes/notes/fix-oracle-can_connect-host-tag-c7b00cb45e17735c.yaml b/releasenotes/notes/fix-oracle-can_connect-host-tag-c7b00cb45e17735c.yaml new file mode 100644 index 0000000000000..df805c338b08c --- /dev/null +++ b/releasenotes/notes/fix-oracle-can_connect-host-tag-c7b00cb45e17735c.yaml @@ -0,0 +1,11 @@ +# Each section from every release note are combined when the +# CHANGELOG.rst is rendered. So the text needs to be worded so that +# it does not depend on any information only available in another +# section. This may mean repeating some details, but each section +# must be readable independently of the other. +# +# Each section note must be formatted as reStructuredText. +--- +fixes: + - | + Corrects host tagging for the oracle.can_connect service check diff --git a/releasenotes/notes/make_image_filters_consistent-14fd44a352723e50.yaml b/releasenotes/notes/make_image_filters_consistent-14fd44a352723e50.yaml new file mode 100644 index 0000000000000..d0b292f5f2267 --- /dev/null +++ b/releasenotes/notes/make_image_filters_consistent-14fd44a352723e50.yaml @@ -0,0 +1,16 @@ +# Each section from every release note are combined when the +# CHANGELOG.rst is rendered. So the text needs to be worded so that +# it does not depend on any information only available in another +# section. This may mean repeating some details, but each section +# must be readable independently of the other. +# +# Each section note must be formatted as reStructuredText. +--- +fixes: + - | + Fixes consistency issue with container image filters. + Depending on the Agent configuration, filters were sometimes behaving differently + for metrics and logs. For example, an image filter that worked for excluding logs + didn't work when used to exclude metrics, and vice versa. + The exclusion logic is now consistent between metrics and logs. + diff --git a/releasenotes/notes/update-embedded-permissions-a8e169f1c079cd41.yaml b/releasenotes/notes/update-embedded-permissions-a8e169f1c079cd41.yaml new file mode 100644 index 0000000000000..8b9cafd486a16 --- /dev/null +++ b/releasenotes/notes/update-embedded-permissions-a8e169f1c079cd41.yaml @@ -0,0 +1,11 @@ +# Each section from every release note are combined when the +# CHANGELOG.rst is rendered. So the text needs to be worded so that +# it does not depend on any information only available in another +# section. This may mean repeating some details, but each section +# must be readable independently of the other. +# +# Each section note must be formatted as reStructuredText. +--- +security: + - | + Move the embedded Python cache out of the installation directory on Windows. diff --git a/tasks/__init__.py b/tasks/__init__.py index d59a06de7463b..0dffed23dacaf 100644 --- a/tasks/__init__.py +++ b/tasks/__init__.py @@ -87,13 +87,13 @@ tidy, tidy_all, ) +from tasks.gointegrationtest import integration_tests from tasks.gotest import ( check_otel_build, check_otel_module_versions, e2e_tests, get_impacted_packages, get_modified_packages, - integration_tests, lint_go, send_unit_tests_stats, test, diff --git a/tasks/agent.py b/tasks/agent.py index d4e5d13230885..19cd6170b96c6 100644 --- a/tasks/agent.py +++ b/tasks/agent.py @@ -17,6 +17,11 @@ from tasks.build_tags import add_fips_tags, filter_incompatible_tags, get_build_tags, get_default_build_tags from tasks.devcontainer import run_on_devcontainer from tasks.flavor import AgentFlavor +from tasks.gointegrationtest import ( + CORE_AGENT_LINUX_IT_CONF, + CORE_AGENT_WINDOWS_IT_CONF, + containerized_integration_tests, +) from tasks.libs.common.utils import ( REPO_PATH, bin_name, @@ -578,79 +583,18 @@ def integration_tests(ctx, race=False, remote_docker=False, go_mod="readonly", t """ Run integration tests for the Agent """ - if sys.platform == 'win32': - return _windows_integration_tests(ctx, race=race, go_mod=go_mod, timeout=timeout) - else: - # TODO: See if these will function on Windows - return _linux_integration_tests(ctx, race=race, remote_docker=remote_docker, go_mod=go_mod, timeout=timeout) - - -def _windows_integration_tests(ctx, race=False, go_mod="readonly", timeout=""): - test_args = { - "go_mod": go_mod, - "go_build_tags": " ".join(get_default_build_tags(build="test")), - "race_opt": "-race" if race else "", - "exec_opts": "", - "timeout_opt": f"-timeout {timeout}" if timeout else "", - } - - go_cmd = 'go test {timeout_opt} -mod={go_mod} {race_opt} -tags "{go_build_tags}" {exec_opts}'.format(**test_args) # noqa: FS002 - - tests = [ - { - # Run eventlog tests with the Windows API, which depend on the EventLog service - "dir": "./pkg/util/winutil/", - 'prefix': './eventlog/...', - 'extra_args': '-evtapi Windows', - }, - { - # Run eventlog tailer tests with the Windows API, which depend on the EventLog service - "dir": ".", - 'prefix': './pkg/logs/tailers/windowsevent/...', - 'extra_args': '-evtapi Windows', - }, - { - # Run eventlog check tests with the Windows API, which depend on the EventLog service - "dir": ".", - # Don't include submodules, since the `-evtapi` flag is not defined in them - 'prefix': './comp/checks/windowseventlog/windowseventlogimpl/check', - 'extra_args': '-evtapi Windows', - }, - ] - - for test in tests: - with ctx.cd(f"{test['dir']}"): - ctx.run(f"{go_cmd} {test['prefix']} {test['extra_args']}") - - -def _linux_integration_tests(ctx, race=False, remote_docker=False, go_mod="readonly", timeout=""): - test_args = { - "go_mod": go_mod, - "go_build_tags": " ".join(get_default_build_tags(build="test")), - "race_opt": "-race" if race else "", - "exec_opts": "", - "timeout_opt": f"-timeout {timeout}" if timeout else "", - } - - # since Go 1.13, the -exec flag of go test could add some parameters such as -test.timeout - # to the call, we don't want them because while calling invoke below, invoke - # thinks that the parameters are for it to interpret. - # we're calling an intermediate script which only pass the binary name to the invoke task. - if remote_docker: - test_args["exec_opts"] = f"-exec \"{os.getcwd()}/test/integration/dockerize_tests.sh\"" - - go_cmd = 'go test {timeout_opt} -mod={go_mod} {race_opt} -tags "{go_build_tags}" {exec_opts}'.format(**test_args) # noqa: FS002 - - prefixes = [ - "./test/integration/config_providers/...", - "./test/integration/corechecks/...", - "./test/integration/listeners/...", - "./test/integration/util/kubelet/...", - ] - - for prefix in prefixes: - ctx.run(f"{go_cmd} {prefix}") + return containerized_integration_tests( + ctx, CORE_AGENT_WINDOWS_IT_CONF, race=race, go_mod=go_mod, timeout=timeout + ) + return containerized_integration_tests( + ctx, + CORE_AGENT_LINUX_IT_CONF, + race=race, + remote_docker=remote_docker, + go_mod=go_mod, + timeout=timeout, + ) def check_supports_python_version(check_dir, python): diff --git a/tasks/build_tags.py b/tasks/build_tags.py index ddd993490f389..c400d2560aa94 100644 --- a/tasks/build_tags.py +++ b/tasks/build_tags.py @@ -28,7 +28,6 @@ "ec2", "etcd", "fargateprocess", - "gce", "jmx", "jetson", "kubeapiserver", @@ -68,7 +67,6 @@ "docker", "ec2", "etcd", - "gce", "jetson", "jmx", "kubeapiserver", @@ -109,7 +107,7 @@ FIPS_AGENT_TAGS = AGENT_TAGS.union({"goexperiment.systemcrypto"}) # CLUSTER_AGENT_TAGS lists the tags needed when building the cluster-agent -CLUSTER_AGENT_TAGS = {"clusterchecks", "datadog.no_waf", "kubeapiserver", "orchestrator", "zlib", "zstd", "ec2", "gce"} +CLUSTER_AGENT_TAGS = {"clusterchecks", "datadog.no_waf", "kubeapiserver", "orchestrator", "zlib", "zstd", "ec2"} # CLUSTER_AGENT_CLOUDFOUNDRY_TAGS lists the tags needed when building the cloudfoundry cluster-agent CLUSTER_AGENT_CLOUDFOUNDRY_TAGS = {"clusterchecks"} @@ -121,7 +119,7 @@ IOT_AGENT_TAGS = {"jetson", "otlp", "systemd", "zlib", "zstd"} # INSTALLER_TAGS lists the tags needed when building the installer -INSTALLER_TAGS = {"docker", "ec2", "gce", "kubelet"} +INSTALLER_TAGS = {"docker", "ec2", "kubelet"} # PROCESS_AGENT_TAGS lists the tags necessary to build the process-agent PROCESS_AGENT_TAGS = AGENT_TAGS.union({"fargateprocess"}).difference({"otlp", "python", "trivy"}) @@ -161,7 +159,18 @@ SERVERLESS_TAGS = {"serverless", "otlp"} # SYSTEM_PROBE_TAGS lists the tags necessary to build system-probe -SYSTEM_PROBE_TAGS = AGENT_TAGS.union({"linux_bpf", "npm", "pcap"}).difference({"python", "systemd"}) +SYSTEM_PROBE_TAGS = { + "datadog.no_waf", + "ec2", + "linux_bpf", + "netcgo", + "npm", + "pcap", + "process", + "trivy", + "zlib", + "zstd", +} # TRACE_AGENT_TAGS lists the tags that have to be added when the trace-agent TRACE_AGENT_TAGS = {"docker", "containerd", "datadog.no_waf", "kubeapiserver", "kubelet", "otlp", "netcgo", "podman"} diff --git a/tasks/buildimages.py b/tasks/buildimages.py index 2f7d228d4d070..e2bf5316e18c7 100644 --- a/tasks/buildimages.py +++ b/tasks/buildimages.py @@ -1,7 +1,5 @@ from __future__ import annotations -import os - import yaml from invoke import Context, Exit, task @@ -37,17 +35,23 @@ def update(_: Context, tag: str = "", images: str = "", test: bool = True, list_ print(f" {', '.join(modified)}") -@task(help={"commit_sha": "commit sha from the test-infra-definitions repository"}) -def update_test_infra_definitions(ctx: Context, commit_sha: str, go_mod_only: bool = False): +@task( + help={ + "commit_sha": "commit sha from the test-infra-definitions repository", + "go_mod_only": "Update only the go.mod file", + "is_dev_image": "Is the image bumped to a dev version, used to test changes in test-infra-definitions", + } +) +def update_test_infra_definitions(ctx: Context, commit_sha: str, go_mod_only: bool = False, is_dev_image: bool = False): """ Update the test-infra-definition image version in the Gitlab CI as well as in the e2e go.mod """ if not go_mod_only: - update_test_infra_def(".gitlab/common/test_infra_version.yml", commit_sha[:12]) + update_test_infra_def(".gitlab/common/test_infra_version.yml", commit_sha[:12], is_dev_image) - os.chdir("test/new-e2e") - ctx.run(f"go get github.com/DataDog/test-infra-definitions@{commit_sha}") - ctx.run("go mod tidy") + with ctx.cd("test/new-e2e"): + ctx.run(f"go get github.com/DataDog/test-infra-definitions@{commit_sha}") + ctx.run("go mod tidy") @task( diff --git a/tasks/cluster_agent.py b/tasks/cluster_agent.py index 8bbde5be51ece..b929270831a58 100644 --- a/tasks/cluster_agent.py +++ b/tasks/cluster_agent.py @@ -12,10 +12,10 @@ from invoke import task from invoke.exceptions import Exit -from tasks.build_tags import get_build_tags, get_default_build_tags +from tasks.build_tags import get_default_build_tags from tasks.cluster_agent_helpers import build_common, clean_common, refresh_assets_common, version_common from tasks.cws_instrumentation import BIN_PATH as CWS_INSTRUMENTATION_BIN_PATH -from tasks.libs.common.utils import TestsNotSupportedError +from tasks.gointegrationtest import CLUSTER_AGENT_IT_CONF, containerized_integration_tests from tasks.libs.releasing.version import load_release_versions # constants @@ -92,33 +92,14 @@ def integration_tests(ctx, race=False, remote_docker=False, go_mod="readonly", t """ Run integration tests for cluster-agent """ - if sys.platform == 'win32': - raise TestsNotSupportedError('Cluster Agent integration tests are not supported on Windows') - - # We need docker for the kubeapiserver integration tests - tags = get_default_build_tags(build="cluster-agent") + ["docker", "test"] - - go_build_tags = " ".join(get_build_tags(tags, [])) - race_opt = "-race" if race else "" - exec_opts = "" - timeout_opt = f"-timeout {timeout}" if timeout else "" - - # since Go 1.13, the -exec flag of go test could add some parameters such as -test.timeout - # to the call, we don't want them because while calling invoke below, invoke - # thinks that the parameters are for it to interpret. - # we're calling an intermediate script which only pass the binary name to the invoke task. - if remote_docker: - exec_opts = f"-exec \"{os.getcwd()}/test/integration/dockerize_tests.sh\"" - - go_cmd = f'go test {timeout_opt} -mod={go_mod} {race_opt} -tags "{go_build_tags}" {exec_opts}' - - prefixes = [ - "./test/integration/util/kube_apiserver", - "./test/integration/util/leaderelection", - ] - - for prefix in prefixes: - ctx.run(f"{go_cmd} {prefix}") + containerized_integration_tests( + ctx, + CLUSTER_AGENT_IT_CONF, + race=race, + remote_docker=remote_docker, + go_mod=go_mod, + timeout=timeout, + ) @task diff --git a/tasks/collector.py b/tasks/collector.py index e4dbd4ae4d68d..74f3a439bd9fd 100644 --- a/tasks/collector.py +++ b/tasks/collector.py @@ -14,7 +14,7 @@ from tasks.go import tidy from tasks.libs.ciproviders.github_api import GithubAPI from tasks.libs.common.color import Color, color_message -from tasks.libs.common.git import check_uncommitted_changes +from tasks.libs.common.git import check_uncommitted_changes, get_git_config, revert_git_config, set_git_config LICENSE_HEADER = """// Unless explicitly stated otherwise all files in this repository are licensed // under the Apache License Version 2.0. @@ -502,23 +502,6 @@ def update(ctx): print("Update complete.") -def get_git_config(key): - result = subprocess.run(['git', 'config', '--get', key], capture_output=True, text=True) - return result.stdout.strip() if result.returncode == 0 else None - - -def set_git_config(key, value): - subprocess.run(['git', 'config', key, value]) - - -def revert_git_config(original_config): - for key, value in original_config.items(): - if value is None: - subprocess.run(['git', 'config', '--unset', key]) - else: - subprocess.run(['git', 'config', key, value]) - - @task() def pull_request(ctx): # Save current Git configuration diff --git a/tasks/dogstatsd.py b/tasks/dogstatsd.py index 08dbe80a85993..311560a3d118e 100644 --- a/tasks/dogstatsd.py +++ b/tasks/dogstatsd.py @@ -11,7 +11,8 @@ from tasks.build_tags import filter_incompatible_tags, get_build_tags, get_default_build_tags from tasks.flavor import AgentFlavor -from tasks.libs.common.utils import REPO_PATH, TestsNotSupportedError, bin_name, get_build_flags, get_root +from tasks.gointegrationtest import DOGSTATSD_IT_CONF, containerized_integration_tests +from tasks.libs.common.utils import REPO_PATH, bin_name, get_build_flags, get_root from tasks.windows_resources import build_messagetable, build_rc, versioninfo_vars # constants @@ -174,29 +175,14 @@ def integration_tests(ctx, race=False, remote_docker=False, go_mod="readonly", t """ Run integration tests for dogstatsd """ - if sys.platform == 'win32': - raise TestsNotSupportedError('DogStatsD integration tests are not supported on Windows') - - go_build_tags = " ".join(get_default_build_tags(build="test")) - race_opt = "-race" if race else "" - exec_opts = "" - timeout_opt = f"-timeout {timeout}" if timeout else "" - - # since Go 1.13, the -exec flag of go test could add some parameters such as -test.timeout - # to the call, we don't want them because while calling invoke below, invoke - # thinks that the parameters are for it to interpret. - # we're calling an intermediate script which only pass the binary name to the invoke task. - if remote_docker: - exec_opts = f"-exec \"{os.getcwd()}/test/integration/dockerize_tests.sh\"" - - go_cmd = f'go test {timeout_opt} -mod={go_mod} {race_opt} -tags "{go_build_tags}" {exec_opts}' - - prefixes = [ - "./test/integration/dogstatsd/...", - ] - - for prefix in prefixes: - ctx.run(f"{go_cmd} {prefix}") + containerized_integration_tests( + ctx, + DOGSTATSD_IT_CONF, + race=race, + remote_docker=remote_docker, + go_mod=go_mod, + timeout=timeout, + ) @task diff --git a/tasks/go_deps.py b/tasks/go_deps.py index 5310ede1384d8..b08560eaa8056 100644 --- a/tasks/go_deps.py +++ b/tasks/go_deps.py @@ -1,5 +1,7 @@ import datetime import os +import shutil +import tempfile from collections.abc import Iterable from invoke.context import Context @@ -185,3 +187,108 @@ def show(ctx: Context, build: str, flavor: str = AgentFlavor.base.name, os: str for dep in deps: print(dep) + + +@task( + help={ + 'build': f'The agent build to use, one of {", ".join(BINARIES.keys())}', + 'flavor': f'The agent flavor to use, one of {", ".join(AgentFlavor.__members__.keys())}. Defaults to base', + 'os': f'The OS to use, one of {", ".join(GOOS_MAPPING.keys())}. Defaults to host platform', + 'arch': f'The architecture to use, one of {", ".join(GOARCH_MAPPING.keys())}. Defaults to host architecture', + 'entrypoint': 'A Go package path, defaults to the entrypoint of the build.', + 'target': 'A Go package path. If specified, generate a graph from the entrypoint to the target.', + 'std': 'Whether to include the standard library in the graph', + 'cluster': 'Whether to group packages by cluster.', + 'fmt': 'The format of the generated image. Must be accepted by "dot -T". Defaults to "svg".', + 'auto_open': 'Whether to open the generated graph automatically.', + } +) +def graph( + ctx: Context, + build: str, + flavor: str = AgentFlavor.base.name, + os: str | None = None, + arch: str | None = None, + entrypoint: str | None = None, + target: str | None = None, + std: bool = False, + cluster: bool = False, + fmt: str = "svg", + auto_open: bool = True, +): + """ + Generate a dependency graph of the given build. + Requires https://github.com/loov/goda and Graphviz's `dot` tools to be in the PATH. + + Usage: + Dependency graph of the trace-agent on Linux + inv -e go-deps.graph --build trace-agent --os linux + Reachability graph of the process-agent on Linux to k8s.io/... dependencies + inv -e go-deps.graph --build process-agent --os linux --target k8s.io/... + Dependency graph of workloadmeta on Linux when using the same build tags as the core-agent + inv -e go-deps.graph --build agent --os linux --entrypoint github.com/DataDog/datadog-agent/comp/core/workloadmeta/...:all + """ + if shutil.which("goda") is None: + raise Exit( + code=1, + message=color_message( + "'goda' not found in PATH. Please install it with `go install github.com/loov/goda@latest`", "red" + ), + ) + + if os is None: + goos = ctx.run("go env GOOS", hide=True) + assert goos is not None + os = goos.stdout.strip() + assert os in GOOS_MAPPING.values() + + if arch is None: + goarch = ctx.run("go env GOARCH", hide=True) + assert goarch is not None + arch = goarch.stdout.strip() + assert arch in GOARCH_MAPPING.values() + + stdarg = "-std" if std else "" + clusterarg = "-cluster" if cluster else "" + + if entrypoint is None: + entrypoint = BINARIES[build]["entrypoint"] + entrypoint = f"github.com/DataDog/datadog-agent/{entrypoint}:all" + + build_tags = get_default_build_tags( + build=build, flavor=AgentFlavor[flavor], platform=key_for_value(GOOS_MAPPING, os) + ) + for tag in build_tags: + entrypoint = f"{tag}=1({entrypoint})" + + expr = entrypoint if target is None else f"reach({entrypoint}, {target})" + + cmd = f"goda graph {stdarg} {clusterarg} \"{expr}\"" + + env = {"GOOS": os, "GOARCH": arch} + res = ctx.run(cmd, env=env, hide='out') + assert res + + tmpfile = tempfile.mktemp(prefix="graph-") + + dotfile = tmpfile + ".dot" + print("Saving dot file in " + dotfile) + with open(dotfile, "w") as f: + f.write(res.stdout) + + if shutil.which("dot") is None: + raise Exit( + code=1, + message=color_message( + "'dot' not found in PATH. Please follow instructions on https://graphviz.org/download/ to install it.", + "red", + ), + ) + + fmtfile = tmpfile + "." + fmt + print(f"Rendering {fmt} in {fmtfile}") + ctx.run(f"dot -T{fmt} -o {fmtfile} {dotfile}") + + if auto_open: + print(f"Opening {fmt} file") + ctx.run(f"open {fmtfile}") diff --git a/tasks/gointegrationtest.py b/tasks/gointegrationtest.py new file mode 100644 index 0000000000000..1d5cc56c8b9cf --- /dev/null +++ b/tasks/gointegrationtest.py @@ -0,0 +1,161 @@ +import os +import sys +import traceback +from dataclasses import dataclass + +from invoke import Context, task +from invoke.exceptions import Exit + +from tasks.build_tags import get_default_build_tags +from tasks.libs.common.utils import TestsNotSupportedError, gitlab_section + + +@dataclass +class IntegrationTest: + """ + Integration tests + """ + + prefix: str + dir: str = None + extra_args: str = None + + +@dataclass +class IntegrationTestsConfig: + """ + Integration tests configuration + """ + + name: str + go_build_tags: list[str] + tests: list[IntegrationTest] + env: dict[str, str] = None + is_windows_supported: bool = True + + +CORE_AGENT_LINUX_IT_CONF = IntegrationTestsConfig( + name="Core Agent Linux", + go_build_tags=get_default_build_tags(build="test"), + tests=[ + IntegrationTest(prefix="./test/integration/config_providers/..."), + IntegrationTest(prefix="./test/integration/corechecks/..."), + IntegrationTest(prefix="./test/integration/listeners/..."), + IntegrationTest(prefix="./test/integration/util/kubelet/..."), + ], + is_windows_supported=False, +) + +CORE_AGENT_WINDOWS_IT_CONF = IntegrationTestsConfig( + name="Core Agent Windows", + go_build_tags=get_default_build_tags(build="test"), + tests=[ + # Run eventlog tests with the Windows API, which depend on the EventLog service + IntegrationTest(dir="./pkg/util/winutil/", prefix="./eventlog/...", extra_args="-evtapi Windows"), + # Run eventlog tailer tests with the Windows API, which depend on the EventLog service + IntegrationTest(dir=".", prefix="./pkg/logs/tailers/windowsevent/...", extra_args="-evtapi Windows"), + # Run eventlog check tests with the Windows API, which depend on the EventLog service + # Don't include submodules, since the `-evtapi` flag is not defined in them + IntegrationTest( + dir=".", prefix="./comp/checks/windowseventlog/windowseventlogimpl/check", extra_args="-evtapi Windows" + ), + ], +) + +DOGSTATSD_IT_CONF = IntegrationTestsConfig( + name="DogStatsD", + go_build_tags=get_default_build_tags(build="test"), + tests=[IntegrationTest(prefix="./test/integration/dogstatsd/...")], + is_windows_supported=False, +) + +CLUSTER_AGENT_IT_CONF = IntegrationTestsConfig( + name="Cluster Agent", + go_build_tags=get_default_build_tags(build="cluster-agent") + ["docker", "test"], + tests=[ + IntegrationTest(prefix="./test/integration/util/kube_apiserver"), + IntegrationTest(prefix="./test/integration/util/leaderelection"), + ], + is_windows_supported=False, +) + +TRACE_AGENT_IT_CONF = IntegrationTestsConfig( + name="Trace Agent", + go_build_tags=get_default_build_tags(build="test"), + tests=[IntegrationTest(prefix="./cmd/trace-agent/test/testsuite/...")], + env={"INTEGRATION": "yes"}, + is_windows_supported=False, +) + + +def containerized_integration_tests( + ctx: Context, + integration_tests_config: IntegrationTestsConfig, + race=False, + remote_docker=False, + go_mod="readonly", + timeout="", +): + if sys.platform == 'win32' and not integration_tests_config.is_windows_supported: + raise TestsNotSupportedError(f'{integration_tests_config.name} integration tests are not supported on Windows') + test_args = { + "go_mod": go_mod, + "go_build_tags": " ".join(integration_tests_config.go_build_tags), + "race_opt": "-race" if race else "", + "exec_opts": "", + "timeout_opt": f"-timeout {timeout}" if timeout else "", + } + + # since Go 1.13, the -exec flag of go test could add some parameters such as -test.timeout + # to the call, we don't want them because while calling invoke below, invoke + # thinks that the parameters are for it to interpret. + # we're calling an intermediate script which only pass the binary name to the invoke task. + if remote_docker: + test_args["exec_opts"] = f"-exec \"{os.getcwd()}/test/integration/dockerize_tests.sh\"" + + go_cmd = 'go test {timeout_opt} -mod={go_mod} {race_opt} -tags "{go_build_tags}" {exec_opts}'.format(**test_args) # noqa: FS002 + + for it in integration_tests_config.tests: + if it.dir: + with ctx.cd(f"{it.dir}"): + ctx.run(f"{go_cmd} {it.prefix}", env=integration_tests_config.env) + else: + ctx.run(f"{go_cmd} {it.prefix}", env=integration_tests_config.env) + + +@task +def integration_tests(ctx, race=False, remote_docker=False, timeout=""): + """ + Run all the available integration tests + """ + core_agent_conf = CORE_AGENT_WINDOWS_IT_CONF if sys.platform == 'win32' else CORE_AGENT_LINUX_IT_CONF + tests = { + "Agent Core": lambda: containerized_integration_tests( + ctx, core_agent_conf, race=race, remote_docker=remote_docker, timeout=timeout + ), + "DogStatsD": lambda: containerized_integration_tests( + ctx, DOGSTATSD_IT_CONF, race=race, remote_docker=remote_docker, timeout=timeout + ), + "Cluster Agent": lambda: containerized_integration_tests( + ctx, CLUSTER_AGENT_IT_CONF, race=race, remote_docker=remote_docker, timeout=timeout + ), + "Trace Agent": lambda: containerized_integration_tests(ctx, TRACE_AGENT_IT_CONF, race=race, timeout=timeout), + } + tests_failures = {} + for t_name, t in tests.items(): + with gitlab_section(f"Running the {t_name} integration tests", collapsed=True, echo=True): + try: + t() + except TestsNotSupportedError as e: + print(f"Skipping {t_name}: {e}") + except Exception: + # Keep printing the traceback not to have to wait until all tests are done to see what failed + traceback.print_exc() + # Storing the traceback to print it at the end without directly raising the exception + tests_failures[t_name] = traceback.format_exc() + if tests_failures: + print("The following integration tests failed:") + for t_name in tests_failures: + print(f"- {t_name}") + print("See the above logs to get the full traceback.") + raise Exit(code=1) diff --git a/tasks/gotest.py b/tasks/gotest.py index 7ca411e7521ea..4aa9a4b3e151f 100644 --- a/tasks/gotest.py +++ b/tasks/gotest.py @@ -11,7 +11,6 @@ import os import re import sys -import traceback from collections import defaultdict from collections.abc import Iterable from datetime import datetime @@ -22,13 +21,10 @@ from invoke.context import Context from invoke.exceptions import Exit -from tasks.agent import integration_tests as agent_integration_tests from tasks.build_tags import compute_build_tags_for_flavor -from tasks.cluster_agent import integration_tests as dca_integration_tests from tasks.collector import OCB_VERSION from tasks.coverage import PROFILE_COV, CodecovWorkaround from tasks.devcontainer import run_on_devcontainer -from tasks.dogstatsd import integration_tests as dsd_integration_tests from tasks.flavor import AgentFlavor from tasks.libs.common.color import color_message from tasks.libs.common.datadog_api import create_count, send_metrics @@ -36,7 +32,6 @@ from tasks.libs.common.gomodules import get_default_modules from tasks.libs.common.junit_upload_core import enrich_junitxml, produce_junit_tar from tasks.libs.common.utils import ( - TestsNotSupportedError, clean_nested_paths, get_build_flags, gitlab_section, @@ -46,7 +41,6 @@ from tasks.modules import GoModule, get_module_by_path from tasks.test_core import ModuleTestResult, process_input_args, process_module_results, test_core from tasks.testwasher import TestWasher -from tasks.trace_agent import integration_tests as trace_integration_tests from tasks.update_go import PATTERN_MAJOR_MINOR_BUGFIX GO_TEST_RESULT_TMP_JSON = 'module_test_output.json' @@ -405,36 +399,6 @@ def test( print(f"Tests final status (including re-runs): {color_message('ALL TESTS PASSED', 'green')}") -@task -def integration_tests(ctx, race=False, remote_docker=False, timeout=""): - """ - Run all the available integration tests - """ - tests = { - "Agent": lambda: agent_integration_tests(ctx, race=race, remote_docker=remote_docker, timeout=timeout), - "DogStatsD": lambda: dsd_integration_tests(ctx, race=race, remote_docker=remote_docker, timeout=timeout), - "Cluster Agent": lambda: dca_integration_tests(ctx, race=race, remote_docker=remote_docker, timeout=timeout), - "Trace Agent": lambda: trace_integration_tests(ctx, race=race, timeout=timeout), - } - tests_failures = {} - for t_name, t in tests.items(): - with gitlab_section(f"Running the {t_name} integration tests", collapsed=True, echo=True): - try: - t() - except TestsNotSupportedError as e: - print(f"Skipping {t_name}: {e}") - except Exception: - # Keep printing the traceback not to have to wait until all tests are done to see what failed - traceback.print_exc() - # Storing the traceback to print it at the end without directly raising the exception - tests_failures[t_name] = traceback.format_exc() - if tests_failures: - print("Integration tests failed:") - for t_name, t_failure in tests_failures.items(): - print(f"{t_name}:\n{t_failure}") - raise Exit(code=1) - - @task def e2e_tests(ctx, target="gitlab", agent_image="", dca_image="", argo_workflow="default"): """ diff --git a/tasks/issue.py b/tasks/issue.py index 4cd05c97abcdc..4615d39716dae 100644 --- a/tasks/issue.py +++ b/tasks/issue.py @@ -25,9 +25,7 @@ def assign_owner(_, issue_id, dry_run=False): from slack_sdk import WebClient client = WebClient(os.environ['SLACK_API_TOKEN']) - channel = next( - (chan for team, chan in GITHUB_SLACK_MAP.items() if owner.lower() in team), '#agent-ask-anything' - ) + channel = next((chan for team, chan in GITHUB_SLACK_MAP.items() if owner.lower() in team), '#agent-devx-help') message = f':githubstatus_partial_outage: *New Community Issue*\n{issue.title} <{issue.html_url}|{gh.repo.name}#{issue_id}>\n' if channel == '#agent-ask-anything': message += "The CI bot failed to assign this issue to a team.\nPlease assign it manually." diff --git a/tasks/libs/ciproviders/github_api.py b/tasks/libs/ciproviders/github_api.py index a32546d23ee38..8a4d5e69027d1 100644 --- a/tasks/libs/ciproviders/github_api.py +++ b/tasks/libs/ciproviders/github_api.py @@ -523,6 +523,9 @@ def create_label(self, name, color, description=""): """ return self._repository.create_label(name, color, description) + def create_milestone(self, title): + self._repository.create_milestone(title) + def create_release(self, tag, message, draft=True): return self._repository.create_git_release( tag=tag, diff --git a/tasks/libs/ciproviders/gitlab_api.py b/tasks/libs/ciproviders/gitlab_api.py index cb4e42644e7c6..adfd8aacfb569 100644 --- a/tasks/libs/ciproviders/gitlab_api.py +++ b/tasks/libs/ciproviders/gitlab_api.py @@ -1258,19 +1258,27 @@ def full_config_get_all_stages(full_config: dict) -> set[str]: return all_stages -def update_test_infra_def(file_path, image_tag): +def update_test_infra_def(file_path, image_tag, is_dev_image=False): """ - Override TEST_INFRA_DEFINITIONS_BUILDIMAGES in `.gitlab/common/test_infra_version.yml` file + Updates TEST_INFRA_DEFINITIONS_BUILDIMAGES in `.gitlab/common/test_infra_version.yml` file """ - with open(file_path) as gl: - file_content = gl.readlines() - with open(file_path, "w") as gl: - for line in file_content: - test_infra_def = re.search(r"TEST_INFRA_DEFINITIONS_BUILDIMAGES:\s*(\w+)", line) - if test_infra_def: - gl.write(line.replace(test_infra_def.group(1), image_tag)) + import yaml + + test_infra_def = {} + with open(file_path) as test_infra_version_file: + try: + test_infra_def = yaml.safe_load(test_infra_version_file) + test_infra_def["variables"]["TEST_INFRA_DEFINITIONS_BUILDIMAGES"] = image_tag + if is_dev_image: + test_infra_def["variables"]["TEST_INFRA_DEFINITIONS_BUILDIMAGES_SUFFIX"] = "-dev" else: - gl.write(line) + test_infra_def["variables"]["TEST_INFRA_DEFINITIONS_BUILDIMAGES_SUFFIX"] = "" + except yaml.YAMLError as e: + raise Exit(f"Error while loading {file_path}: {e}") from e + with open(file_path, "w") as test_infra_version_file: + # Add explicit_start=True to keep the document start marker --- + # See "Document Start" in https://www.yaml.info/learn/document.html for more details + yaml.dump(test_infra_def, test_infra_version_file, explicit_start=True) def update_gitlab_config(file_path, tag, images="", test=True, update=True): diff --git a/tasks/libs/common/git.py b/tasks/libs/common/git.py index dfff77eda03f7..b1dc1b1cd7683 100644 --- a/tasks/libs/common/git.py +++ b/tasks/libs/common/git.py @@ -1,8 +1,11 @@ from __future__ import annotations import os +import subprocess +import sys import tempfile from contextlib import contextmanager +from time import sleep from typing import TYPE_CHECKING from invoke import Context @@ -161,25 +164,45 @@ def check_base_branch(branch, release_version): return branch == get_default_branch() or branch == release_version.branch() -def try_git_command(ctx, git_command): - """ - Try a git command that should be retried (after user confirmation) if it fails. +def try_git_command(ctx, git_command, non_interactive_retries=2, non_interactive_delay=5): + """Try a git command that should be retried (after user confirmation) if it fails. Primarily useful for commands which can fail if commit signing fails: we don't want the whole workflow to fail if that happens, we want to retry. + + Args: + ctx: The invoke context. + git_command: The git command to run. + non_interactive_retries: The number of times to retry the command if it fails when running non-interactively. + non_interactive_delay: The delay in seconds to retry the command if it fails when running non-interactively. """ do_retry = True + n_retries = 0 + interactive = sys.stdin.isatty() while do_retry: res = ctx.run(git_command, warn=True) if res.exited is None or res.exited > 0: - print( - color_message( - f"Failed to run \"{git_command}\" (did the commit/tag signing operation fail?)", - "orange", + if interactive: + print( + color_message( + f"Failed to run \"{git_command}\" (did the commit/tag signing operation fail?)", + "orange", + ) ) - ) - do_retry = yes_no_question("Do you want to retry this operation?", color="orange", default=True) + do_retry = yes_no_question("Do you want to retry this operation?", color="orange", default=True) + else: + # Non interactive, retry in `non_interactive_delay` seconds if we haven't reached the limit + n_retries += 1 + if n_retries > non_interactive_retries: + print(f'{color_message("Error", Color.RED)}: Failed to run git command', file=sys.stderr) + return False + + print( + f'{color_message("Warning", Color.ORANGE)}: Retrying git command in {non_interactive_delay}s', + file=sys.stderr, + ) + sleep(non_interactive_delay) continue return True @@ -270,3 +293,20 @@ def get_last_release_tag(ctx, repo, pattern): last_tag_name = last_tag_name_with_suffix.removesuffix("^{}") last_tag_name = last_tag_name.removeprefix("refs/tags/") return last_tag_commit, last_tag_name + + +def get_git_config(key): + result = subprocess.run(['git', 'config', '--get', key], capture_output=True, text=True) + return result.stdout.strip() if result.returncode == 0 else None + + +def set_git_config(key, value): + subprocess.run(['git', 'config', key, value]) + + +def revert_git_config(original_config): + for key, value in original_config.items(): + if value is None: + subprocess.run(['git', 'config', '--unset', key]) + else: + subprocess.run(['git', 'config', key, value]) diff --git a/tasks/libs/common/gomodules.py b/tasks/libs/common/gomodules.py index bd37387a010a2..e4805588f73f5 100644 --- a/tasks/libs/common/gomodules.py +++ b/tasks/libs/common/gomodules.py @@ -252,8 +252,13 @@ def tag(self, agent_version): >>> [mod.tag("7.27.0") for mod in mods] [["7.27.0"], ["pkg/util/log/v0.27.0"]] """ + from invoke import Context + + from tasks.libs.common.git import is_agent6 + + major = "6" if is_agent6(Context()) else "7" if self.path == ".": - return ["7" + agent_version[1:]] + return [major + agent_version[1:]] return [f"{self.path}/{self.__version(agent_version)}"] diff --git a/tasks/libs/common/worktree.py b/tasks/libs/common/worktree.py index e8c9d740f07bc..17e5db4abfc97 100644 --- a/tasks/libs/common/worktree.py +++ b/tasks/libs/common/worktree.py @@ -9,7 +9,7 @@ from contextlib import contextmanager from pathlib import Path -from invoke.exceptions import Exit +from invoke.exceptions import Exit, UnexpectedExit from tasks.libs.common.color import Color, color_message from tasks.libs.common.git import get_current_branch @@ -49,7 +49,18 @@ def init_env(ctx, branch: str | None = None): f"git -C '{WORKTREE_DIRECTORY}' rev-parse --abbrev-ref HEAD", hide=True ).stdout.strip() if worktree_branch != branch: - ctx.run(f"git -C '{WORKTREE_DIRECTORY}' checkout '{branch}'", hide=True) + for retry in range(2): + try: + ctx.run(f"git -C '{WORKTREE_DIRECTORY}' checkout '{branch}'", hide=True) + except UnexpectedExit as e: + if retry == 1: + raise e + else: + print( + f'{color_message("Warning", Color.ORANGE)}: Git branch not found in the local worktree folder, fetching repository', + file=sys.stderr, + ) + ctx.run(f"git -C '{WORKTREE_DIRECTORY}' fetch", hide=True) if not os.environ.get("AGENT_WORKTREE_NO_PULL"): ctx.run(f"git -C '{WORKTREE_DIRECTORY}' pull", hide=True) diff --git a/tasks/pipeline.py b/tasks/pipeline.py index bff7b05b8b1ab..ad825bee1540d 100644 --- a/tasks/pipeline.py +++ b/tasks/pipeline.py @@ -43,11 +43,9 @@ # Tasks to trigger pipelines -def check_deploy_pipeline(repo: Project, git_ref: str, release_version_6, release_version_7, repo_branch): +def check_deploy_pipeline(repo_branch): """ - Run checks to verify a deploy pipeline is valid: - - it targets a valid repo branch - - it has matching Agent 6 and Agent 7 tags (depending on release_version_* values) + Run checks to verify a deploy pipeline is valid (it targets a valid repo branch) """ # Check that the target repo branch is valid @@ -57,41 +55,6 @@ def check_deploy_pipeline(repo: Project, git_ref: str, release_version_6, releas ) raise Exit(code=1) - # - # If git_ref matches v7 pattern and release_version_6 is not empty, make sure Gitlab has v6 tag. - # If git_ref matches v6 pattern and release_version_7 is not empty, make sure Gitlab has v7 tag. - # v7 version pattern should be able to match 7.12.24-rc2 and 7.12.34 - # - v7_pattern = r'^7\.(\d+\.\d+)(-.+|)$' - v6_pattern = r'^6\.(\d+\.\d+)(-.+|)$' - - match = re.match(v7_pattern, git_ref) - - # TODO(@spencergilbert): remove cross reference check when all references to a6 are removed - if release_version_6 and match: - # release_version_6 is not empty and git_ref matches v7 pattern, construct v6 tag and check. - tag_name = "6." + "".join(match.groups()) - try: - repo.tags.get(tag_name) - except GitlabError: - print(f"Cannot find GitLab v6 tag {tag_name} while trying to build git ref {git_ref}") - print("v6 tags are no longer created, this check will be removed in a later commit") - - print(f"Successfully cross checked v6 tag {tag_name} and git ref {git_ref}") - else: - match = re.match(v6_pattern, git_ref) - - if release_version_7 and match: - # release_version_7 is not empty and git_ref matches v6 pattern, construct v7 tag and check. - tag_name = "7." + "".join(match.groups()) - try: - repo.tags.get(tag_name) - except GitlabError as e: - print(f"Cannot find GitLab v7 tag {tag_name} while trying to build git ref {git_ref}") - raise Exit(code=1) from e - - print(f"Successfully cross checked v7 tag {tag_name} and git ref {git_ref}") - @task def clean_running_pipelines(ctx, git_ref=None, here=False, use_latest_sha=False, sha=None): @@ -168,6 +131,9 @@ def auto_cancel_previous_pipelines(ctx): raise Exit("GITLAB_TOKEN variable needed to cancel pipelines on the same ref.", 1) git_ref = os.environ["CI_COMMIT_REF_NAME"] + if git_ref == "": + raise Exit("CI_COMMIT_REF_NAME is empty, skipping pipeline cancellation", 0) + git_sha = os.getenv("CI_COMMIT_SHA") repo = get_gitlab_repo() @@ -292,7 +258,7 @@ def run( if deploy or deploy_installer: # Check the validity of the deploy pipeline - check_deploy_pipeline(repo, git_ref, release_version_6, release_version_7, repo_branch) + check_deploy_pipeline(repo_branch) # Force all builds and e2e tests to be run if not all_builds: print( diff --git a/tasks/release.py b/tasks/release.py index b91e4a48742a6..077834b279923 100644 --- a/tasks/release.py +++ b/tasks/release.py @@ -34,6 +34,7 @@ get_last_commit, get_last_release_tag, is_agent6, + set_git_config, try_git_command, ) from tasks.libs.common.gomodules import get_default_modules @@ -84,16 +85,21 @@ BACKPORT_LABEL_COLOR = "5319e7" -def deduce_and_ask_version(ctx, branch, as_str=True, trust=False) -> str | Version: +def deduce_version(ctx, branch, as_str=True, trust=False) -> str | Version: release_version = get_next_version_from_branch(ctx, branch, as_str=as_str) - if trust: - return release_version + print( + f'{color_message("Info", Color.BLUE)}: Version {release_version} deduced from branch {branch}', file=sys.stderr + ) - if not os.isatty(sys.stdin.fileno()) or yes_no_question( - f'Version {release_version} deduced from branch {branch}. Is this the version you want to use?', - color="orange", - default=False, + if ( + trust + or not os.isatty(sys.stdin.fileno()) + or yes_no_question( + 'Is this the version you want to use?', + color="orange", + default=False, + ) ): return release_version @@ -170,7 +176,7 @@ def update_modules(ctx, release_branch=None, version=None, trust=False): assert release_branch or version - agent_version = version or deduce_and_ask_version(ctx, release_branch, trust=trust) + agent_version = version or deduce_version(ctx, release_branch, trust=trust) with agent_context(ctx, release_branch, skip_checkout=release_branch is None): modules = get_default_modules() @@ -235,7 +241,7 @@ def tag_modules( assert release_branch or version - agent_version = version or deduce_and_ask_version(ctx, release_branch, trust=trust) + agent_version = version or deduce_version(ctx, release_branch, trust=trust) tags = [] with agent_context(ctx, release_branch, skip_checkout=release_branch is None): @@ -274,7 +280,7 @@ def tag_version( assert release_branch or version - agent_version = version or deduce_and_ask_version(ctx, release_branch, trust=trust) + agent_version = version or deduce_version(ctx, release_branch, trust=trust) # Always tag the main module force_option = __get_force_option(force) @@ -427,11 +433,16 @@ def create_rc(ctx, release_branch, patch_version=False, upstream="origin", slack This also requires that there are no local uncommitted changes, that the current branch is 'main' or the release branch, and that no branch named 'release/' already exists locally or upstream. """ - major_version = get_version_major(release_branch) with agent_context(ctx, release_branch): github = GithubAPI(repository=GITHUB_REPO_NAME) + github_action = os.environ.get("GITHUB_ACTIONS") + + if github_action: + set_git_config('user.name', 'github-actions[bot]') + set_git_config('user.email', 'github-actions[bot]@users.noreply.github.com') + upstream = f"https://x-access-token:{os.environ.get('GITHUB_TOKEN')}@github.com/{GITHUB_REPO_NAME}.git" # Get the version of the highest major: useful for some logging & to get # the version to use for Go submodules updates @@ -463,12 +474,6 @@ def create_rc(ctx, release_branch, patch_version=False, upstream="origin", slack # Step 1: Update release entries print(color_message("Updating release entries", "bold")) new_version = next_rc_version(ctx, major_version, patch_version) - if not yes_no_question( - f'Do you want to create release candidate with:\n- new version: {new_version}\n- new highest version: {new_highest_version}\n- new final version: {new_final_version}?', - color="bold", - default=False, - ): - raise Exit(color_message("Aborting.", "red"), code=1) update_release_json(new_version, new_final_version) @@ -492,7 +497,9 @@ def create_rc(ctx, release_branch, patch_version=False, upstream="origin", slack ctx.run("git ls-files . | grep 'go.mod$' | xargs git add") ok = try_git_command( - ctx, f"git commit --no-verify -m 'Update release.json and Go modules for {new_highest_version}'" + ctx, + f"git commit --no-verify -m 'Update release.json and Go modules for {new_highest_version}'", + github_action, ) if not ok: raise Exit( @@ -724,10 +731,8 @@ def create_release_branches(ctx, base_directory="~/dd", major_version: int = 7, github = GithubAPI(repository=GITHUB_REPO_NAME) current = current_version(ctx, major_version) - next = current.next_version(bump_minor=True) current.rc = False current.devel = False - next.devel = False # Strings with proper branch/tag names release_branch = current.branch() @@ -765,43 +770,7 @@ def create_release_branches(ctx, base_directory="~/dd", major_version: int = 7, ) # Step 2 - Create PRs with new settings in datadog-agent repository - # Step 2.0 - Create milestone update - milestone_branch = f"release_milestone-{int(time.time())}" - ctx.run(f"git switch -c {milestone_branch}") - rj = load_release_json() - rj["current_milestone"] = f"{next}" - _save_release_json(rj) - # Commit release.json - ctx.run("git add release.json") - ok = try_git_command(ctx, f"git commit -m 'Update release.json with current milestone to {next}'") - - if not ok: - raise Exit( - color_message( - f"Could not create commit. Please commit manually and push the commit to the {milestone_branch} branch.", - "red", - ), - code=1, - ) - - res = ctx.run(f"git push --set-upstream {upstream} {milestone_branch}", warn=True) - if res.exited is None or res.exited > 0: - raise Exit( - color_message( - f"Could not push branch {milestone_branch} to the upstream '{upstream}'. Please push it manually and then open a PR against {release_branch}.", - "red", - ), - code=1, - ) - - create_release_pr( - f"[release] Update current milestone to {next}", - get_default_branch(), - milestone_branch, - next, - ) - - # Step 2.1 - Update release.json + # Step 2.0 - Update release.json update_branch = f"{release_branch}-updates" ctx.run(f"git checkout {release_branch}") @@ -1257,7 +1226,7 @@ def create_github_release(ctx, release_branch, draft=True): ) notes = [] - version = deduce_and_ask_version(ctx, release_branch) + version = deduce_version(ctx, release_branch) with agent_context(ctx, release_branch): for section, filename in sections: @@ -1296,3 +1265,63 @@ def create_github_release(ctx, release_branch, draft=True): ) print(f"Link to the release note: {release.html_url}") + + +@task +def update_current_milestone(ctx, major_version: int = 7, upstream="origin"): + """ + Create a PR to bump the current_milestone in the release.json file + """ + import github + + gh = GithubAPI() + + current = current_version(ctx, major_version) + next = current.next_version(bump_minor=True) + next.devel = False + + print(f"Creating the {next} milestone...") + + try: + gh.create_milestone(str(next)) + except github.GithubException as e: + if e.status == 422: + print(f"Milestone {next} already exists") + else: + raise e + + with agent_context(ctx, get_default_branch(major=major_version)): + milestone_branch = f"release_milestone-{int(time.time())}" + ctx.run(f"git switch -c {milestone_branch}") + rj = load_release_json() + rj["current_milestone"] = f"{next}" + _save_release_json(rj) + # Commit release.json + ctx.run("git add release.json") + ok = try_git_command(ctx, f"git commit -m 'Update release.json with current milestone to {next}'") + + if not ok: + raise Exit( + color_message( + f"Could not create commit. Please commit manually and push the commit to the {milestone_branch} branch.", + Color.RED, + ), + code=1, + ) + + res = ctx.run(f"git push --set-upstream {upstream} {milestone_branch}", warn=True) + if res.exited is None or res.exited > 0: + raise Exit( + color_message( + f"Could not push branch {milestone_branch} to the upstream '{upstream}'. Please push it manually and then open a PR against main.", + Color.RED, + ), + code=1, + ) + + create_release_pr( + f"[release] Update current milestone to {next}", + get_default_branch(), + milestone_branch, + next, + ) diff --git a/tasks/trace_agent.py b/tasks/trace_agent.py index d65ae6861fcd8..0ec1dd1956aa8 100644 --- a/tasks/trace_agent.py +++ b/tasks/trace_agent.py @@ -5,7 +5,8 @@ from tasks.build_tags import add_fips_tags, filter_incompatible_tags, get_build_tags, get_default_build_tags from tasks.flavor import AgentFlavor -from tasks.libs.common.utils import REPO_PATH, TestsNotSupportedError, bin_name, get_build_flags +from tasks.gointegrationtest import TRACE_AGENT_IT_CONF, containerized_integration_tests +from tasks.libs.common.utils import REPO_PATH, bin_name, get_build_flags from tasks.windows_resources import build_messagetable, build_rc, versioninfo_vars BIN_PATH = os.path.join(".", "bin", "trace-agent") @@ -81,15 +82,14 @@ def integration_tests(ctx, race=False, go_mod="readonly", timeout="10m"): """ Run integration tests for trace agent """ - if sys.platform == 'win32': - raise TestsNotSupportedError('Trace Agent integration tests are not supported on Windows') - - go_build_tags = " ".join(get_default_build_tags(build="test")) - race_opt = "-race" if race else "" - timeout_opt = f"-timeout {timeout}" if timeout else "" - - go_cmd = f'go test {timeout_opt} -mod={go_mod} {race_opt} -v -tags "{go_build_tags}"' - ctx.run(f"{go_cmd} ./cmd/trace-agent/test/testsuite/...", env={"INTEGRATION": "yes"}) + containerized_integration_tests( + ctx, + TRACE_AGENT_IT_CONF, + race=race, + remote_docker=False, + go_mod=go_mod, + timeout=timeout, + ) @task diff --git a/tasks/winbuildscripts/Generate-Chocolatey-Package.ps1 b/tasks/winbuildscripts/Generate-Chocolatey-Package.ps1 index 9780b4a3a4103..991317602152f 100644 --- a/tasks/winbuildscripts/Generate-Chocolatey-Package.ps1 +++ b/tasks/winbuildscripts/Generate-Chocolatey-Package.ps1 @@ -1,97 +1,185 @@ +<# +.SYNOPSIS +Generates a Chocolatey package for the Datadog Agent. + +.PARAMETER installMethod +Specifies the installation method. Valid values are "offline" and "online". This parameter is mandatory. + +.PARAMETER msiDirectory +Specifies the directory containing the MSI file that will be used to calculate the checksum. This parameter is mandatory when the installMethod is "online". + +.PARAMETER Flavor +Specifies the flavor of the Datadog Agent. The default value is "datadog-agent". + +.PARAMETER VersionOverride +Overrides the Agent version when building packages locally for testing. + +.PARAMETER InstallDeps +Indicates whether to install dependencies. The default value is $true. + +.EXAMPLE +.\Generate-Chocolatey-Package.ps1 -installMethod online -Flavor datadog-agent -VersionOverride "7.62.0" -msiDirectory C:\mnt\omnibus\pkg\ + +Generates a chocolatey package for 7.62.0, requires the MSI file to be present in MSIDirectory. + +.EXAMPLE +$env:CI_PIPELINE_ID="50910739"; .\Generate-Chocolatey-Package.ps1 -installMethod online -Flavor datadog-agent -VersionOverride "7.62.0-devel.git.276.e59b1b3.pipeline.50910739" -msiDirectory C:\mnt\omnibus\pkg + +Generates a chocolatey package for PR/devel build 7.62.0-devel.git.276.e59b1b3.pipeline.50910739, requires the MSI file to be present in MSIDirectory. +The generated chocolatey package requires the MSI be uploaded to the dd-agent-mstesting bucket. +#> Param( - [Parameter(Mandatory=$true,Position=0)] + [Parameter(Mandatory=$true)] [ValidateSet("offline", "online")] [String] $installMethod, - [Parameter(Mandatory=$false,Position=1)] - [String] - $msiDirectory + [Parameter(Mandatory=$false)] + [String] + $msiDirectory, + + [Parameter(Mandatory=$false)] + [ValidateSet("datadog-agent", "datadog-fips-agent")] + [String] + $Flavor = "datadog-agent", + + [Parameter(Mandatory=$false)] + [String] + $VersionOverride, + + [bool] $InstallDeps = $true ) $ErrorActionPreference = 'Stop'; Set-Location c:\mnt -# Install chocolatey binary -$env:chocolateyUseWindowsCompression = 'true'; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) - -# Install dev tools, including invoke -pip3 install -r requirements.txt +if ($InstallDeps) { + # Install chocolatey + $env:chocolateyUseWindowsCompression = 'true'; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) + # Install dev tools, including invoke + pip3 install -r requirements.txt +} -$outputDirectory = "c:\mnt\build-out" -$rawAgentVersion = (inv agent.version --url-safe --major-version 7) +$repoRoot = "C:\mnt" +$outputDirectory = "$repoRoot\build-out" +if (![string]::IsNullOrEmpty($VersionOverride)) { + $rawAgentVersion = $VersionOverride +} else { + $rawAgentVersion = (inv agent.version --url-safe --major-version 7) +} $copyright = "Datadog {0}" -f (Get-Date).Year $releasePattern = "(\d+\.\d+\.\d+)" $releaseCandidatePattern = "(\d+\.\d+\.\d+)-rc\.(\d+)" $develPattern = "(\d+\.\d+\.\d+)-devel\.git\.\d+\.(.+)" -$nuspecFile = "c:\mnt\chocolatey\datadog-agent-online.nuspec" -$licensePath = "c:\mnt\chocolatey\tools-online\LICENSE.txt" -$installScript = "c:\mnt\chocolatey\tools-online\chocolateyinstall.ps1" - -if ($installMethod -eq "offline") { - $nuspecFile = "c:\mnt\chocolatey\datadog-agent-offline.nuspec" - $licensePath = "c:\mnt\chocolatey\tools-offline\LICENSE.txt" +# Build the package in a temporary directory +# Some of the build steps modify the package source, so we don't want to do this in the source directory +$buildTempDir = [System.IO.Path]::GetTempPath() + "\datadog-choco-build" +if (Test-Path $buildTempDir) { + Remove-Item -Recurse -Force $buildTempDir } - -if ($rawAgentVersion -match $releaseCandidatePattern) { - $agentVersionMatches = $rawAgentVersion | Select-String -Pattern $releaseCandidatePattern - $agentVersion = "{0}-rc-{1}" -f $agentVersionMatches.Matches.Groups[1], $agentVersionMatches.Matches.Groups[2].Value - # We don't have release notes for RCs but this way the user can always see what commits are included in this RC - $releaseNotes = "https://github.com/DataDog/datadog-agent/releases/tag/{0}-rc.{1}" -f $agentVersionMatches.Matches.Groups[1], $agentVersionMatches.Matches.Groups[2] - $url = "https://s3.amazonaws.com/dd-agent-mstesting/builds/beta/ddagent-cli-$($agentVersionMatches.Matches.Groups[1])-rc.$($agentVersionMatches.Matches.Groups[2]).msi" -} elseif ($rawAgentVersion -match $develPattern) { - if ($installMethod -eq "online") { - # We don't publish online chocolatey packages for dev branches, error out - Write-Host "Chocolatey packages are not built for dev branches aborting" - exit 2 +New-Item -ItemType Directory -Path $buildTempDir | Out-Null +Push-Location -Path $buildTempDir +try { + # Set the artifact name and package source based on the flavor + if ($Flavor -eq "datadog-agent") { + # For historical reasons, use a different artifact name for the datadog-agent flavor + # See agent-release-management for more details + $artifactName = "ddagent-cli" + $packageSource = "$repoRoot\chocolatey\datadog-agent\$installMethod" + $nuspecFile = "datadog-agent-$installMethod.nuspec" + } elseif ($Flavor -eq "datadog-fips-agent") { + if ($installMethod -eq "offline") { + Write-Error "Offline install method not supported for flavor $Flavor" + exit 1 + } + $artifactName = "datadog-fips-agent" + $packageSource = "$repoRoot\chocolatey\datadog-fips-agent\online" + $nuspecFile = "datadog-fips-agent-online.nuspec" + } else { + Write-Error "Unknown flavor $Flavor" + exit 1 } - $agentVersionMatches = $rawAgentVersion | Select-String -Pattern $develPattern - $agentVersion = "{0}-devel-{1}" -f $agentVersionMatches.Matches.Groups[1], $agentVersionMatches.Matches.Groups[2].Value - # We don't have release notes for devel, so point it to the generic url - $releaseNotes = "https://github.com/DataDog/datadog-agent/releases" -} elseif ($rawAgentVersion -match $releasePattern) { - $agentVersionMatches = $rawAgentVersion | Select-String -Pattern $releasePattern - $agentVersion = $agentVersionMatches.Matches.Groups[1].Value - $releaseNotes = "https://github.com/DataDog/datadog-agent/releases/tag/$agentVersion" - $url = "https://s3.amazonaws.com/ddagent-windows-stable/ddagent-cli-$($agentVersion).msi" -} else { - Write-Host "Unknown agent version '$rawAgentVersion', aborting" - exit 3 -} -Invoke-WebRequest -Uri "https://raw.githubusercontent.com/DataDog/datadog-agent/main/LICENSE" -OutFile $licensePath - -Write-Host "Generating Chocolatey $installMethod package version $agentVersion in $outputDirectory" + # These files/directories are referenced in the nuspec file + $licensePath = "tools\LICENSE.txt" + $installScript = "tools\chocolateyinstall.ps1" + + # Copy package source to build temp dir + Copy-Item -Recurse -Force -Path $packageSource\* -Destination $buildTempDir + Copy-Item -Force -Path $repoRoot\LICENSE -Destination $licensePath + + # Generate URLs based on the Agent version + if ($rawAgentVersion -match $releaseCandidatePattern) { + $agentVersionMatches = $rawAgentVersion | Select-String -Pattern $releaseCandidatePattern + $agentVersion = "{0}-rc-{1}" -f $agentVersionMatches.Matches.Groups[1], $agentVersionMatches.Matches.Groups[2].Value + # We don't have release notes for RCs but this way the user can always see what commits are included in this RC + $releaseNotes = "https://github.com/DataDog/datadog-agent/releases/tag/{0}-rc.{1}" -f $agentVersionMatches.Matches.Groups[1], $agentVersionMatches.Matches.Groups[2] + $url = "https://s3.amazonaws.com/dd-agent-mstesting/builds/beta/$artifactName-$($agentVersionMatches.Matches.Groups[1])-rc.$($agentVersionMatches.Matches.Groups[2]).msi" + } elseif ($rawAgentVersion -match $develPattern) { + if ($installMethod -eq "online") { + # For devel builds/branches, use the dd-agent-mstesting bucket URL + # This allows us to build and test the package in PRs, and locally + # by using the `-VersionOverride` param. + if ([string]::IsNullOrEmpty($env:CI_PIPELINE_ID)) { + Write-Error "CI_PIPELINE_ID is not set, aborting" + exit 1 + } else { + if ($rawAgentVersion -notmatch $env:CI_PIPELINE_ID) { + Write-Error "CI_PIPELINE_ID is not found in the agent version, aborting" -ErrorAction Continue + if ([string]::IsNullOrEmpty($env:BUCKET_BRANCH)) { + # inv agent.version requires BUCKET_BRANCH to be set when including pipeline in version + Write-Error "BUCKET_BRANCH is not set, if you are running this locally, set `$env:BUCKET_BRANCH='dev' or pass the -VersionOverride parameter" -ErrorAction Continue + } + exit 1 + } + $url = "https://s3.amazonaws.com/dd-agent-mstesting/pipelines/A7/$env:CI_PIPELINE_ID/$flavor-$rawAgentVersion-1-x86_64.msi" + } + } + $agentVersionMatches = $rawAgentVersion | Select-String -Pattern $develPattern + $agentVersion = "{0}-devel-{1}" -f $agentVersionMatches.Matches.Groups[1], $agentVersionMatches.Matches.Groups[2].Value + # We don't have release notes for devel, so point it to the generic url + $releaseNotes = "https://github.com/DataDog/datadog-agent/releases" + } elseif ($rawAgentVersion -match $releasePattern) { + $agentVersionMatches = $rawAgentVersion | Select-String -Pattern $releasePattern + $agentVersion = $agentVersionMatches.Matches.Groups[1].Value + $releaseNotes = "https://github.com/DataDog/datadog-agent/releases/tag/$agentVersion" + $url = "https://s3.amazonaws.com/ddagent-windows-stable/$artifactName-$($agentVersion).msi" + } else { + Write-Host "Unknown agent version '$rawAgentVersion', aborting" + exit 1 + } -if (!(Test-Path $outputDirectory)) { - New-Item -ItemType Directory -Path $outputDirectory -} + Write-Host "Generating Chocolatey $installMethod package $flavor version $agentVersion in $(Get-Location)" -if ($installMethod -eq "online") { - try { - $tempMsi = Join-Path -Path "$msiDirectory" "datadog-agent-$rawAgentVersion-1-x86_64.msi" - if (!(Test-Path $tempMsi)) { - Write-Host "Error: Could not find MSI file in $tempMsi" - Get-ChildItem "$msiDirectory" - exit 1 + # Template the install script with the URL and checksum + if ($installMethod -eq "online") { + try { + $tempMsi = Join-Path -Path "$msiDirectory" "$flavor-$rawAgentVersion-1-x86_64.msi" + if (!(Test-Path $tempMsi)) { + Write-Host "Error: Could not find MSI file in $tempMsi" + Get-ChildItem "$msiDirectory" + exit 1 + } + $checksum = (Get-FileHash $tempMsi -Algorithm SHA256).Hash + } + catch { + Write-Host "Error: Could not generate checksum for package $($tempMsi): $($_)" + exit 1 } - $checksum = (Get-FileHash $tempMsi -Algorithm SHA256).Hash - } - catch { - Write-Host "Error: Could not generate checksum for package $($tempMsi): $($_)" - exit 4 + # Set the $url in the install script + (Get-Content $installScript).replace('$__url_from_ci__', '"' + $url + '"').replace('$__checksum_from_ci__', '"' + $checksum + '"') | Set-Content $installScript } - # Set the $url in the install script - (Get-Content $installScript).replace('$__url_from_ci__', '"' + $url + '"').replace('$__checksum_from_ci__', '"' + $checksum + '"') | Set-Content $installScript -} - -Write-Host "Generated nupsec file:" -Write-Host (Get-Content $installScript | Out-String) -Write-Host choco pack --out=$outputDirectory $nuspecFile --version $agentVersion release_notes=$releaseNotes copyright=$copyright -choco pack --out=$outputDirectory $nuspecFile --version $agentVersion release_notes=$releaseNotes copyright=$copyright + Write-Host "Generated nuspec file:" + Write-Host (Get-Content $installScript | Out-String) -# restore installScript (useful for local testing/deployment) -git checkout $installScript + if (!(Test-Path $outputDirectory)) { + New-Item -ItemType Directory -Path $outputDirectory + } + Write-Host choco pack --out=$outputDirectory $nuspecFile --version $agentVersion release_notes=$releaseNotes copyright=$copyright + choco pack --out=$outputDirectory $nuspecFile --version $agentVersion release_notes=$releaseNotes copyright=$copyright +} finally { + Pop-Location +} diff --git a/tasks/winbuildscripts/chocopack.bat b/tasks/winbuildscripts/chocopack.bat deleted file mode 100644 index df8915ae14698..0000000000000 --- a/tasks/winbuildscripts/chocopack.bat +++ /dev/null @@ -1,11 +0,0 @@ -if not exist c:\mnt\ goto nomntdir - -@echo c:\mnt found, continuing - -Powershell -C "C:\mnt\tasks\winbuildscripts\Generate-Chocolatey-Package.ps1 %1 %2" || exit /b 1 -goto :EOF - -:nomntdir -@echo directory not mounted, parameters incorrect -exit /b 2 -goto :EOF diff --git a/test/new-e2e/go.mod b/test/new-e2e/go.mod index 8b0a384191503..2bd2138c3ea69 100644 --- a/test/new-e2e/go.mod +++ b/test/new-e2e/go.mod @@ -45,7 +45,7 @@ replace ( require ( github.com/DataDog/agent-payload/v5 v5.0.138 github.com/DataDog/datadog-agent/comp/otelcol/ddflareextension/def v0.56.2 - github.com/DataDog/datadog-agent/pkg/util/optional v0.59.0 + github.com/DataDog/datadog-agent/pkg/util/optional v0.59.1 github.com/DataDog/datadog-agent/pkg/util/pointer v0.59.0 github.com/DataDog/datadog-agent/pkg/util/scrubber v0.59.0 github.com/DataDog/datadog-agent/pkg/util/testutil v0.56.2 @@ -58,20 +58,20 @@ require ( // `TEST_INFRA_DEFINITIONS_BUILDIMAGES` matches the commit sha in the module version // Example: github.com/DataDog/test-infra-definitions v0.0.0-YYYYMMDDHHmmSS-0123456789AB // => TEST_INFRA_DEFINITIONS_BUILDIMAGES: 0123456789AB - github.com/DataDog/test-infra-definitions v0.0.0-20241211124138-9c7c5005ca28 - github.com/aws/aws-sdk-go-v2 v1.32.5 - github.com/aws/aws-sdk-go-v2/config v1.28.5 + github.com/DataDog/test-infra-definitions v0.0.0-20241217110507-4b4112f5f64d + github.com/aws/aws-sdk-go-v2 v1.32.6 + github.com/aws/aws-sdk-go-v2/config v1.28.6 github.com/aws/aws-sdk-go-v2/service/ec2 v1.190.0 - github.com/aws/aws-sdk-go-v2/service/eks v1.44.1 - github.com/aws/aws-sdk-go-v2/service/ssm v1.50.7 + github.com/aws/aws-sdk-go-v2/service/eks v1.51.0 + github.com/aws/aws-sdk-go-v2/service/ssm v1.55.2 github.com/cenkalti/backoff v2.2.1+incompatible - github.com/docker/cli v27.1.1+incompatible - github.com/docker/docker v27.3.1+incompatible + github.com/docker/cli v27.4.0+incompatible + github.com/docker/docker v27.4.0+incompatible github.com/fatih/color v1.18.0 github.com/google/uuid v1.6.0 github.com/kr/pretty v0.3.1 github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c - github.com/pkg/sftp v1.13.6 + github.com/pkg/sftp v1.13.7 github.com/pulumi/pulumi-aws/sdk/v6 v6.56.1 github.com/pulumi/pulumi-awsx/sdk/v2 v2.16.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.18.3 @@ -84,8 +84,8 @@ require ( golang.org/x/term v0.27.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/zorkian/go-datadog-api.v2 v2.30.0 - k8s.io/api v0.31.3 - k8s.io/apimachinery v0.31.3 + k8s.io/api v0.31.4 + k8s.io/apimachinery v0.31.4 k8s.io/cli-runtime v0.31.2 k8s.io/client-go v0.31.3 k8s.io/kubectl v0.31.2 @@ -109,23 +109,22 @@ require ( github.com/alessio/shellescape v1.4.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.46 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.47 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.19 // indirect - github.com/aws/aws-sdk-go-v2/service/ecr v1.36.2 // indirect - github.com/aws/aws-sdk-go-v2/service/ecs v1.47.4 + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 // indirect + github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7 // indirect + github.com/aws/aws-sdk-go-v2/service/ecs v1.52.2 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.0 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.65.0 - github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 // indirect github.com/aws/smithy-go v1.22.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect @@ -134,7 +133,6 @@ require ( github.com/charmbracelet/bubbles v0.18.0 // indirect github.com/charmbracelet/bubbletea v0.25.0 // indirect github.com/charmbracelet/lipgloss v0.10.0 // indirect - github.com/cheggaaa/pb v1.0.29 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/console v1.0.4 // indirect github.com/containerd/log v0.1.0 // indirect @@ -219,8 +217,8 @@ require ( github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect github.com/pulumi/esc v0.10.0 // indirect github.com/pulumi/pulumi-command/sdk v1.0.1 // indirect - github.com/pulumi/pulumi-docker/sdk/v4 v4.5.5 // indirect - github.com/pulumi/pulumi-libvirt/sdk v0.4.7 // indirect + github.com/pulumi/pulumi-docker/sdk/v4 v4.5.7 // indirect + github.com/pulumi/pulumi-libvirt/sdk v0.5.3 // indirect github.com/pulumi/pulumi-random/sdk/v4 v4.16.7 // indirect github.com/pulumi/pulumi-tls/sdk/v4 v4.11.1 // indirect github.com/pulumiverse/pulumi-time/sdk v0.1.0 // indirect @@ -284,16 +282,18 @@ require ( require ( github.com/DataDog/datadog-agent/comp/core/tagger/types v0.0.0-00010101000000-000000000000 github.com/DataDog/datadog-agent/pkg/trace v0.56.0-rc.3 - github.com/DataDog/datadog-go/v5 v5.5.0 + github.com/DataDog/datadog-go/v5 v5.6.0 github.com/aws/aws-sdk-go v1.55.5 - github.com/aws/session-manager-plugin v0.0.0-20241010233726-61cf1288c7c6 + github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 + github.com/aws/session-manager-plugin v0.0.0-20241119210807-82dc72922492 github.com/digitalocean/go-libvirt v0.0.0-20240812180835-9c6c0a310c6c - github.com/hairyhenderson/go-codeowners v0.5.0 + github.com/hairyhenderson/go-codeowners v0.7.0 ) require ( github.com/DataDog/datadog-agent/comp/core/tagger/utils v0.59.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cheggaaa/pb v1.0.29 // indirect github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect github.com/creack/pty v1.1.20 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect @@ -309,7 +309,7 @@ require ( github.com/pulumi/pulumi-azure-native-sdk/managedidentity/v2 v2.73.1 // indirect github.com/pulumi/pulumi-azure-native-sdk/network/v2 v2.73.1 // indirect github.com/pulumi/pulumi-azure-native-sdk/v2 v2.73.1 // indirect - github.com/pulumi/pulumi-eks/sdk/v3 v3.3.0 // indirect + github.com/pulumi/pulumi-eks/sdk/v3 v3.4.0 // indirect github.com/pulumi/pulumi-gcp/sdk/v7 v7.38.0 // indirect github.com/twinj/uuid v0.0.0-20151029044442-89173bcdda19 // indirect github.com/x448/float16 v0.8.4 // indirect diff --git a/test/new-e2e/go.sum b/test/new-e2e/go.sum index d8ba72c668e62..b08902fb2e378 100644 --- a/test/new-e2e/go.sum +++ b/test/new-e2e/go.sum @@ -13,12 +13,12 @@ github.com/DataDog/datadog-api-client-go v1.16.0 h1:5jOZv1m98criCvYTa3qpW8Hzv301 github.com/DataDog/datadog-api-client-go v1.16.0/go.mod h1:PgrP2ABuJWL3Auw2iEkemAJ/r72ghG4DQQmb5sgnKW4= github.com/DataDog/datadog-api-client-go/v2 v2.33.0 h1:OI6kDnJeQmkjfGzxmP0XUQUxMD4tp6oAPXnnJ4VpgUM= github.com/DataDog/datadog-api-client-go/v2 v2.33.0/go.mod h1:d3tOEgUd2kfsr9uuHQdY+nXrWp4uikgTgVCPdKNK30U= -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/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49 h1:EbzDX8HPk5uE2FsJYxD74QmMw0/3CqSKhEr6teh0ncQ= github.com/DataDog/mmh3 v0.0.0-20210722141835-012dc69a9e49/go.mod h1:SvsjzyJlSg0rKsqYgdcFxeEVflx3ZNAyFfkUHP0TxXg= -github.com/DataDog/test-infra-definitions v0.0.0-20241211124138-9c7c5005ca28 h1:LaZgAke+RN4wBKNl+R10ewdtKe/C2MJCbp9ozXKlLP8= -github.com/DataDog/test-infra-definitions v0.0.0-20241211124138-9c7c5005ca28/go.mod h1:blPG0VXBgk1oXm2+KHMTMyR0sNI2jv51FACAYPNQvNo= +github.com/DataDog/test-infra-definitions v0.0.0-20241217110507-4b4112f5f64d h1:F1yqGiWtXVsHkMiNUhs8bgaoZ1WlV3rYGRZ1CtCxpm8= +github.com/DataDog/test-infra-definitions v0.0.0-20241217110507-4b4112f5f64d/go.mod h1:1PAUwGjC25ACjfft4HrLEmHliuajlvjzcLFWpuqAIyk= github.com/DataDog/zstd v1.5.6 h1:LbEglqepa/ipmmQJUDnSsfvA8e8IStVcGaFWDuxvGOY= github.com/DataDog/zstd v1.5.6/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/DataDog/zstd_0 v0.0.0-20210310093942-586c1286621f h1:5Vuo4niPKFkfwW55jV4vY0ih3VQ9RaQqeqY67fvRn8A= @@ -52,52 +52,52 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.32.5 h1:U8vdWJuY7ruAkzaOdD7guwJjD06YSKmnKCJs7s3IkIo= -github.com/aws/aws-sdk-go-v2 v1.32.5/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA= -github.com/aws/aws-sdk-go-v2/config v1.28.5 h1:Za41twdCXbuyyWv9LndXxZZv3QhTG1DinqlFsSuvtI0= -github.com/aws/aws-sdk-go-v2/config v1.28.5/go.mod h1:4VsPbHP8JdcdUDmbTVgNL/8w9SqOkM5jyY8ljIxLO3o= -github.com/aws/aws-sdk-go-v2/credentials v1.17.46 h1:AU7RcriIo2lXjUfHFnFKYsLCwgbz1E7Mm95ieIRDNUg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.46/go.mod h1:1FmYyLGL08KQXQ6mcTlifyFXfJVCNJTVGuQP4m0d/UA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 h1:sDSXIrlsFSFJtWKLQS4PUWRvrT580rrnuLydJrCQ/yA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20/go.mod h1:WZ/c+w0ofps+/OUqMwWgnfrgzZH1DZO1RIkktICsqnY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 h1:4usbeaes3yJnCFC7kfeyhkdkPtoRYPa/hTmCqMpKpLI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24/go.mod h1:5CI1JemjVwde8m2WG3cz23qHKPOxbpkq0HaoreEgLIY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 h1:N1zsICrQglfzaBnrfM0Ys00860C+QFwu6u/5+LomP+o= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24/go.mod h1:dCn9HbJ8+K31i8IQ8EWmWj0EiIk0+vKiHNMxTTYveAg= +github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4= +github.com/aws/aws-sdk-go-v2 v1.32.6/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc= +github.com/aws/aws-sdk-go-v2/config v1.28.6 h1:D89IKtGrs/I3QXOLNTH93NJYtDhm8SYa9Q5CsPShmyo= +github.com/aws/aws-sdk-go-v2/config v1.28.6/go.mod h1:GDzxJ5wyyFSCoLkS+UhGB0dArhb9mI+Co4dHtoTxbko= +github.com/aws/aws-sdk-go-v2/credentials v1.17.47 h1:48bA+3/fCdi2yAwVt+3COvmatZ6jUDNkDTIsqDiMUdw= +github.com/aws/aws-sdk-go-v2/credentials v1.17.47/go.mod h1:+KdckOejLW3Ks3b0E3b5rHsr2f9yuORBum0WPnE5o5w= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 h1:AmoU1pziydclFT/xRV+xXE/Vb8fttJCLRPv8oAkprc0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21/go.mod h1:AjUdLYe4Tgs6kpH4Bv7uMZo7pottoyHMn4eTcIcneaY= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.19 h1:FKdiFzTxlTRO71p0C7VrLbkkdW8qfMKF5+ej6bTmkT0= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.19/go.mod h1:abO3pCj7WLQPTllnSeYImqFfkGrmJV0JovWo/gqT5N0= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 h1:r67ps7oHCYnflpgDy2LZU0MAQtQbYIOqNNnqGO6xQkE= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25/go.mod h1:GrGY+Q4fIokYLtjCVB/aFfCVL6hhGUFl8inD18fDalE= github.com/aws/aws-sdk-go-v2/service/ec2 v1.190.0 h1:k97fGog9Tl0woxTiSIHN14Qs5ehqK6GXejUwkhJYyL0= github.com/aws/aws-sdk-go-v2/service/ec2 v1.190.0/go.mod h1:mzj8EEjIHSN2oZRXiw1Dd+uB4HZTl7hC8nBzX9IZMWw= -github.com/aws/aws-sdk-go-v2/service/ecr v1.36.2 h1:VDQaVwGOokbd3VUbHF+wupiffdrbAZPdQnr5XZMJqrs= -github.com/aws/aws-sdk-go-v2/service/ecr v1.36.2/go.mod h1:lvUlMghKYmSxSfv0vU7pdU/8jSY+s0zpG8xXhaGKCw0= -github.com/aws/aws-sdk-go-v2/service/ecs v1.47.4 h1:CTkPGE8fiElvLtYWl/U+Eu5+1fVXiZbJUjyVCRSRgxk= -github.com/aws/aws-sdk-go-v2/service/ecs v1.47.4/go.mod h1:sMFLFhL27cKYa/eQYZp4asvIwHsnJWrAzTUpy9AQdnU= -github.com/aws/aws-sdk-go-v2/service/eks v1.44.1 h1:onUAzZXDsyXzyrmOGw/9p8Csl1NZkTDEs4URZ8covUY= -github.com/aws/aws-sdk-go-v2/service/eks v1.44.1/go.mod h1:dg9l/W4hXygeRNydRB4LWKY/MwHJhfUomGJUBwI29Dw= +github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7 h1:R+5XKIJga2K9Dkj0/iQ6fD/MBGo02oxGGFTc512lK/Q= +github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7/go.mod h1:fDPQV/6ONOQOjvtKhtypIy1wcGLcKYtoK/lvZ9fyDGQ= +github.com/aws/aws-sdk-go-v2/service/ecs v1.52.2 h1:LRM6z+wmXqAgCvuH36RR+Wf8SZZhvOVjt6f5r38V2II= +github.com/aws/aws-sdk-go-v2/service/ecs v1.52.2/go.mod h1:Ghi1OWUv4+VMEULWiHsKH2gNA3KAcMoLWsvU0eRXvIA= +github.com/aws/aws-sdk-go-v2/service/eks v1.51.0 h1:BYyB+byjQ7oyupe3v+YjTp1yfmfNEwChYA2naCc85xI= +github.com/aws/aws-sdk-go-v2/service/eks v1.51.0/go.mod h1:oaPCqTzAe8C5RQZJGRD4RENcV7A4n99uGxbD4rULbNg= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.0 h1:FQNWhRuSq8QwW74GtU0MrveNhZbqvHsA4dkA9w8fTDQ= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.0/go.mod h1:j/zZ3zmWfGCK91K73YsfHP53BSTLSjL/y6YN39XbBLM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 h1:wtpJ4zcwrSbwhECWQoI/g6WM9zqCcSpHDJIWSbMLOu4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5/go.mod h1:qu/W9HXQbbQ4+1+JcZp0ZNPV31ym537ZJN+fiS7Ti8E= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.0 h1:1NKXS8XfhMM0bg5wVYa/eOH8AM2f6JijugbKEyQFTIg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.0/go.mod h1:ph931DUfVfgrhZR7py9olSvHCiRpvaGxNvlWBcXxFds= -github.com/aws/aws-sdk-go-v2/service/s3 v1.65.0 h1:2dSm7frMrw2tdJ0QvyccQNJyPGaP24dyDgZ6h1QJMGU= -github.com/aws/aws-sdk-go-v2/service/s3 v1.65.0/go.mod h1:4XSVpw66upN8wND3JZA29eXl2NOZvfFVq7DIP6xvfuQ= -github.com/aws/aws-sdk-go-v2/service/ssm v1.50.7 h1:GkRsyFS9MmX/ybCvOncmp1A4XYn75v0x/ReWnIUao6E= -github.com/aws/aws-sdk-go-v2/service/ssm v1.50.7/go.mod h1:oBlt+H2x16bM5mSUNhmzIR2BWWnMsLUa1Qqs5auS1Bs= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 h1:3zu537oLmsPfDMyjnUS2g+F2vITgy5pB74tHI+JBNoM= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.6/go.mod h1:WJSZH2ZvepM6t6jwu4w/Z45Eoi75lPN7DcydSRtJg6Y= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 h1:K0OQAsDywb0ltlFrZm0JHPY3yZp/S9OaoLU33S7vPS8= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5/go.mod h1:ORITg+fyuMoeiQFiVGoqB3OydVTLkClw/ljbblMq6Cc= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 h1:6SZUVRQNvExYlMLbHdlKB48x0fLbc2iVROyaNEwBHbU= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.1/go.mod h1:GqWyYCwLXnlUB1lOAXQyNSPqPLQJvmo8J0DWBzp9mtg= -github.com/aws/session-manager-plugin v0.0.0-20241010233726-61cf1288c7c6 h1:iQc6pdTje/w3D3vrocVIvcosNVQGjoGxqBgPpwG28BY= -github.com/aws/session-manager-plugin v0.0.0-20241010233726-61cf1288c7c6/go.mod h1:7n17tunRPUsniNBu5Ja9C7WwJWTdOzaLqr/H0Ns3uuI= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6 h1:HCpPsWqmYQieU7SS6E9HXfdAMSud0pteVXieJmcpIRI= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6/go.mod h1:ngUiVRCco++u+soRRVBIvBZxSMMvOVMXA4PJ36JLfSw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 h1:50+XsN70RS7dwJ2CkVNXzj7U2L1HKP8nqTd3XWEXBN4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6/go.mod h1:WqgLmwY7so32kG01zD8CPTJWVWM+TzJoOVHwTg4aPug= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 h1:BbGDtTi0T1DYlmjBiCr/le3wzhA37O8QTC5/Ab8+EXk= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6/go.mod h1:hLMJt7Q8ePgViKupeymbqI0la+t9/iYFBjxQCFwuAwI= +github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 h1:nyuzXooUNJexRT0Oy0UQY6AhOzxPxhtt4DcBIHyCnmw= +github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0/go.mod h1:sT/iQz8JK3u/5gZkT+Hmr7GzVZehUMkRZpOaAwYXeGY= +github.com/aws/aws-sdk-go-v2/service/ssm v1.55.2 h1:z6Pq4+jtKlhK4wWJGHRGwMLGjC1HZwAO3KJr/Na0tSU= +github.com/aws/aws-sdk-go-v2/service/ssm v1.55.2/go.mod h1:DSmu/VZzpQlAubWBbAvNpt+S4k/XweglJi4XaDGyvQk= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 h1:rLnYAfXQ3YAccocshIH5mzNNwZBkBo+bP6EhIxak6Hw= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.7/go.mod h1:ZHtuQJ6t9A/+YDuxOLnbryAmITtr8UysSny3qcyvJTc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 h1:JnhTZR3PiYDNKlXy50/pNeix9aGMo6lLpXwJ1mw8MD4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6/go.mod h1:URronUEGfXZN1VpdktPSD1EkAL9mfrV+2F4sjH38qOY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 h1:s4074ZO1Hk8qv65GqNXqDjmkf4HSQqJukaLuuW0TpDA= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.2/go.mod h1:mVggCnIWoM09jP71Wh+ea7+5gAp53q+49wDFs1SW5z8= +github.com/aws/session-manager-plugin v0.0.0-20241119210807-82dc72922492 h1:Ihams/fjKo4iWwM313ng2gCJWoetsL7ZQkXhOTmVUq4= +github.com/aws/session-manager-plugin v0.0.0-20241119210807-82dc72922492/go.mod h1:7n17tunRPUsniNBu5Ja9C7WwJWTdOzaLqr/H0Ns3uuI= github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -153,10 +153,10 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c= github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0= -github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= -github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= -github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/cli v27.4.0+incompatible h1:/nJzWkcI1MDMN+U+px/YXnQWJqnu4J+QKGTfD6ptiTc= +github.com/docker/cli v27.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/docker v27.4.0+incompatible h1:I9z7sQ5qyzO0BfAb9IMOawRkAGxhYsidKiTMcm0DU+A= +github.com/docker/docker v27.4.0+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= @@ -259,8 +259,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= -github.com/hairyhenderson/go-codeowners v0.5.0 h1:dpQB+hVHiRc2VVvc2BHxkuM+tmu9Qej/as3apqUbsWc= -github.com/hairyhenderson/go-codeowners v0.5.0/go.mod h1:R3uW1OQXEj2Gu6/OvZ7bt6hr0qdkLvUWPiqNaWnexpo= +github.com/hairyhenderson/go-codeowners v0.7.0 h1:s0W4wF8bdsBEjTWzwzSlsatSthWtTAF2xLgo4a4RwAo= +github.com/hairyhenderson/go-codeowners v0.7.0/go.mod h1:wUlNgQ3QjqC4z8DnM5nnCYVq/icpqXJyJOukKx5U8/Q= 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= @@ -381,8 +381,8 @@ github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFz github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 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.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= -github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/pkg/sftp v1.13.7 h1:uv+I3nNJvlKZIQGSr8JVQLNHFU9YhhNpvC14Y6KgmSM= +github.com/pkg/sftp v1.13.7/go.mod h1:KMKI0t3T6hfA+lTR/ssZdunHo+uwq7ghoN09/FSu3DY= github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= @@ -421,16 +421,16 @@ github.com/pulumi/pulumi-azure-native-sdk/v2 v2.73.1 h1:yzXxwwq3tHdtSOi5vjKmKXq7 github.com/pulumi/pulumi-azure-native-sdk/v2 v2.73.1/go.mod h1:ChjIUNDNeN6jI33ZOivHUFqM6purDiLP01mghMGe1Fs= github.com/pulumi/pulumi-command/sdk v1.0.1 h1:ZuBSFT57nxg/fs8yBymUhKLkjJ6qmyN3gNvlY/idiN0= github.com/pulumi/pulumi-command/sdk v1.0.1/go.mod h1:C7sfdFbUIoXKoIASfXUbP/U9xnwPfxvz8dBpFodohlA= -github.com/pulumi/pulumi-docker/sdk/v4 v4.5.5 h1:7OjAfgLz5PAy95ynbgPAlWls5WBe4I/QW/61TdPWRlQ= -github.com/pulumi/pulumi-docker/sdk/v4 v4.5.5/go.mod h1:XZKLFXbw13olxuztlWnmVUPYZp2a+BqzqhuMl0j/Ow8= -github.com/pulumi/pulumi-eks/sdk/v3 v3.3.0 h1:F3xAOBZ/In4PqydTsKeg3tou/c5FZ+JTp5dQO0oMjqE= -github.com/pulumi/pulumi-eks/sdk/v3 v3.3.0/go.mod h1:QbAamxfUpDJC81BGtyEuV0P88RrdbOjQEhbgY+OOPpg= +github.com/pulumi/pulumi-docker/sdk/v4 v4.5.7 h1:cuIl5YyIghqtnFMGsdtPOeaNSix5S2CrqO0/UZ1Yjsc= +github.com/pulumi/pulumi-docker/sdk/v4 v4.5.7/go.mod h1:f2ek887nKRSwNtqTqCFENJSOH0PXm1b3FhzSXYL0IyM= +github.com/pulumi/pulumi-eks/sdk/v3 v3.4.0 h1:s2Cpu6E2lmADNUbutbJGm6O+O9j0mBLlrhQmc40ukt0= +github.com/pulumi/pulumi-eks/sdk/v3 v3.4.0/go.mod h1:QbAamxfUpDJC81BGtyEuV0P88RrdbOjQEhbgY+OOPpg= github.com/pulumi/pulumi-gcp/sdk/v7 v7.38.0 h1:21oSj+TKlKTzQcxN9Hik7iSNNHPUQXN4s3itOnahy/w= github.com/pulumi/pulumi-gcp/sdk/v7 v7.38.0/go.mod h1:YaEZms1NgXFqGhObKVofcAeWXu2V+3t/BAXdHQZq7fU= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.18.3 h1:quqoGsLbF7lpGpGU4mi5WfVLIAo4gfvoQeYYmemx1Dg= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.18.3/go.mod h1:9dBA6+rtpKmyZB3k1XryUOHDOuNdoTODFKEEZZCtrz8= -github.com/pulumi/pulumi-libvirt/sdk v0.4.7 h1:/BBnqqx/Gbg2vINvJxXIVb58THXzw2lSqFqxlRSXH9M= -github.com/pulumi/pulumi-libvirt/sdk v0.4.7/go.mod h1:VKvjhAm1sGtzKZruYwIhgascabEx7+oVVRCoxp/cPi4= +github.com/pulumi/pulumi-libvirt/sdk v0.5.3 h1:CiUGTweLLIxbAbADxxnwPv4BK8pxXfU8urokJvK1ihM= +github.com/pulumi/pulumi-libvirt/sdk v0.5.3/go.mod h1:gAhyIZKtzs4rknrl8fu8BQnyqijAmViFbaUkyuHt4xY= github.com/pulumi/pulumi-random/sdk/v4 v4.16.7 h1:39rhOe/PTUGMYia8pR5T2wbxxMt2pwrlonf0ncYKSzE= github.com/pulumi/pulumi-random/sdk/v4 v4.16.7/go.mod h1:cxxDhJzUPt/YElfvlWa15Q4NGF6XXS8kUs4OQsCxSBk= github.com/pulumi/pulumi-tls/sdk/v4 v4.11.1 h1:tXemWrzeVTqG8zq6hBdv1TdPFXjgZ+dob63a/6GlF1o= @@ -560,7 +560,7 @@ 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/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -575,6 +575,7 @@ 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= 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.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -592,7 +593,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-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.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +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.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -607,6 +609,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -632,19 +635,26 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/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-20220908164124-27713097b956/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.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.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= +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.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= 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.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.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +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.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= @@ -661,6 +671,7 @@ 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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -715,10 +726,10 @@ gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= 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= -k8s.io/api v0.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8= -k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE= -k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4= -k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/api v0.31.4 h1:I2QNzitPVsPeLQvexMEsj945QumYraqv9m74isPDKhM= +k8s.io/api v0.31.4/go.mod h1:d+7vgXLvmcdT1BCo79VEgJxHHryww3V5np2OYTr6jdw= +k8s.io/apimachinery v0.31.4 h1:8xjE2C4CzhYVm9DGf60yohpNUh5AEBnPxCryPBECmlM= +k8s.io/apimachinery v0.31.4/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= k8s.io/cli-runtime v0.31.2 h1:7FQt4C4Xnqx8V1GJqymInK0FFsoC+fAZtbLqgXYVOLQ= k8s.io/cli-runtime v0.31.2/go.mod h1:XROyicf+G7rQ6FQJMbeDV9jqxzkWXTYD6Uxd15noe0Q= k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4= diff --git a/test/new-e2e/tests/containers/k8s_test.go b/test/new-e2e/tests/containers/k8s_test.go index fb235f979c951..ea2e14c8d3742 100644 --- a/test/new-e2e/tests/containers/k8s_test.go +++ b/test/new-e2e/tests/containers/k8s_test.go @@ -41,6 +41,7 @@ const ( kubeNamespaceDogstatsWorkload = "workload-dogstatsd" kubeNamespaceDogstatsStandaloneWorkload = "workload-dogstatsd-standalone" kubeNamespaceTracegenWorkload = "workload-tracegen" + kubeDeploymentDogstatsdUDP = "dogstatsd-udp" kubeDeploymentDogstatsdUDPOrigin = "dogstatsd-udp-origin-detection" kubeDeploymentDogstatsdUDPExternalData = "dogstatsd-udp-external-data-only" kubeDeploymentDogstatsdUDS = "dogstatsd-uds" @@ -468,7 +469,10 @@ func (suite *k8sSuite) TestNginx() { `^pod_name:nginx-[[:alnum:]]+-[[:alnum:]]+$`, `^pod_phase:running$`, `^short_image:apps-nginx-server$`, - `^email:team-container-platform@datadoghq.com$`, + `^domain:deployment$`, + `^mail:team-container-platform@datadoghq.com$`, + `^org:agent-org$`, + `^parent-name:nginx$`, `^team:contp$`, }, AcceptUnexpectedTags: true, @@ -543,7 +547,10 @@ func (suite *k8sSuite) TestNginx() { `^pod_name:nginx-[[:alnum:]]+-[[:alnum:]]+$`, `^pod_phase:running$`, `^short_image:apps-nginx-server$`, - `^email:team-container-platform@datadoghq.com$`, + `^domain:deployment$`, + `^mail:team-container-platform@datadoghq.com$`, + `^org:agent-org$`, + `^parent-name:nginx$`, `^team:contp$`, }, Message: `GET / HTTP/1\.1`, @@ -794,46 +801,73 @@ func (suite *k8sSuite) TestCPU() { }) } +func (suite *k8sSuite) TestKSM() { + suite.testMetric(&testMetricArgs{ + Filter: testMetricFilterArgs{ + Name: "kubernetes_state.vpa.count", + }, + Expect: testMetricExpectArgs{ + Tags: &[]string{ + `^kube_cluster_name:` + regexp.QuoteMeta(suite.clusterName) + `$`, + `^kube_namespace:workload-(?:nginx|redis)$`, + }, + Value: &testMetricExpectValueArgs{ + Max: 1, + Min: 1, + }, + }, + }) +} + func (suite *k8sSuite) TestDogstatsdInAgent() { // Test with UDS - suite.testDogstatsdContainerID(kubeNamespaceDogstatsWorkload, kubeDeploymentDogstatsdUDS) + suite.testDogstatsd(kubeNamespaceDogstatsWorkload, kubeDeploymentDogstatsdUDS) // Test with UDP + Origin detection - suite.testDogstatsdContainerID(kubeNamespaceDogstatsWorkload, kubeDeploymentDogstatsdUDPOrigin) + suite.testDogstatsd(kubeNamespaceDogstatsWorkload, kubeDeploymentDogstatsdUDPOrigin) // Test with UDP + DD_ENTITY_ID - suite.testDogstatsdPodUID(kubeNamespaceDogstatsWorkload) + suite.testDogstatsd(kubeNamespaceDogstatsWorkload, kubeDeploymentDogstatsdUDP) // Test with UDP + External Data suite.testDogstatsdExternalData(kubeNamespaceDogstatsWorkload, kubeDeploymentDogstatsdUDPExternalData) } func (suite *k8sSuite) TestDogstatsdStandalone() { // Test with UDS - suite.testDogstatsdContainerID(kubeNamespaceDogstatsStandaloneWorkload, kubeDeploymentDogstatsdUDS) + suite.testDogstatsd(kubeNamespaceDogstatsStandaloneWorkload, kubeDeploymentDogstatsdUDS) // Dogstatsd standalone does not support origin detection // Test with UDP + DD_ENTITY_ID - suite.testDogstatsdPodUID(kubeNamespaceDogstatsWorkload) + suite.testDogstatsd(kubeNamespaceDogstatsWorkload, kubeDeploymentDogstatsdUDP) } -func (suite *k8sSuite) testDogstatsdPodUID(kubeNamespace string) { - // Test dogstatsd origin detection with UDP + DD_ENTITY_ID +func (suite *k8sSuite) testDogstatsd(kubeNamespace, kubeDeployment string) { suite.testMetric(&testMetricArgs{ Filter: testMetricFilterArgs{ Name: "custom.metric", Tags: []string{ - "^kube_deployment:dogstatsd-udp$", + "^kube_deployment:" + regexp.QuoteMeta(kubeDeployment) + "$", "^kube_namespace:" + regexp.QuoteMeta(kubeNamespace) + "$", }, }, Expect: testMetricExpectArgs{ Tags: &[]string{ - `^kube_deployment:dogstatsd-udp$`, + `^container_id:`, + `^container_name:dogstatsd$`, + `^display_container_name:dogstatsd`, + `^git.commit.sha:`, // org.opencontainers.image.revision docker image label + `^git.repository_url:https://github.com/DataDog/test-infra-definitions$`, // org.opencontainers.image.source docker image label + `^image_id:ghcr.io/datadog/apps-dogstatsd@sha256:`, + `^image_name:ghcr.io/datadog/apps-dogstatsd$`, + `^image_tag:main$`, + `^kube_container_name:dogstatsd$`, + `^kube_deployment:` + regexp.QuoteMeta(kubeDeployment) + `$`, "^kube_namespace:" + regexp.QuoteMeta(kubeNamespace) + "$", `^kube_ownerref_kind:replicaset$`, - `^kube_ownerref_name:dogstatsd-udp-[[:alnum:]]+$`, + `^kube_ownerref_name:` + regexp.QuoteMeta(kubeDeployment) + `-[[:alnum:]]+$`, `^kube_qos:Burstable$`, - `^kube_replica_set:dogstatsd-udp-[[:alnum:]]+$`, - `^pod_name:dogstatsd-udp-[[:alnum:]]+-[[:alnum:]]+$`, + `^kube_replica_set:` + regexp.QuoteMeta(kubeDeployment) + `-[[:alnum:]]+$`, + `^pod_name:` + regexp.QuoteMeta(kubeDeployment) + `-[[:alnum:]]+-[[:alnum:]]+$`, `^pod_phase:running$`, `^series:`, + `^short_image:apps-dogstatsd$`, }, }, }) @@ -911,41 +945,6 @@ func (suite *k8sSuite) testDogstatsdExternalData(kubeNamespace, kubeDeployment s }) } -func (suite *k8sSuite) testDogstatsdContainerID(kubeNamespace, kubeDeployment string) { - suite.testMetric(&testMetricArgs{ - Filter: testMetricFilterArgs{ - Name: "custom.metric", - Tags: []string{ - "^kube_deployment:" + regexp.QuoteMeta(kubeDeployment) + "$", - "^kube_namespace:" + regexp.QuoteMeta(kubeNamespace) + "$", - }, - }, - Expect: testMetricExpectArgs{ - Tags: &[]string{ - `^container_id:`, - `^container_name:dogstatsd$`, - `^display_container_name:dogstatsd`, - `^git.commit.sha:`, // org.opencontainers.image.revision docker image label - `^git.repository_url:https://github.com/DataDog/test-infra-definitions$`, // org.opencontainers.image.source docker image label - `^image_id:ghcr.io/datadog/apps-dogstatsd@sha256:`, - `^image_name:ghcr.io/datadog/apps-dogstatsd$`, - `^image_tag:main$`, - `^kube_container_name:dogstatsd$`, - `^kube_deployment:` + regexp.QuoteMeta(kubeDeployment) + `$`, - "^kube_namespace:" + regexp.QuoteMeta(kubeNamespace) + "$", - `^kube_ownerref_kind:replicaset$`, - `^kube_ownerref_name:` + regexp.QuoteMeta(kubeDeployment) + `-[[:alnum:]]+$`, - `^kube_qos:Burstable$`, - `^kube_replica_set:` + regexp.QuoteMeta(kubeDeployment) + `-[[:alnum:]]+$`, - `^pod_name:` + regexp.QuoteMeta(kubeDeployment) + `-[[:alnum:]]+-[[:alnum:]]+$`, - `^pod_phase:running$`, - `^series:`, - `^short_image:apps-dogstatsd$`, - }, - }, - }) -} - func (suite *k8sSuite) TestPrometheus() { // Test Prometheus check suite.testMetric(&testMetricArgs{ diff --git a/test/new-e2e/tests/discovery/linux_test.go b/test/new-e2e/tests/discovery/linux_test.go index ec7d0aa339be3..0df272712dedd 100644 --- a/test/new-e2e/tests/discovery/linux_test.go +++ b/test/new-e2e/tests/discovery/linux_test.go @@ -170,7 +170,19 @@ func assertRunningCheck(t *assert.CollectT, remoteHost *components.RemoteHost, c func (s *linuxTestSuite) provisionServer() { err := s.Env().RemoteHost.CopyFolder("testdata/provision", "/home/ubuntu/e2e-test") require.NoError(s.T(), err) - s.Env().RemoteHost.MustExecute("sudo bash /home/ubuntu/e2e-test/provision.sh") + + cmd := "sudo bash /home/ubuntu/e2e-test/provision.sh" + _, err = s.Env().RemoteHost.Execute(cmd) + if err != nil { + // Sometimes temporary network errors are seen which cause the provision + // script to fail. + s.T().Log("Retrying provision due to failure", err) + time.Sleep(30 * time.Second) + _, err := s.Env().RemoteHost.Execute(cmd) + if err != nil { + s.T().Skip("Unable to provision server") + } + } } func (s *linuxTestSuite) startServices() { diff --git a/test/new-e2e/tests/gpu/gpu_test.go b/test/new-e2e/tests/gpu/gpu_test.go index 74b1229437a46..0c71a1fe7f74c 100644 --- a/test/new-e2e/tests/gpu/gpu_test.go +++ b/test/new-e2e/tests/gpu/gpu_test.go @@ -3,6 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2024-present Datadog, Inc. +// Package gpu contains e2e tests for the GPU monitoring module package gpu import ( @@ -14,18 +15,13 @@ import ( "testing" "time" - "github.com/DataDog/test-infra-definitions/scenarios/aws/ec2" "github.com/stretchr/testify/assert" "github.com/DataDog/datadog-agent/pkg/util/testutil/flake" "github.com/DataDog/datadog-agent/test/fakeintake/client" - "github.com/DataDog/test-infra-definitions/components/datadog/agentparams" - "github.com/DataDog/test-infra-definitions/components/os" - "github.com/DataDog/datadog-agent/test/new-e2e/pkg/e2e" "github.com/DataDog/datadog-agent/test/new-e2e/pkg/environments" - awshost "github.com/DataDog/datadog-agent/test/new-e2e/pkg/environments/aws/host" "github.com/DataDog/datadog-agent/test/new-e2e/pkg/utils/e2e/client/agentclient" ) @@ -34,63 +30,35 @@ var imageTag = flag.String("image-tag", "main", "Docker image tag to use") type gpuSuite struct { e2e.BaseSuite[environments.Host] - imageTag string containerNameCounter int } -const defaultGpuCheckConfig = ` -init_config: - min_collection_interval: 5 - -instances: - - {} -` - -const defaultSysprobeConfig = ` -gpu_monitoring: - enabled: true -` - const vectorAddDockerImg = "ghcr.io/datadog/apps-cuda-basic" -const gpuEnabledAMI = "ami-0f71e237bb2ba34be" // Ubuntu 22.04 with GPU drivers + +func dockerImageName() string { + return fmt.Sprintf("%s:%s", vectorAddDockerImg, *imageTag) +} // TestGPUSuite runs tests for the VM interface to ensure its implementation is correct. // Not to be run in parallel, as some tests wait until the checks are available. func TestGPUSuite(t *testing.T) { - provisioner := awshost.Provisioner( - awshost.WithEC2InstanceOptions( - ec2.WithInstanceType("g4dn.xlarge"), - ec2.WithAMI(gpuEnabledAMI, os.Ubuntu2204, os.AMD64Arch), - ), - awshost.WithAgentOptions( - agentparams.WithIntegration("gpu.d", defaultGpuCheckConfig), - agentparams.WithSystemProbeConfig(defaultSysprobeConfig), - ), - awshost.WithDocker(), - ) + provParams := getDefaultProvisionerParams() + + // Append our vectorAdd image for testing + provParams.dockerImages = append(provParams.dockerImages, dockerImageName()) + + provisioner := gpuInstanceProvisioner(provParams) suiteParams := []e2e.SuiteOption{e2e.WithProvisioner(provisioner)} if *devMode { suiteParams = append(suiteParams, e2e.WithDevMode()) } - suite := &gpuSuite{ - imageTag: *imageTag, - } + suite := &gpuSuite{} e2e.Run(t, suite, suiteParams...) } -func (v *gpuSuite) SetupSuite() { - v.BaseSuite.SetupSuite() - - v.Env().RemoteHost.MustExecute(fmt.Sprintf("docker pull %s", v.dockerImageName())) -} - -func (v *gpuSuite) dockerImageName() string { - return fmt.Sprintf("%s:%s", vectorAddDockerImg, v.imageTag) -} - // TODO: Extract this to common package? service_discovery uses it too type checkStatus struct { CheckID string `json:"CheckID"` @@ -118,7 +86,7 @@ func (v *gpuSuite) runCudaDockerWorkload() string { containerName := fmt.Sprintf("cuda-basic-%d", v.containerNameCounter) v.containerNameCounter++ - cmd := fmt.Sprintf("docker run --gpus all --name %s %s %s %d %d %d", containerName, v.dockerImageName(), binary, vectorSize, numLoops, waitTimeSeconds) + cmd := fmt.Sprintf("docker run --gpus all --name %s %s %s %d %d %d", containerName, dockerImageName(), binary, vectorSize, numLoops, waitTimeSeconds) out, err := v.Env().RemoteHost.Execute(cmd) v.Require().NoError(err) v.Require().NotEmpty(out) diff --git a/test/new-e2e/tests/gpu/provisioner.go b/test/new-e2e/tests/gpu/provisioner.go new file mode 100644 index 0000000000000..ee552dcca7d8d --- /dev/null +++ b/test/new-e2e/tests/gpu/provisioner.go @@ -0,0 +1,237 @@ +// 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 gpu + +import ( + "fmt" + "strconv" + + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + + "github.com/DataDog/test-infra-definitions/common/utils" + "github.com/DataDog/test-infra-definitions/components/command" + "github.com/DataDog/test-infra-definitions/components/datadog/agent" + "github.com/DataDog/test-infra-definitions/components/datadog/agentparams" + "github.com/DataDog/test-infra-definitions/components/docker" + "github.com/DataDog/test-infra-definitions/components/os" + "github.com/DataDog/test-infra-definitions/components/remote" + "github.com/DataDog/test-infra-definitions/resources/aws" + "github.com/DataDog/test-infra-definitions/scenarios/aws/ec2" + "github.com/DataDog/test-infra-definitions/scenarios/aws/fakeintake" + + "github.com/DataDog/datadog-agent/test/new-e2e/pkg/e2e" + "github.com/DataDog/datadog-agent/test/new-e2e/pkg/environments" +) + +// gpuEnabledAMI is an AMI that has GPU drivers pre-installed. In this case it's +// an Ubuntu 22.04 with NVIDIA drivers +const gpuEnabledAMI = "ami-0f71e237bb2ba34be" + +// gpuInstanceType is the instance type to use. By default we use g4dn.xlarge, +// which is the cheapest GPU instance type +const gpuInstanceType = "g4dn.xlarge" + +// nvidiaPCIVendorID is the PCI vendor ID for NVIDIA GPUs, used to identify the +// GPU devices with lspci +const nvidiaPCIVendorID = "10de" + +// cudaSanityCheckImage is a Docker image that contains a CUDA sample to +// validate the GPU setup with the default CUDA installation. Note that the CUDA +// version in this image must be equal or less than the one installed in the +// AMI. +const cudaSanityCheckImage = "669783387624.dkr.ecr.us-east-1.amazonaws.com/dockerhub/nvidia/cuda:12.6.3-base-ubuntu22.04" + +// nvidiaSMIValidationCmd is a command that checks if the nvidia-smi command is +// available and can list the GPUs +const nvidiaSMIValidationCmd = "nvidia-smi -L | grep GPU" + +// validationCommandMarker is a command that can be appended to all validation commands +// to identify them in the output, which can be useful to later force retries. Retries +// are controlled in test/new-e2e/pkg/utils/infra/retriable_errors.go, and the way to +// identify them are based on the pulumi logs. This command will be echoed to the output +// and can be used to identify the validation commands. +const validationCommandMarker = "echo 'gpu-validation-command'" + +const defaultGpuCheckConfig = ` +init_config: + min_collection_interval: 5 + +instances: + - {} +` + +const defaultSysprobeConfig = ` +gpu_monitoring: + enabled: true +` + +type provisionerParams struct { + agentOptions []agentparams.Option + ami string + amiOS os.Descriptor + instanceType string + dockerImages []string +} + +func getDefaultProvisionerParams() *provisionerParams { + return &provisionerParams{ + agentOptions: []agentparams.Option{ + agentparams.WithIntegration("gpu.d", defaultGpuCheckConfig), + agentparams.WithSystemProbeConfig(defaultSysprobeConfig), + }, + ami: gpuEnabledAMI, + amiOS: os.Ubuntu2204, + instanceType: gpuInstanceType, + dockerImages: []string{cudaSanityCheckImage}, + } +} + +func gpuInstanceProvisioner(params *provisionerParams) e2e.Provisioner { + return e2e.NewTypedPulumiProvisioner[environments.Host]("gpu", func(ctx *pulumi.Context, env *environments.Host) error { + name := "gpuvm" + awsEnv, err := aws.NewEnvironment(ctx) + if err != nil { + return err + } + + // Create the EC2 instance + host, err := ec2.NewVM(awsEnv, name, + ec2.WithInstanceType(params.instanceType), + ec2.WithAMI(params.ami, params.amiOS, os.AMD64Arch), + ) + if err != nil { + return err + } + err = host.Export(ctx, &env.RemoteHost.HostOutput) + if err != nil { + return err + } + + // Create the fakeintake instance + fakeIntake, err := fakeintake.NewECSFargateInstance(awsEnv, name) + if err != nil { + return err + } + err = fakeIntake.Export(ctx, &env.FakeIntake.FakeintakeOutput) + if err != nil { + return err + } + + // install the ECR credentials helper + // required to get pipeline agent images or other internally hosted images + installEcrCredsHelperCmd, err := ec2.InstallECRCredentialsHelper(awsEnv, host) + if err != nil { + return err + } + + // Validate GPU devices + validateGPUDevicesCmd, err := validateGPUDevices(awsEnv, host) + if err != nil { + return err + } + + // Install Docker (only after GPU devices are validated and the ECR credentials helper is installed) + dockerManager, err := docker.NewManager(&awsEnv, host, utils.PulumiDependsOn(installEcrCredsHelperCmd)) + if err != nil { + return err + } + + // Pull all the docker images required for the tests + dockerPullCmds, err := downloadDockerImages(awsEnv, host, params.dockerImages, dockerManager) + if err != nil { + return err + } + + // Validate that Docker can run CUDA samples + dockerCudaDeps := append(dockerPullCmds, validateGPUDevicesCmd...) + err = validateDockerCuda(awsEnv, host, dockerCudaDeps...) + if err != nil { + return err + } + + // Combine agent options from the parameters with the fakeintake and docker dependencies + params.agentOptions = append(params.agentOptions, + agentparams.WithFakeintake(fakeIntake), + agentparams.WithPulumiResourceOptions(utils.PulumiDependsOn(dockerManager)), // Depend on Docker to avoid apt lock issues + ) + + // Set updater to nil as we're not using it + env.Updater = nil + + // Install the agent + agent, err := agent.NewHostAgent(&awsEnv, host, params.agentOptions...) + if err != nil { + return err + } + + err = agent.Export(ctx, &env.Agent.HostAgentOutput) + if err != nil { + return err + } + + return nil + }, nil) +} + +// validateGPUDevices checks that there are GPU devices present and accesible +func validateGPUDevices(e aws.Environment, vm *remote.Host) ([]pulumi.Resource, error) { + commands := map[string]string{ + "pci": fmt.Sprintf("lspci -d %s:: | grep NVIDIA", nvidiaPCIVendorID), + "driver": "lsmod | grep nvidia", + "nvidia": "nvidia-smi -L | grep GPU", + } + + var cmds []pulumi.Resource + + for name, cmd := range commands { + c, err := vm.OS.Runner().Command( + e.CommonNamer().ResourceName("gpu-validate", name), + &command.Args{ + Create: pulumi.Sprintf("%s && %s", validationCommandMarker, cmd), + Sudo: false, + }, + ) + if err != nil { + return nil, err + } + cmds = append(cmds, c) + } + + return cmds, nil +} + +func downloadDockerImages(e aws.Environment, vm *remote.Host, images []string, dependsOn ...pulumi.Resource) ([]pulumi.Resource, error) { + var cmds []pulumi.Resource + + for i, image := range images { + cmd, err := vm.OS.Runner().Command( + e.CommonNamer().ResourceName("docker-pull", strconv.Itoa(i)), + &command.Args{ + Create: pulumi.Sprintf("docker pull %s", image), + }, + utils.PulumiDependsOn(dependsOn...), + ) + if err != nil { + return nil, err + } + + cmds = append(cmds, cmd) + } + + return cmds, nil +} + +func validateDockerCuda(e aws.Environment, vm *remote.Host, dependsOn ...pulumi.Resource) error { + _, err := vm.OS.Runner().Command( + e.CommonNamer().ResourceName("docker-cuda-validate"), + &command.Args{ + Create: pulumi.Sprintf("%s && docker run --gpus all --rm %s bash -c \"%s\"", validationCommandMarker, cudaSanityCheckImage, nvidiaSMIValidationCmd), + }, + utils.PulumiDependsOn(dependsOn...), + ) + + return err +} diff --git a/test/new-e2e/tests/installer/unix/package_definitions.go b/test/new-e2e/tests/installer/unix/package_definitions.go index 2f7c2d15057dd..78c5ac64fd75b 100644 --- a/test/new-e2e/tests/installer/unix/package_definitions.go +++ b/test/new-e2e/tests/installer/unix/package_definitions.go @@ -67,8 +67,8 @@ func WithAlias(alias string) PackageOption { // PackagesConfig is the list of known packages configuration for testing var PackagesConfig = []TestPackageConfig{ - {Name: "datadog-installer", Version: fmt.Sprintf("pipeline-%v", os.Getenv("E2E_PIPELINE_ID")), Registry: "669783387624.dkr.ecr.us-east-1.amazonaws.com", Auth: "ecr"}, - {Name: "datadog-agent", Alias: "agent-package", Version: fmt.Sprintf("pipeline-%v", os.Getenv("E2E_PIPELINE_ID")), Registry: "669783387624.dkr.ecr.us-east-1.amazonaws.com", Auth: "ecr"}, + {Name: "datadog-installer", Version: fmt.Sprintf("pipeline-%v", os.Getenv("E2E_PIPELINE_ID")), Registry: "installtesting.datad0g.com"}, + {Name: "datadog-agent", Alias: "agent-package", Version: fmt.Sprintf("pipeline-%v", os.Getenv("E2E_PIPELINE_ID")), Registry: "installtesting.datad0g.com"}, {Name: "datadog-apm-inject", Version: "latest"}, {Name: "datadog-apm-library-java", Version: "latest"}, {Name: "datadog-apm-library-ruby", Version: "latest"}, diff --git a/test/new-e2e/tests/installer/unix/upgrade_scenario_test.go b/test/new-e2e/tests/installer/unix/upgrade_scenario_test.go index 74d3b888cab58..6230ef741410c 100644 --- a/test/new-e2e/tests/installer/unix/upgrade_scenario_test.go +++ b/test/new-e2e/tests/installer/unix/upgrade_scenario_test.go @@ -404,6 +404,10 @@ func (s *upgradeScenarioSuite) TestConfigUpgradeSuccessful() { s.host.WaitForFileExists(true, "/opt/datadog-packages/run/installer.sock") state := s.host.State() + // Assert setup successful + state.AssertDirExists("/etc/datadog-agent/managed", 0755, "root", "root") + state.AssertDirExists("/etc/datadog-agent/managed/datadog-apm-libraries", 0755, "root", "root") + state.AssertDirExists("/etc/datadog-agent/managed/datadog-agent", 0755, "root", "root") state.AssertSymlinkExists("/etc/datadog-agent/managed/datadog-agent/stable", "/etc/datadog-agent/managed/datadog-agent/e94406c45ae766b7d34d2793e4759b9c4d15ed5d5e2b7f73ce1bf0e6836f728d", "root", "root") // Verify metadata state.AssertFileExists("/etc/datadog-agent/managed/datadog-agent/e94406c45ae766b7d34d2793e4759b9c4d15ed5d5e2b7f73ce1bf0e6836f728d/policy.metadata", 0440, "dd-agent", "dd-agent") diff --git a/test/new-e2e/tests/orchestrator/apply.go b/test/new-e2e/tests/orchestrator/apply.go index ee4e8668ab40c..45b3d792102a7 100644 --- a/test/new-e2e/tests/orchestrator/apply.go +++ b/test/new-e2e/tests/orchestrator/apply.go @@ -18,6 +18,7 @@ import ( dogstatsdstandalone "github.com/DataDog/test-infra-definitions/components/datadog/dogstatsd-standalone" fakeintakeComp "github.com/DataDog/test-infra-definitions/components/datadog/fakeintake" localKubernetes "github.com/DataDog/test-infra-definitions/components/kubernetes" + "github.com/DataDog/test-infra-definitions/components/kubernetes/vpa" resAws "github.com/DataDog/test-infra-definitions/resources/aws" "github.com/DataDog/test-infra-definitions/scenarios/aws/ec2" "github.com/DataDog/test-infra-definitions/scenarios/aws/fakeintake" @@ -86,6 +87,12 @@ func createCluster(ctx *pulumi.Context) (*resAws.Environment, *localKubernetes.C if err != nil { return nil, nil, nil, err } + + // Deploy VPA CRD + if _, err := vpa.DeployCRD(&awsEnv, kindKubeProvider); err != nil { + return nil, nil, nil, err + } + return &awsEnv, kindCluster, kindKubeProvider, nil } diff --git a/test/new-e2e/tests/windows/install-test/installtester.go b/test/new-e2e/tests/windows/install-test/installtester.go index e0fbee6886600..f0c86fdf8c9d1 100644 --- a/test/new-e2e/tests/windows/install-test/installtester.go +++ b/test/new-e2e/tests/windows/install-test/installtester.go @@ -536,31 +536,6 @@ func (t *Tester) testInstalledFilePermissions(tt *testing.T, ddAgentUserIdentity }) } - // expect to have standard inherited permissions, plus an explciit ACE for ddagentuser - embeddedPaths := []string{ - filepath.Join(t.expectedInstallPath, "embedded3"), - } - if t.ExpectPython2Installed() { - embeddedPaths = append(embeddedPaths, - filepath.Join(t.expectedInstallPath, "embedded2"), - ) - } - agentUserFullAccessDirRule := windows.NewExplicitAccessRuleWithFlags( - ddAgentUserIdentity, - windows.FileFullControl, - windows.AccessControlTypeAllow, - windows.InheritanceFlagsContainer|windows.InheritanceFlagsObject, - windows.PropagationFlagsNone, - ) - for _, path := range embeddedPaths { - out, err := windows.GetSecurityInfoForPath(t.host, path) - require.NoError(tt, err) - if !windows.IsIdentityLocalSystem(ddAgentUserIdentity) { - windows.AssertContainsEqualable(tt, out.Access, agentUserFullAccessDirRule, "%s should have full access rule for %s", path, ddAgentUserIdentity) - } - assert.False(tt, out.AreAccessRulesProtected, "%s should inherit access rules", path) - } - // ensure the agent user does not have an ACE on the install dir out, err := windows.GetSecurityInfoForPath(t.host, t.expectedInstallPath) require.NoError(tt, err) diff --git a/test/otel/go.mod b/test/otel/go.mod index c1d17501161ea..a4523c0b33b0b 100644 --- a/test/otel/go.mod +++ b/test/otel/go.mod @@ -175,7 +175,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/winutil v0.59.1 // indirect github.com/DataDog/datadog-agent/pkg/version v0.59.1 // indirect github.com/DataDog/datadog-api-client-go/v2 v2.33.0 // indirect - github.com/DataDog/datadog-go/v5 v5.5.0 // indirect + github.com/DataDog/datadog-go/v5 v5.6.0 // indirect github.com/DataDog/dd-sensitive-data-scanner/sds-go/go v0.0.0-20240816154533-f7f9beb53a42 // indirect github.com/DataDog/go-sqllexer v0.0.17 // indirect github.com/DataDog/go-tuf v1.1.0-0.5.2 // indirect @@ -214,7 +214,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect + github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect diff --git a/test/otel/go.sum b/test/otel/go.sum index e8d514c34bee5..bce88ff15bfa8 100644 --- a/test/otel/go.sum +++ b/test/otel/go.sum @@ -4,8 +4,8 @@ github.com/DataDog/agent-payload/v5 v5.0.138 h1:Wg7hmWuoLC/o0X3zZ+uGcfRHPyaytlju github.com/DataDog/agent-payload/v5 v5.0.138/go.mod h1:lxh9lb5xYrBXjblpIWYUi4deJqVbkIfkjwesi5nskDc= github.com/DataDog/datadog-api-client-go/v2 v2.33.0 h1:OI6kDnJeQmkjfGzxmP0XUQUxMD4tp6oAPXnnJ4VpgUM= github.com/DataDog/datadog-api-client-go/v2 v2.33.0/go.mod h1:d3tOEgUd2kfsr9uuHQdY+nXrWp4uikgTgVCPdKNK30U= -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/datadog-go/v5 v5.6.0 h1:2oCLxjF/4htd55piM75baflj/KoE6VYS7alEUqFvRDw= +github.com/DataDog/datadog-go/v5 v5.6.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= 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.17 h1:u47fJAVg/+5DA74ZW3w0Qu+3qXHd3GtnA8ZBYixdPrM= @@ -168,8 +168,8 @@ github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb h1:PGufWXXDq9yaev6xX1YQauaO1MV90e6Mpoq1I7Lz/VM= +github.com/hectane/go-acl v0.0.0-20230122075934-ca0b05cb1adb/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= diff --git a/test/regression/cases/quality_gate_idle/experiment.yaml b/test/regression/cases/quality_gate_idle/experiment.yaml index 6555258f34601..1c120a0d23187 100644 --- a/test/regression/cases/quality_gate_idle/experiment.yaml +++ b/test/regression/cases/quality_gate_idle/experiment.yaml @@ -36,7 +36,7 @@ checks: description: "Memory usage quality gate. This puts a bound on the total agent memory usage." bounds: series: total_rss_bytes - upper_bound: "390.0 MiB" + upper_bound: "365.0 MiB" report_links: - text: "bounds checks dashboard" diff --git a/test/regression/cases/quality_gate_idle_all_features/experiment.yaml b/test/regression/cases/quality_gate_idle_all_features/experiment.yaml index 624b68caeab20..2b16f4988c0b0 100644 --- a/test/regression/cases/quality_gate_idle_all_features/experiment.yaml +++ b/test/regression/cases/quality_gate_idle_all_features/experiment.yaml @@ -47,7 +47,7 @@ checks: description: "Memory usage quality gate. This puts a bound on the total agent memory usage." bounds: series: total_rss_bytes - upper_bound: "795.0 MiB" + upper_bound: "755.0 MiB" report_links: - text: "bounds checks dashboard" diff --git a/test/regression/cases/quality_gate_logs/experiment.yaml b/test/regression/cases/quality_gate_logs/experiment.yaml index b1b2d9ee9c02b..761cae4678a8e 100644 --- a/test/regression/cases/quality_gate_logs/experiment.yaml +++ b/test/regression/cases/quality_gate_logs/experiment.yaml @@ -29,7 +29,7 @@ checks: description: "Memory usage" bounds: series: total_rss_bytes - upper_bound: 440MiB + upper_bound: 420MiB - name: lost_bytes description: "Allowable bytes not polled by log Agent" diff --git a/tools/windows/DatadogAgentInstaller/CustomActions/ConfigureUserCustomActions.cs b/tools/windows/DatadogAgentInstaller/CustomActions/ConfigureUserCustomActions.cs index 1447f8a080fd0..817f118b0c797 100644 --- a/tools/windows/DatadogAgentInstaller/CustomActions/ConfigureUserCustomActions.cs +++ b/tools/windows/DatadogAgentInstaller/CustomActions/ConfigureUserCustomActions.cs @@ -586,9 +586,6 @@ private List PathsWithAgentAccess() // agent needs to be able to write to run/ // agent needs to be able to create auth_token _session.Property("APPLICATIONDATADIRECTORY"), - // allow agent to write __pycache__ - Path.Combine(_session.Property("PROJECTLOCATION"), "embedded2"), - Path.Combine(_session.Property("PROJECTLOCATION"), "embedded3"), }; }