diff --git a/.builders/images/linux-aarch64/Dockerfile b/.builders/images/linux-aarch64/Dockerfile index 85cc9a048b8e1..00b9506d5e98e 100644 --- a/.builders/images/linux-aarch64/Dockerfile +++ b/.builders/images/linux-aarch64/Dockerfile @@ -19,8 +19,8 @@ ENV LDFLAGS="-Wl,-rpath,'\$\$ORIGIN' -Wl,--strip-debug" RUN yum install -y perl-IPC-Cmd perl-CPANPLUS perl-core && \ cpanp -i List::Util 1.66 && \ DOWNLOAD_URL="https://www.openssl.org/source/openssl-{{version}}.tar.gz" \ - VERSION="3.6.1" \ - SHA256="b1bfedcd5b289ff22aee87c9d600f515767ebf45f77168cb6d64f231f518a82e" \ + VERSION="3.6.2" \ + SHA256="aaf51a1fe064384f811daeaeb4ec4dce7340ec8bd893027eee676af31e83a04f" \ RELATIVE_PATH="openssl-{{version}}" \ # https://docs.python.org/3/using/unix.html#custom-openssl INSTALL_COMMAND="make install_sw" \ diff --git a/.builders/images/linux-x86_64/Dockerfile b/.builders/images/linux-x86_64/Dockerfile index ce75485d38678..1455252b42a62 100644 --- a/.builders/images/linux-x86_64/Dockerfile +++ b/.builders/images/linux-x86_64/Dockerfile @@ -19,8 +19,8 @@ ENV LDFLAGS="-Wl,-rpath,'\$\$ORIGIN' -Wl,--strip-debug" RUN yum install -y perl-IPC-Cmd perl-CPANPLUS perl-core && \ cpanp -i List::Util 1.66 && \ DOWNLOAD_URL="https://www.openssl.org/source/openssl-{{version}}.tar.gz" \ - VERSION="3.6.1" \ - SHA256="b1bfedcd5b289ff22aee87c9d600f515767ebf45f77168cb6d64f231f518a82e" \ + VERSION="3.6.2" \ + SHA256="aaf51a1fe064384f811daeaeb4ec4dce7340ec8bd893027eee676af31e83a04f" \ RELATIVE_PATH="openssl-{{version}}" \ # https://docs.python.org/3/using/unix.html#custom-openssl INSTALL_COMMAND="make install_sw" \ diff --git a/.builders/images/macos/builder_setup.sh b/.builders/images/macos/builder_setup.sh index 74df25381da4f..9861d47937b8d 100644 --- a/.builders/images/macos/builder_setup.sh +++ b/.builders/images/macos/builder_setup.sh @@ -23,8 +23,8 @@ cp -R /opt/mqm "${DD_PREFIX_PATH}" # openssl DOWNLOAD_URL="https://www.openssl.org/source/openssl-{{version}}.tar.gz" \ -VERSION="3.6.1" \ -SHA256="b1bfedcd5b289ff22aee87c9d600f515767ebf45f77168cb6d64f231f518a82e" \ +VERSION="3.6.2" \ +SHA256="aaf51a1fe064384f811daeaeb4ec4dce7340ec8bd893027eee676af31e83a04f" \ RELATIVE_PATH="openssl-{{version}}" \ CONFIGURE_SCRIPT="./config" \ install-from-source \ diff --git a/.builders/images/windows-x86_64/Dockerfile b/.builders/images/windows-x86_64/Dockerfile index 4a797271be2b8..af3b6735d7838 100644 --- a/.builders/images/windows-x86_64/Dockerfile +++ b/.builders/images/windows-x86_64/Dockerfile @@ -127,11 +127,11 @@ RUN Get-RemoteFile ` Add-ToPath -Append "C:\nasm\nasm-$Env:NASM_VERSION" && ` Remove-Item "nasm-$Env:NASM_VERSION-win64.zip" -ENV OPENSSL_VERSION="3.6.1" +ENV OPENSSL_VERSION="3.6.2" RUN Get-RemoteFile ` -Uri https://www.openssl.org/source/openssl-$Env:OPENSSL_VERSION.tar.gz ` -Path openssl-$Env:OPENSSL_VERSION.tar.gz ` - -Hash 'b1bfedcd5b289ff22aee87c9d600f515767ebf45f77168cb6d64f231f518a82e'; ` + -Hash 'aaf51a1fe064384f811daeaeb4ec4dce7340ec8bd893027eee676af31e83a04f'; ` 7z x openssl-$Env:OPENSSL_VERSION.tar.gz -r -y && ` 7z x openssl-$Env:OPENSSL_VERSION.tar -oC:\openssl_3 && ` cd C:\openssl_3\openssl-$Env:OPENSSL_VERSION && ` diff --git a/.builders/images/windows-x86_64/build_script.ps1 b/.builders/images/windows-x86_64/build_script.ps1 index 7e3a6642320d5..6684875dadb45 100644 --- a/.builders/images/windows-x86_64/build_script.ps1 +++ b/.builders/images/windows-x86_64/build_script.ps1 @@ -24,7 +24,7 @@ Remove-Item "librdkafka-${kafka_version}.tar.gz" $triplet = "x64-windows" $vcpkg_dir = "C:\vcpkg" $librdkafka_dir = "C:\librdkafka\librdkafka-${kafka_version}" -$desired_commit = "48cfe1e0e928341709d97fc3d2eff10ad6262c96" +$desired_commit = "36118ef68885436fd2a999188216337365856ad4" # Clone and configure vcpkg if (-Not (Test-Path -Path "$vcpkg_dir\.git")) { diff --git a/.deps/builder_inputs.toml b/.deps/builder_inputs.toml index 2dfbe5a814928..7b53a49f2d03a 100644 --- a/.deps/builder_inputs.toml +++ b/.deps/builder_inputs.toml @@ -11,6 +11,6 @@ # .builders/inputs_hash.py plus everything under .builders/images//. [inputs] -linux-aarch64 = "e48bf769667a4f30addf317d2b889aea045e025b981276a5cbfdf5b53ae86ca8" -linux-x86_64 = "5e769b5c5678a0c578bbaf2289a8359ade8f3420de2a7f7ed3c09217866014c7" -windows-x86_64 = "beba3774e0929bc4f9377cabcde2f797a83309d88be329154b3e099961c95884" +linux-aarch64 = "e3b9a63fa95c9d58a54926fd42d1a20ae738a6c05ff8338d995b8cd9c5497ef2" +linux-x86_64 = "58a8e70bf5f870e210d586662843cdc9948b5d90638e3487f1e07a2b10f27f19" +windows-x86_64 = "130572854fdcd9ca5d021af13087afa7384b1e659959087db21c77ac144ad313" diff --git a/.deps/image_digests.json b/.deps/image_digests.json index a40766f7f01f8..e67d22ca236fe 100644 --- a/.deps/image_digests.json +++ b/.deps/image_digests.json @@ -1,5 +1,5 @@ { - "linux-aarch64": "sha256:223fa103a2f1b67c98d2c15a250a9eec39b6b1768011096260f6e12cef1870c4", - "linux-x86_64": "sha256:7dca4137ffe24807e2e5ffafb4d50dbd9a201534c1c5e072618075d378e9b975", - "windows-x86_64": "sha256:ee9772fc71d78c232f6315e9609cf78a78213200ca24bcc55040f18d8e63313f" + "linux-aarch64": "sha256:bced710c0b1812c224caaa951b412ba3fbf2d299dcb4cb001b58898cd9e119ae", + "linux-x86_64": "sha256:82a4605484daf57ff3edfc2c4a10d19cb3ee592ba5cdf6a53605c99a76856ae3", + "windows-x86_64": "sha256:7ebc2f51eca870f551f663159b399e2cd98a15830f2a495a775dfd124f7f859b" } diff --git a/.deps/resolved/linux-aarch64_3.13.txt b/.deps/resolved/linux-aarch64_3.13.txt index 2e705db7d6fed..986b71d1407a1 100644 --- a/.deps/resolved/linux-aarch64_3.13.txt +++ b/.deps/resolved/linux-aarch64_3.13.txt @@ -1,30 +1,30 @@ -aerospike @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/aerospike/aerospike-7.1.1-20260418125217-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=a1de7c7019b1dd5363cdd1a838ba92185418a114be9b59f902e8aef66326c4ea -botocore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/botocore/botocore-1.42.72-20260421082705-py3-none-any.whl#sha256=f1933a8ca6c1108ed23f7b01f82577327fc254e330025887fdd4ba17db03e8e2 +aerospike @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/aerospike/aerospike-7.1.1-20260421153433-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=13e750c0fbc8fd5f41810e5b3e72be2d132124e47a148dd147352a84b90fc614 +botocore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/botocore/botocore-1.42.72-20260421153126-py3-none-any.whl#sha256=f1933a8ca6c1108ed23f7b01f82577327fc254e330025887fdd4ba17db03e8e2 cm-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/cm-client/cm_client-45.0.4-20260326173357-py3-none-manylinux2014_aarch64.whl#sha256=0bbcf2766028850c26a917deef3704a096cc9ba0c25220d45ff424334d25dcd7 -confluent-kafka @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/confluent-kafka/confluent_kafka-2.13.2-20260421095908-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=65e0d489118fa94ca54abea65610fa3f5d116c67fd84bc5561f741adade2b40a -cryptography @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/cryptography/cryptography-46.0.6-20260421095911-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=e3b8dc89254638fe20fda837433092b2b4f89e1a683710f9d05a4419dfbf39f7 +confluent-kafka @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/confluent-kafka/confluent_kafka-2.13.2-20260421153443-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=033107872bd70d3f96b0c6d0c91cc8cad173f143cefd74387538dc75f980448d +cryptography @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/cryptography/cryptography-46.0.6-20260421153446-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=e55c7befde32fd6ce7e378b4c343ecc50490df8eee3e9ee8dc59d77ab7ef9772 ddtrace @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/ddtrace/ddtrace-3.19.5-20260417115249-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl#sha256=a4f8d07adccdd43908156ab2c143dbb6261ed9a3c43ba58a3bb6bd1b6ef94734 foundationdb @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/foundationdb/foundationdb-6.3.25-20260326173358-py3-none-manylinux2014_aarch64.whl#sha256=d34180500220db4458e57505c774de0363456d4129f0e3fe98c9e99e8eef77c2 -gssapi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/gssapi/gssapi-1.11.1-20260420112228-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=95e5e8521bb191907748a7360ffd025398aa861cb47014c551384380d52be412 -keystoneauth1 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/keystoneauth1/keystoneauth1-5.13.1-20260421083930-py3-none-any.whl#sha256=a15092187950de965ff6096e203d31e461c61cfd47ec1f5249a0e2955187cba2 -krb5 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/krb5/krb5-0.9.0-20260420112240-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=9700f818130cf996f844203d60c9e41b95700a90916c9ef39b008166ba6c9f71 -openstacksdk @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/openstacksdk/openstacksdk-4.10.0-20260421083943-py3-none-any.whl#sha256=88abe8f44e3b8c5c25b1093de735c700aa727a7ac408e273aa855d6db6ba38bf -os-service-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/os-service-types/os_service_types-1.8.2-20260421083957-py3-none-any.whl#sha256=758ccaa020eea0edd84bcf4123746ddd060d1dbaeef63d04d76bd2e0ae6f91d8 -pbr @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pbr/pbr-7.0.3-20260421084012-py2.py3-none-any.whl#sha256=1544652b80307f0b4c491bd66f58f969cb0656994e632365f90e8e044c223b4e +gssapi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/gssapi/gssapi-1.11.1-20260421153448-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=861b3cde93aec1b05a5e9ac917780dbac66d773bd427834bdf738825e559d197 +keystoneauth1 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/keystoneauth1/keystoneauth1-5.13.1-20260421153141-py3-none-any.whl#sha256=a15092187950de965ff6096e203d31e461c61cfd47ec1f5249a0e2955187cba2 +krb5 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/krb5/krb5-0.9.0-20260421153455-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=f6dd9d9a2d81b129b52ace318104ea9c04c1e7a5e11724aede73ba7c12f7fcac +openstacksdk @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/openstacksdk/openstacksdk-4.10.0-20260421153148-py3-none-any.whl#sha256=88abe8f44e3b8c5c25b1093de735c700aa727a7ac408e273aa855d6db6ba38bf +os-service-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/os-service-types/os_service_types-1.8.2-20260421153155-py3-none-any.whl#sha256=758ccaa020eea0edd84bcf4123746ddd060d1dbaeef63d04d76bd2e0ae6f91d8 +pbr @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pbr/pbr-7.0.3-20260421153201-py2.py3-none-any.whl#sha256=1544652b80307f0b4c491bd66f58f969cb0656994e632365f90e8e044c223b4e psutil @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psutil/psutil-6.0.0-20260326173401-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=22e075e3cbc57b5da0d93f72f691746c5198ce88c5aea6fdb54186b3e8c46832 -psycopg-c @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psycopg-c/psycopg_c-3.3.3-20260418125308-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=e9a6db500356a67b07cf971b394b92445797d608578961cd2c931ec1d61567b9 +psycopg-c @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psycopg-c/psycopg_c-3.3.3-20260421153515-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=0bee628a33b6d05bae2f8ba97995e4f6c95ae6a6bb4c7b27160a17b7fb21c8ec pymongo @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymongo/pymongo-4.8.0-20260415154515-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=30d8af4ef8fda85d1a865bdb254e6b2e3988f26b723eb39a4843c766371ff517 pyodbc @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pyodbc/pyodbc-5.3.0-20260415154516-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=91a4191cf30930755d82e8edd6ac861443dfb6fbbf7915753b73209038ad5ad2 -pysnmp-mibs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pysnmp-mibs/pysnmp_mibs-0.1.6-20260421084027-py2.py3-none-any.whl#sha256=0cc4610711208cdc64361464a23d1f2dce88ec5990a12b4bdce4f13b6a169810 +pysnmp-mibs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pysnmp-mibs/pysnmp_mibs-0.1.6-20260421153209-py2.py3-none-any.whl#sha256=0cc4610711208cdc64361464a23d1f2dce88ec5990a12b4bdce4f13b6a169810 pyvmomi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pyvmomi/pyvmomi-8.0.3.0.1-20260326173403-py2.py3-none-manylinux2014_aarch64.whl#sha256=dd71476b7308286ed4219373ca9523e4f06bfed3f5932f60e5c67d8d5a673e1e -requests-unixsocket2 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/requests-unixsocket2/requests_unixsocket2-1.0.1-20260421084042-py3-none-any.whl#sha256=aae3f1743ab60955ea91e9a095d54997ea56b956bab652bf194379ef4dc6fa7f -securesystemslib @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/securesystemslib/securesystemslib-0.28.0-20260421084056-py3-none-any.whl#sha256=861ab6f8c1930e0c05915f32a34f1c4ae1d76ee542ad2b424121e3e26a9fb1dd -setuptools @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/setuptools/setuptools-82.0.1-20260421084111-py3-none-any.whl#sha256=b020c62c9ea6c1c3e7a29a8e385967909ceb85a77398f7fbe3c63e2abab52e87 +requests-unixsocket2 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/requests-unixsocket2/requests_unixsocket2-1.0.1-20260421153216-py3-none-any.whl#sha256=aae3f1743ab60955ea91e9a095d54997ea56b956bab652bf194379ef4dc6fa7f +securesystemslib @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/securesystemslib/securesystemslib-0.28.0-20260421153223-py3-none-any.whl#sha256=861ab6f8c1930e0c05915f32a34f1c4ae1d76ee542ad2b424121e3e26a9fb1dd +setuptools @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/setuptools/setuptools-82.0.1-20260421153230-py3-none-any.whl#sha256=b020c62c9ea6c1c3e7a29a8e385967909ceb85a77398f7fbe3c63e2abab52e87 simplejson @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/simplejson/simplejson-3.20.2-20260326173404-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#sha256=cb739020a718c2e32041a0fa0a3f79398f45c067347fe8f286c8222fa777bc5d -stevedore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/stevedore/stevedore-5.7.0-20260421084126-py3-none-any.whl#sha256=0cf2a7cb9c915eddc77a591df48e8ab78f93167e8ac77d0efb04eb375f91d8b2 -supervisor @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/supervisor/supervisor-4.3.0-20260421084140-py2.py3-none-any.whl#sha256=81d63e968a5133203a334102b8e6e72b1f5ecfc9673c1af7680f9f7e0db8d4fd -vertica-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/vertica-python/vertica_python-1.4.0-20260421084155-py3-none-any.whl#sha256=df8d667b7bd070532a72c25f37e7259d3673c1908ae726fdfb3087d777caa9da -websocket-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/websocket-client/websocket_client-1.9.0-20260421084209-py3-none-any.whl#sha256=b628876a9b1eed1d49f1a230bf4b1c21fa3cd9163594f9f9628c8a8b22f97e10 +stevedore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/stevedore/stevedore-5.7.0-20260421153237-py3-none-any.whl#sha256=0cf2a7cb9c915eddc77a591df48e8ab78f93167e8ac77d0efb04eb375f91d8b2 +supervisor @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/supervisor/supervisor-4.3.0-20260421153243-py2.py3-none-any.whl#sha256=81d63e968a5133203a334102b8e6e72b1f5ecfc9673c1af7680f9f7e0db8d4fd +vertica-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/vertica-python/vertica_python-1.4.0-20260421153250-py3-none-any.whl#sha256=df8d667b7bd070532a72c25f37e7259d3673c1908ae726fdfb3087d777caa9da +websocket-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/websocket-client/websocket_client-1.9.0-20260421153257-py3-none-any.whl#sha256=b628876a9b1eed1d49f1a230bf4b1c21fa3cd9163594f9f9628c8a8b22f97e10 annotated-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/annotated-types/annotated_types-0.7.0-py3-none-any.whl#sha256=1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 attrs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/attrs/attrs-26.1.0-py3-none-any.whl#sha256=c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 aws-msk-iam-sasl-signer-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/aws-msk-iam-sasl-signer-python/aws_msk_iam_sasl_signer_python-1.0.2-py2.py3-none-any.whl#sha256=310eb2db9ca0ff55ed06a24212739b87533e7f1cf6f34e43aabbd97a3b21290e diff --git a/.deps/resolved/linux-x86_64_3.13.txt b/.deps/resolved/linux-x86_64_3.13.txt index c9c03fa08e90e..80cc9c1137912 100644 --- a/.deps/resolved/linux-x86_64_3.13.txt +++ b/.deps/resolved/linux-x86_64_3.13.txt @@ -1,31 +1,31 @@ -aerospike @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/aerospike/aerospike-7.1.1-20260418130014-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=611776d7bc950a342e16b75973aadc0bf11280666055d4d868bac6d160e7164d -botocore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/botocore/botocore-1.42.72-20260421100323-py3-none-any.whl#sha256=f1933a8ca6c1108ed23f7b01f82577327fc254e330025887fdd4ba17db03e8e2 +aerospike @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/aerospike/aerospike-7.1.1-20260421153120-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=aba4253796375b00ed7850c6cab414673bdf429861ecdb4338208665ea9df767 +botocore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/botocore/botocore-1.42.72-20260421153126-py3-none-any.whl#sha256=f1933a8ca6c1108ed23f7b01f82577327fc254e330025887fdd4ba17db03e8e2 cm-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/cm-client/cm_client-45.0.4-20260326173305-py3-none-manylinux2014_x86_64.whl#sha256=0bbcf2766028850c26a917deef3704a096cc9ba0c25220d45ff424334d25dcd7 -confluent-kafka @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/confluent-kafka/confluent_kafka-2.13.2-20260421100447-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=dacc5df49c3e15ddf4f7384660f0feac760d9ba089e1ac3a73322523f2bd9c1f -cryptography @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/cryptography/cryptography-46.0.6-20260421100449-cp313-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=547c00f19b05f938443269e99707d4bfdb397109f24c3fdf324edd5f9fdd6331 +confluent-kafka @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/confluent-kafka/confluent_kafka-2.13.2-20260421153130-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=9a9dd7e8d4a0cbf46fd66f378c0189672853740ffdc025aaf23004d892889bc8 +cryptography @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/cryptography/cryptography-46.0.6-20260421153133-cp313-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=7770e7cd9dba207af90ef793df2de6544dd445d2c0489457fd208ab3e60bc72d ddtrace @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/ddtrace/ddtrace-3.19.5-20260417115349-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=e0aa298cfd1947902fed35d8fa6129c90f6d5e687328b0cba6fe137714198608 foundationdb @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/foundationdb/foundationdb-6.3.25-20260326173307-py3-none-manylinux2014_x86_64.whl#sha256=d34180500220db4458e57505c774de0363456d4129f0e3fe98c9e99e8eef77c2 -gssapi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/gssapi/gssapi-1.11.1-20260418130032-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=9cf9e44ae3c9adbf681ab815511ce6c274f6403f106fc8e8e73eaa9268a0913f -keystoneauth1 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/keystoneauth1/keystoneauth1-5.13.1-20260421100330-py3-none-any.whl#sha256=a15092187950de965ff6096e203d31e461c61cfd47ec1f5249a0e2955187cba2 -krb5 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/krb5/krb5-0.9.0-20260418130041-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=082536495ab7afb814a87311d3f5000b1d85b5afe19c5f52e8ea98c1da9c0df0 -openstacksdk @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/openstacksdk/openstacksdk-4.10.0-20260421100335-py3-none-any.whl#sha256=88abe8f44e3b8c5c25b1093de735c700aa727a7ac408e273aa855d6db6ba38bf -os-service-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/os-service-types/os_service_types-1.8.2-20260421100341-py3-none-any.whl#sha256=758ccaa020eea0edd84bcf4123746ddd060d1dbaeef63d04d76bd2e0ae6f91d8 -pbr @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pbr/pbr-7.0.3-20260421100347-py2.py3-none-any.whl#sha256=1544652b80307f0b4c491bd66f58f969cb0656994e632365f90e8e044c223b4e +gssapi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/gssapi/gssapi-1.11.1-20260421153134-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=b0eefba08d72fa793402e49072b61c84e8414c9fdeda2b80dfa8a47c3865dc66 +keystoneauth1 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/keystoneauth1/keystoneauth1-5.13.1-20260421153141-py3-none-any.whl#sha256=a15092187950de965ff6096e203d31e461c61cfd47ec1f5249a0e2955187cba2 +krb5 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/krb5/krb5-0.9.0-20260421153142-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=1814588e913f80e3f81753b2cb601eb1fce0001d33749cdc78b6134c20f1382a +openstacksdk @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/openstacksdk/openstacksdk-4.10.0-20260421153148-py3-none-any.whl#sha256=88abe8f44e3b8c5c25b1093de735c700aa727a7ac408e273aa855d6db6ba38bf +os-service-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/os-service-types/os_service_types-1.8.2-20260421153155-py3-none-any.whl#sha256=758ccaa020eea0edd84bcf4123746ddd060d1dbaeef63d04d76bd2e0ae6f91d8 +pbr @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pbr/pbr-7.0.3-20260421153201-py2.py3-none-any.whl#sha256=1544652b80307f0b4c491bd66f58f969cb0656994e632365f90e8e044c223b4e psutil @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psutil/psutil-6.0.0-20260326173308-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=af8dd07e6f1bf1d41381ad59dff0a0a36153c7dd5a69becc765010329f17db01 -psycopg-c @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psycopg-c/psycopg_c-3.3.3-20260418130105-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=1381485b44a98283661adeee3aae934dc1275eef8f62c8cedce46ffa750708d2 +psycopg-c @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psycopg-c/psycopg_c-3.3.3-20260421153202-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=e7eafc789e999ae259d825fc9425655f627584bc1ff76c8c0847d53e236df6cf pymongo @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymongo/pymongo-4.8.0-20260415154630-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=a0bc69dc57d3ba6db1fc23ac471ddd5edeeef737fef8e912b0b96126f0b13a8c pymqi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymqi/pymqi-1.12.13-20260326173310-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=20b5e67134719cae77a2b6c20da5219931b3735e30538567fb2b73e34219203b pyodbc @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pyodbc/pyodbc-5.3.0-20260415154630-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=80d6bdc8ba09a778205c68493fa72a44a599fd8c31803a4f4d4e3bcf1f2284fe -pysnmp-mibs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pysnmp-mibs/pysnmp_mibs-0.1.6-20260421100353-py2.py3-none-any.whl#sha256=0cc4610711208cdc64361464a23d1f2dce88ec5990a12b4bdce4f13b6a169810 +pysnmp-mibs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pysnmp-mibs/pysnmp_mibs-0.1.6-20260421153209-py2.py3-none-any.whl#sha256=0cc4610711208cdc64361464a23d1f2dce88ec5990a12b4bdce4f13b6a169810 pyvmomi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pyvmomi/pyvmomi-8.0.3.0.1-20260326173310-py2.py3-none-manylinux2014_x86_64.whl#sha256=dd71476b7308286ed4219373ca9523e4f06bfed3f5932f60e5c67d8d5a673e1e -requests-unixsocket2 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/requests-unixsocket2/requests_unixsocket2-1.0.1-20260421100359-py3-none-any.whl#sha256=aae3f1743ab60955ea91e9a095d54997ea56b956bab652bf194379ef4dc6fa7f -securesystemslib @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/securesystemslib/securesystemslib-0.28.0-20260421100405-py3-none-any.whl#sha256=861ab6f8c1930e0c05915f32a34f1c4ae1d76ee542ad2b424121e3e26a9fb1dd -setuptools @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/setuptools/setuptools-82.0.1-20260421100411-py3-none-any.whl#sha256=b020c62c9ea6c1c3e7a29a8e385967909ceb85a77398f7fbe3c63e2abab52e87 +requests-unixsocket2 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/requests-unixsocket2/requests_unixsocket2-1.0.1-20260421153216-py3-none-any.whl#sha256=aae3f1743ab60955ea91e9a095d54997ea56b956bab652bf194379ef4dc6fa7f +securesystemslib @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/securesystemslib/securesystemslib-0.28.0-20260421153223-py3-none-any.whl#sha256=861ab6f8c1930e0c05915f32a34f1c4ae1d76ee542ad2b424121e3e26a9fb1dd +setuptools @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/setuptools/setuptools-82.0.1-20260421153230-py3-none-any.whl#sha256=b020c62c9ea6c1c3e7a29a8e385967909ceb85a77398f7fbe3c63e2abab52e87 simplejson @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/simplejson/simplejson-3.20.2-20260326173311-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=dec16958f71ce93ac1c2fdc212800892ca22a9e90efcab5b5e01d121146cc5cc -stevedore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/stevedore/stevedore-5.7.0-20260421100416-py3-none-any.whl#sha256=0cf2a7cb9c915eddc77a591df48e8ab78f93167e8ac77d0efb04eb375f91d8b2 -supervisor @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/supervisor/supervisor-4.3.0-20260421100422-py2.py3-none-any.whl#sha256=81d63e968a5133203a334102b8e6e72b1f5ecfc9673c1af7680f9f7e0db8d4fd -vertica-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/vertica-python/vertica_python-1.4.0-20260421100428-py3-none-any.whl#sha256=df8d667b7bd070532a72c25f37e7259d3673c1908ae726fdfb3087d777caa9da -websocket-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/websocket-client/websocket_client-1.9.0-20260421100434-py3-none-any.whl#sha256=b628876a9b1eed1d49f1a230bf4b1c21fa3cd9163594f9f9628c8a8b22f97e10 +stevedore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/stevedore/stevedore-5.7.0-20260421153237-py3-none-any.whl#sha256=0cf2a7cb9c915eddc77a591df48e8ab78f93167e8ac77d0efb04eb375f91d8b2 +supervisor @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/supervisor/supervisor-4.3.0-20260421153243-py2.py3-none-any.whl#sha256=81d63e968a5133203a334102b8e6e72b1f5ecfc9673c1af7680f9f7e0db8d4fd +vertica-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/vertica-python/vertica_python-1.4.0-20260421153250-py3-none-any.whl#sha256=df8d667b7bd070532a72c25f37e7259d3673c1908ae726fdfb3087d777caa9da +websocket-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/websocket-client/websocket_client-1.9.0-20260421153257-py3-none-any.whl#sha256=b628876a9b1eed1d49f1a230bf4b1c21fa3cd9163594f9f9628c8a8b22f97e10 annotated-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/annotated-types/annotated_types-0.7.0-py3-none-any.whl#sha256=1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 attrs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/attrs/attrs-26.1.0-py3-none-any.whl#sha256=c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 aws-msk-iam-sasl-signer-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/aws-msk-iam-sasl-signer-python/aws_msk_iam_sasl_signer_python-1.0.2-py2.py3-none-any.whl#sha256=310eb2db9ca0ff55ed06a24212739b87533e7f1cf6f34e43aabbd97a3b21290e diff --git a/.deps/resolved/macos-aarch64_3.13.txt b/.deps/resolved/macos-aarch64_3.13.txt index 68eecc6f9b6ec..b787cd6baf8ac 100644 --- a/.deps/resolved/macos-aarch64_3.13.txt +++ b/.deps/resolved/macos-aarch64_3.13.txt @@ -1,28 +1,28 @@ -botocore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/botocore/botocore-1.42.72-20260421082705-py3-none-any.whl#sha256=f1933a8ca6c1108ed23f7b01f82577327fc254e330025887fdd4ba17db03e8e2 +botocore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/botocore/botocore-1.42.72-20260421133609-py3-none-any.whl#sha256=f1933a8ca6c1108ed23f7b01f82577327fc254e330025887fdd4ba17db03e8e2 cm-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/cm-client/cm_client-45.0.4-20260326173218-py3-none-macosx_12_0_universal2.whl#sha256=0bbcf2766028850c26a917deef3704a096cc9ba0c25220d45ff424334d25dcd7 -confluent-kafka @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/confluent-kafka/confluent_kafka-2.13.2-20260419053453-cp313-cp313-macosx_12_0_arm64.whl#sha256=344f33861abc0c7392317debd7386086022672d25c978cec64fc8dcf285c542b +confluent-kafka @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/confluent-kafka/confluent_kafka-2.13.2-20260421152810-cp313-cp313-macosx_12_0_arm64.whl#sha256=dacd007c85a087687bd5f1a42e05a435a5f61ab24848fe002028abe00b5e629e ddtrace @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/ddtrace/ddtrace-3.19.5-20260417115301-cp313-cp313-macosx_12_0_arm64.whl#sha256=1274db819aa41b189135f83ad2b8e37c6e26b8d2f25c60a725a01637ebd63ee4 foundationdb @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/foundationdb/foundationdb-6.3.25-20260326173219-py3-none-macosx_12_0_universal2.whl#sha256=d34180500220db4458e57505c774de0363456d4129f0e3fe98c9e99e8eef77c2 gssapi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/gssapi/gssapi-1.11.1-20260326173323-cp311-abi3-macosx_11_0_arm64.whl#sha256=b5f5ac28470db99338814e4285a491dc218b9bee3f8d20bfa219274e84bd87c4 -keystoneauth1 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/keystoneauth1/keystoneauth1-5.13.1-20260421083930-py3-none-any.whl#sha256=a15092187950de965ff6096e203d31e461c61cfd47ec1f5249a0e2955187cba2 +keystoneauth1 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/keystoneauth1/keystoneauth1-5.13.1-20260421133627-py3-none-any.whl#sha256=a15092187950de965ff6096e203d31e461c61cfd47ec1f5249a0e2955187cba2 krb5 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/krb5/krb5-0.9.0-20260326173323-cp311-abi3-macosx_11_0_arm64.whl#sha256=47f731bebe725962f7b644e7238a4c68eca2879f6c35842babda9140f263c615 -openstacksdk @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/openstacksdk/openstacksdk-4.10.0-20260421083943-py3-none-any.whl#sha256=88abe8f44e3b8c5c25b1093de735c700aa727a7ac408e273aa855d6db6ba38bf -os-service-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/os-service-types/os_service_types-1.8.2-20260421083957-py3-none-any.whl#sha256=758ccaa020eea0edd84bcf4123746ddd060d1dbaeef63d04d76bd2e0ae6f91d8 -pbr @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pbr/pbr-7.0.3-20260421084012-py2.py3-none-any.whl#sha256=1544652b80307f0b4c491bd66f58f969cb0656994e632365f90e8e044c223b4e +openstacksdk @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/openstacksdk/openstacksdk-4.10.0-20260421133641-py3-none-any.whl#sha256=88abe8f44e3b8c5c25b1093de735c700aa727a7ac408e273aa855d6db6ba38bf +os-service-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/os-service-types/os_service_types-1.8.2-20260421133656-py3-none-any.whl#sha256=758ccaa020eea0edd84bcf4123746ddd060d1dbaeef63d04d76bd2e0ae6f91d8 +pbr @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pbr/pbr-7.0.3-20260421133710-py2.py3-none-any.whl#sha256=1544652b80307f0b4c491bd66f58f969cb0656994e632365f90e8e044c223b4e psutil @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psutil/psutil-6.0.0-20260326173324-cp38-abi3-macosx_11_0_arm64.whl#sha256=33472398d3e6da655a430b106920164b04f036f891bd0ea803a4309ed2a80ef9 -psycopg-c @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psycopg-c/psycopg_c-3.3.3-20260418125458-cp313-cp313-macosx_12_0_arm64.whl#sha256=2c853472bed5a003bdcfbec159bf7849d1ac7a2a3867055d0005d1aa647549cf +psycopg-c @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psycopg-c/psycopg_c-3.3.3-20260421152837-cp313-cp313-macosx_12_0_arm64.whl#sha256=bfe56ecdab4dce0ae8442ef05e1a37df4b1d63741f7188f66f9005fc11bfd013 pymongo @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymongo/pymongo-4.8.0-20260326173325-cp313-cp313-macosx_12_0_arm64.whl#sha256=7c94a2b73c148f84ab217ea2084d07e01e834d49244dec026b473e889016f556 pymqi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymqi/pymqi-1.12.13-20260326173325-cp313-cp313-macosx_12_0_arm64.whl#sha256=482b0d2593868c595ec53db794a61a792c0e1fcad04aee86db96afaadf986baf -pysnmp-mibs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pysnmp-mibs/pysnmp_mibs-0.1.6-20260421084027-py2.py3-none-any.whl#sha256=0cc4610711208cdc64361464a23d1f2dce88ec5990a12b4bdce4f13b6a169810 +pysnmp-mibs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pysnmp-mibs/pysnmp_mibs-0.1.6-20260421133727-py2.py3-none-any.whl#sha256=0cc4610711208cdc64361464a23d1f2dce88ec5990a12b4bdce4f13b6a169810 pyvmomi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pyvmomi/pyvmomi-8.0.3.0.1-20260326173224-py2.py3-none-macosx_12_0_universal2.whl#sha256=dd71476b7308286ed4219373ca9523e4f06bfed3f5932f60e5c67d8d5a673e1e -requests-unixsocket2 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/requests-unixsocket2/requests_unixsocket2-1.0.1-20260421084042-py3-none-any.whl#sha256=aae3f1743ab60955ea91e9a095d54997ea56b956bab652bf194379ef4dc6fa7f -securesystemslib @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/securesystemslib/securesystemslib-0.28.0-20260421084056-py3-none-any.whl#sha256=861ab6f8c1930e0c05915f32a34f1c4ae1d76ee542ad2b424121e3e26a9fb1dd -setuptools @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/setuptools/setuptools-82.0.1-20260421084111-py3-none-any.whl#sha256=b020c62c9ea6c1c3e7a29a8e385967909ceb85a77398f7fbe3c63e2abab52e87 +requests-unixsocket2 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/requests-unixsocket2/requests_unixsocket2-1.0.1-20260421133742-py3-none-any.whl#sha256=aae3f1743ab60955ea91e9a095d54997ea56b956bab652bf194379ef4dc6fa7f +securesystemslib @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/securesystemslib/securesystemslib-0.28.0-20260421133756-py3-none-any.whl#sha256=861ab6f8c1930e0c05915f32a34f1c4ae1d76ee542ad2b424121e3e26a9fb1dd +setuptools @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/setuptools/setuptools-82.0.1-20260421133811-py3-none-any.whl#sha256=b020c62c9ea6c1c3e7a29a8e385967909ceb85a77398f7fbe3c63e2abab52e87 simplejson @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/simplejson/simplejson-3.20.2-20260326173326-cp313-cp313-macosx_11_0_arm64.whl#sha256=fc3c4e9feecd85f1831fb0983b04e7170765b5047c3c629ab97c0c49190a5da8 -stevedore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/stevedore/stevedore-5.7.0-20260421084126-py3-none-any.whl#sha256=0cf2a7cb9c915eddc77a591df48e8ab78f93167e8ac77d0efb04eb375f91d8b2 -supervisor @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/supervisor/supervisor-4.3.0-20260421084140-py2.py3-none-any.whl#sha256=81d63e968a5133203a334102b8e6e72b1f5ecfc9673c1af7680f9f7e0db8d4fd -vertica-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/vertica-python/vertica_python-1.4.0-20260421084155-py3-none-any.whl#sha256=df8d667b7bd070532a72c25f37e7259d3673c1908ae726fdfb3087d777caa9da -websocket-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/websocket-client/websocket_client-1.9.0-20260421084209-py3-none-any.whl#sha256=b628876a9b1eed1d49f1a230bf4b1c21fa3cd9163594f9f9628c8a8b22f97e10 +stevedore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/stevedore/stevedore-5.7.0-20260421133826-py3-none-any.whl#sha256=0cf2a7cb9c915eddc77a591df48e8ab78f93167e8ac77d0efb04eb375f91d8b2 +supervisor @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/supervisor/supervisor-4.3.0-20260421133841-py2.py3-none-any.whl#sha256=81d63e968a5133203a334102b8e6e72b1f5ecfc9673c1af7680f9f7e0db8d4fd +vertica-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/vertica-python/vertica_python-1.4.0-20260421133856-py3-none-any.whl#sha256=df8d667b7bd070532a72c25f37e7259d3673c1908ae726fdfb3087d777caa9da +websocket-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/websocket-client/websocket_client-1.9.0-20260421133911-py3-none-any.whl#sha256=b628876a9b1eed1d49f1a230bf4b1c21fa3cd9163594f9f9628c8a8b22f97e10 annotated-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/annotated-types/annotated_types-0.7.0-py3-none-any.whl#sha256=1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 attrs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/attrs/attrs-26.1.0-py3-none-any.whl#sha256=c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 aws-msk-iam-sasl-signer-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/aws-msk-iam-sasl-signer-python/aws_msk_iam_sasl_signer_python-1.0.2-py2.py3-none-any.whl#sha256=310eb2db9ca0ff55ed06a24212739b87533e7f1cf6f34e43aabbd97a3b21290e diff --git a/.deps/resolved/macos-x86_64_3.13.txt b/.deps/resolved/macos-x86_64_3.13.txt index 602170b96af26..200b9e8777924 100644 --- a/.deps/resolved/macos-x86_64_3.13.txt +++ b/.deps/resolved/macos-x86_64_3.13.txt @@ -1,28 +1,28 @@ -botocore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/botocore/botocore-1.42.72-20260421100323-py3-none-any.whl#sha256=f1933a8ca6c1108ed23f7b01f82577327fc254e330025887fdd4ba17db03e8e2 +botocore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/botocore/botocore-1.42.72-20260421153126-py3-none-any.whl#sha256=f1933a8ca6c1108ed23f7b01f82577327fc254e330025887fdd4ba17db03e8e2 cm-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/cm-client/cm_client-45.0.4-20260326173218-py3-none-macosx_12_0_universal2.whl#sha256=0bbcf2766028850c26a917deef3704a096cc9ba0c25220d45ff424334d25dcd7 -confluent-kafka @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/confluent-kafka/confluent_kafka-2.13.2-20260419053856-cp313-cp313-macosx_12_0_x86_64.whl#sha256=e217d743a2d906dd4cbe16d711aad2bc0519772fc00891e8159f004fd33c5a5a +confluent-kafka @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/confluent-kafka/confluent_kafka-2.13.2-20260421153309-cp313-cp313-macosx_12_0_x86_64.whl#sha256=f8c08d2f08a641599ceb4661e740743df09da1e92fc318764a5c172b1f72ab7b ddtrace @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/ddtrace/ddtrace-3.19.5-20260417115332-cp313-cp313-macosx_12_0_x86_64.whl#sha256=813c9fae90bd65d60d97e183b21dff8f9d54591a9186cf163f606fb11b7a6575 foundationdb @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/foundationdb/foundationdb-6.3.25-20260326173219-py3-none-macosx_12_0_universal2.whl#sha256=d34180500220db4458e57505c774de0363456d4129f0e3fe98c9e99e8eef77c2 gssapi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/gssapi/gssapi-1.11.1-20260326173219-cp311-abi3-macosx_10_9_x86_64.whl#sha256=91608d102056a7768b9e572ccbe2ccbe7da84688a84f05bb8c4ea56e9d0e979d -keystoneauth1 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/keystoneauth1/keystoneauth1-5.13.1-20260421100330-py3-none-any.whl#sha256=a15092187950de965ff6096e203d31e461c61cfd47ec1f5249a0e2955187cba2 +keystoneauth1 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/keystoneauth1/keystoneauth1-5.13.1-20260421153141-py3-none-any.whl#sha256=a15092187950de965ff6096e203d31e461c61cfd47ec1f5249a0e2955187cba2 krb5 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/krb5/krb5-0.9.0-20260326173220-cp311-abi3-macosx_10_9_x86_64.whl#sha256=0fe3a687f4e9a8d305ba0183f9b8368e9ed13f4e32716ba3a14de77e12f1e978 -openstacksdk @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/openstacksdk/openstacksdk-4.10.0-20260421100335-py3-none-any.whl#sha256=88abe8f44e3b8c5c25b1093de735c700aa727a7ac408e273aa855d6db6ba38bf -os-service-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/os-service-types/os_service_types-1.8.2-20260421100341-py3-none-any.whl#sha256=758ccaa020eea0edd84bcf4123746ddd060d1dbaeef63d04d76bd2e0ae6f91d8 -pbr @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pbr/pbr-7.0.3-20260421100347-py2.py3-none-any.whl#sha256=1544652b80307f0b4c491bd66f58f969cb0656994e632365f90e8e044c223b4e +openstacksdk @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/openstacksdk/openstacksdk-4.10.0-20260421153148-py3-none-any.whl#sha256=88abe8f44e3b8c5c25b1093de735c700aa727a7ac408e273aa855d6db6ba38bf +os-service-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/os-service-types/os_service_types-1.8.2-20260421153155-py3-none-any.whl#sha256=758ccaa020eea0edd84bcf4123746ddd060d1dbaeef63d04d76bd2e0ae6f91d8 +pbr @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pbr/pbr-7.0.3-20260421153201-py2.py3-none-any.whl#sha256=1544652b80307f0b4c491bd66f58f969cb0656994e632365f90e8e044c223b4e psutil @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psutil/psutil-6.0.0-20260326173222-cp36-abi3-macosx_10_9_x86_64.whl#sha256=81ae816033cb82995bc78424b02886430400b730698d6a7c492e3256b7854777 -psycopg-c @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psycopg-c/psycopg_c-3.3.3-20260418125859-cp313-cp313-macosx_12_0_x86_64.whl#sha256=eb227dea25dadacf8cfe6a20fb7206f889723f0990b603ae388d9e5fb5087110 +psycopg-c @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psycopg-c/psycopg_c-3.3.3-20260421153335-cp313-cp313-macosx_12_0_x86_64.whl#sha256=e8ab0dba4501610ffbddf96a2747ab5894650634498b6933c7646852f1933520 pymongo @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymongo/pymongo-4.8.0-20260326173223-cp313-cp313-macosx_12_0_x86_64.whl#sha256=8b8c0174d55284134d7373fa1116522a241804560b86f05b883d4964692caaaa pymqi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymqi/pymqi-1.12.13-20260326173223-cp313-cp313-macosx_12_0_x86_64.whl#sha256=95ed07eebe53c2720cdaaf5d7de3364c80d373b9286b4a1b301f157592ee8ccb -pysnmp-mibs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pysnmp-mibs/pysnmp_mibs-0.1.6-20260421100353-py2.py3-none-any.whl#sha256=0cc4610711208cdc64361464a23d1f2dce88ec5990a12b4bdce4f13b6a169810 +pysnmp-mibs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pysnmp-mibs/pysnmp_mibs-0.1.6-20260421153209-py2.py3-none-any.whl#sha256=0cc4610711208cdc64361464a23d1f2dce88ec5990a12b4bdce4f13b6a169810 pyvmomi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pyvmomi/pyvmomi-8.0.3.0.1-20260326173224-py2.py3-none-macosx_12_0_universal2.whl#sha256=dd71476b7308286ed4219373ca9523e4f06bfed3f5932f60e5c67d8d5a673e1e -requests-unixsocket2 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/requests-unixsocket2/requests_unixsocket2-1.0.1-20260421100359-py3-none-any.whl#sha256=aae3f1743ab60955ea91e9a095d54997ea56b956bab652bf194379ef4dc6fa7f -securesystemslib @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/securesystemslib/securesystemslib-0.28.0-20260421100405-py3-none-any.whl#sha256=861ab6f8c1930e0c05915f32a34f1c4ae1d76ee542ad2b424121e3e26a9fb1dd -setuptools @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/setuptools/setuptools-82.0.1-20260421100411-py3-none-any.whl#sha256=b020c62c9ea6c1c3e7a29a8e385967909ceb85a77398f7fbe3c63e2abab52e87 +requests-unixsocket2 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/requests-unixsocket2/requests_unixsocket2-1.0.1-20260421153216-py3-none-any.whl#sha256=aae3f1743ab60955ea91e9a095d54997ea56b956bab652bf194379ef4dc6fa7f +securesystemslib @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/securesystemslib/securesystemslib-0.28.0-20260421153223-py3-none-any.whl#sha256=861ab6f8c1930e0c05915f32a34f1c4ae1d76ee542ad2b424121e3e26a9fb1dd +setuptools @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/setuptools/setuptools-82.0.1-20260421153230-py3-none-any.whl#sha256=b020c62c9ea6c1c3e7a29a8e385967909ceb85a77398f7fbe3c63e2abab52e87 simplejson @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/simplejson/simplejson-3.20.2-20260326173225-cp313-cp313-macosx_10_13_x86_64.whl#sha256=41b283f75ddb7e47b24fb57dc37d88078e51cd777438f368224e1282fc8ee465 -stevedore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/stevedore/stevedore-5.7.0-20260421100416-py3-none-any.whl#sha256=0cf2a7cb9c915eddc77a591df48e8ab78f93167e8ac77d0efb04eb375f91d8b2 -supervisor @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/supervisor/supervisor-4.3.0-20260421100422-py2.py3-none-any.whl#sha256=81d63e968a5133203a334102b8e6e72b1f5ecfc9673c1af7680f9f7e0db8d4fd -vertica-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/vertica-python/vertica_python-1.4.0-20260421100428-py3-none-any.whl#sha256=df8d667b7bd070532a72c25f37e7259d3673c1908ae726fdfb3087d777caa9da -websocket-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/websocket-client/websocket_client-1.9.0-20260421100434-py3-none-any.whl#sha256=b628876a9b1eed1d49f1a230bf4b1c21fa3cd9163594f9f9628c8a8b22f97e10 +stevedore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/stevedore/stevedore-5.7.0-20260421153237-py3-none-any.whl#sha256=0cf2a7cb9c915eddc77a591df48e8ab78f93167e8ac77d0efb04eb375f91d8b2 +supervisor @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/supervisor/supervisor-4.3.0-20260421153243-py2.py3-none-any.whl#sha256=81d63e968a5133203a334102b8e6e72b1f5ecfc9673c1af7680f9f7e0db8d4fd +vertica-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/vertica-python/vertica_python-1.4.0-20260421153250-py3-none-any.whl#sha256=df8d667b7bd070532a72c25f37e7259d3673c1908ae726fdfb3087d777caa9da +websocket-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/websocket-client/websocket_client-1.9.0-20260421153257-py3-none-any.whl#sha256=b628876a9b1eed1d49f1a230bf4b1c21fa3cd9163594f9f9628c8a8b22f97e10 annotated-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/annotated-types/annotated_types-0.7.0-py3-none-any.whl#sha256=1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 attrs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/attrs/attrs-26.1.0-py3-none-any.whl#sha256=c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 aws-msk-iam-sasl-signer-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/aws-msk-iam-sasl-signer-python/aws_msk_iam_sasl_signer_python-1.0.2-py2.py3-none-any.whl#sha256=310eb2db9ca0ff55ed06a24212739b87533e7f1cf6f34e43aabbd97a3b21290e diff --git a/.deps/resolved/windows-x86_64_3.13.txt b/.deps/resolved/windows-x86_64_3.13.txt index aae4cea5f0b9c..ca37c76eedd57 100644 --- a/.deps/resolved/windows-x86_64_3.13.txt +++ b/.deps/resolved/windows-x86_64_3.13.txt @@ -1,28 +1,28 @@ -botocore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/botocore/botocore-1.42.72-20260421100149-py3-none-any.whl#sha256=6f69d4818864f67ab304ac48497fefcc7f4fdd9bbcb9403cbc22dbe211177824 +botocore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/botocore/botocore-1.42.72-20260421152939-py3-none-any.whl#sha256=6f69d4818864f67ab304ac48497fefcc7f4fdd9bbcb9403cbc22dbe211177824 cm-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/cm-client/cm_client-45.0.4-20260326173335-py3-none-win_amd64.whl#sha256=6a11ff78eeff20d6a20036e7320a2cb1fd4a5c318a2f1b81b1449efea34048eb colorama @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/colorama/colorama-0.4.6-20260417115313-py2.py3-none-any.whl#sha256=3eb3f5bc1022d96fbe8df6f419cfb07d028e24c055cc3c59517fa49a95ab067a -confluent-kafka @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/confluent-kafka/confluent_kafka-2.13.2-20260421100152-cp313-cp313-win_amd64.whl#sha256=a36f5a37b3471c7cadd85ff8c631db92240291be32c0fb76aa442c31b9f6e7eb +confluent-kafka @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/confluent-kafka/confluent_kafka-2.13.2-20260421152942-cp313-cp313-win_amd64.whl#sha256=d117d3bf84a201f672010af224fbf252fbe9041eaa961451516ec4f66e233a3d ddtrace @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/ddtrace/ddtrace-3.19.5-20260417115314-cp313-cp313-win_amd64.whl#sha256=4f3009589d1c2e0ca84fe8bdb20367de10f090e84cb401ab1d538055927ac0f7 foundationdb @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/foundationdb/foundationdb-6.3.25-20260326173337-py3-none-win_amd64.whl#sha256=828ed23b81a64a5495b1091dd8a66ea51e84c55d9d814c5b6baf7b80dbd9881b -keystoneauth1 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/keystoneauth1/keystoneauth1-5.13.1-20260421100159-py3-none-any.whl#sha256=81b21cc6f3283215bb1a993f7c8240a0aeef36775d52ccca99c438075e054fba -openstacksdk @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/openstacksdk/openstacksdk-4.10.0-20260421100204-py3-none-any.whl#sha256=4ac88799ad5c355825b9567f5ca00fe9bcbd97cfe2649f60500fbe5f66610732 -os-service-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/os-service-types/os_service_types-1.8.2-20260421100210-py3-none-any.whl#sha256=668903c54b88cc4db5fd1dcbaf7cf7417220ef70592b70b49a76d202e8a7f4e8 -pbr @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pbr/pbr-7.0.3-20260421100216-py2.py3-none-any.whl#sha256=dbc2e1e0dbf694097374a40b72c890c915302ae4dd7d37c73db9cff8bf520c4b +keystoneauth1 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/keystoneauth1/keystoneauth1-5.13.1-20260421152949-py3-none-any.whl#sha256=81b21cc6f3283215bb1a993f7c8240a0aeef36775d52ccca99c438075e054fba +openstacksdk @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/openstacksdk/openstacksdk-4.10.0-20260421152955-py3-none-any.whl#sha256=4ac88799ad5c355825b9567f5ca00fe9bcbd97cfe2649f60500fbe5f66610732 +os-service-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/os-service-types/os_service_types-1.8.2-20260421153002-py3-none-any.whl#sha256=668903c54b88cc4db5fd1dcbaf7cf7417220ef70592b70b49a76d202e8a7f4e8 +pbr @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pbr/pbr-7.0.3-20260421153008-py2.py3-none-any.whl#sha256=dbc2e1e0dbf694097374a40b72c890c915302ae4dd7d37c73db9cff8bf520c4b psutil @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psutil/psutil-6.0.0-20260326173339-cp37-abi3-win_amd64.whl#sha256=484a4a6e0e16a9adf22b01dc2917426536c8bf63378e445816eee9833aad4f71 -psycopg-c @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psycopg-c/psycopg_c-3.3.3-20260421100219-cp313-cp313-win_amd64.whl#sha256=7f90c425cf418f9cf66009096134f8279908392c16f468af3b96781704ef2de7 -pymongo @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymongo/pymongo-4.8.0-20260421100222-cp313-cp313-win_amd64.whl#sha256=3d30f69794ad794f74301f24ed49fcd1a2acb8eb981c19465263f68cab18fb8a -pymqi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymqi/pymqi-1.12.13-20260421100226-cp313-cp313-win_amd64.whl#sha256=dcddff1b1dfcab879595da327f922a762e0380928632f387671e955e02c06bfd -pysnmp-mibs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pysnmp-mibs/pysnmp_mibs-0.1.6-20260421100231-py2.py3-none-any.whl#sha256=b3796e82ce920d942b3e2de5af4c8567738b72caffac49ec6d88684fd0365690 +psycopg-c @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/psycopg-c/psycopg_c-3.3.3-20260421153012-cp313-cp313-win_amd64.whl#sha256=96bdfed0be771bb7e311a30c196fc9cead6b46495471025abc2b3e2df5c9a06f +pymongo @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymongo/pymongo-4.8.0-20260421153016-cp313-cp313-win_amd64.whl#sha256=763de328e56a4b33ea9a1885a69ebe8e4dfa2d32317670b1be2bc088931f6b15 +pymqi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pymqi/pymqi-1.12.13-20260421153019-cp313-cp313-win_amd64.whl#sha256=e7a0dcbb13ac844510d5b6293c75f15fe4aab7d052be027195f70057eda3351b +pysnmp-mibs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pysnmp-mibs/pysnmp_mibs-0.1.6-20260421153026-py2.py3-none-any.whl#sha256=b3796e82ce920d942b3e2de5af4c8567738b72caffac49ec6d88684fd0365690 pyvmomi @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pyvmomi/pyvmomi-8.0.3.0.1-20260326173340-py2.py3-none-win_amd64.whl#sha256=c8487fb88881dc6bfc3507b9c351929221c8e85aa5e74179b82cda9d21364218 pywin32 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/pywin32/pywin32-311-20260326173341-cp313-cp313-win_amd64.whl#sha256=1e7784bf006cbfd7ffc4ce238eecc6ae43bfaf5d8132a6401d58a4ad0a36aea5 -requests-unixsocket2 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/requests-unixsocket2/requests_unixsocket2-1.0.1-20260421100238-py3-none-any.whl#sha256=7f0bbfc823535680dd0e1ad2aedad8dc958130a180c421288244a33509ea2b0d -securesystemslib @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/securesystemslib/securesystemslib-0.28.0-20260421100244-py3-none-any.whl#sha256=4b33353c4d80e63f2417fff600939c30580c49721c76b0f7cf1ea4a18a131c4b -setuptools @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/setuptools/setuptools-82.0.1-20260421100250-py3-none-any.whl#sha256=3e5b8439ed8ba11221d6479f27a25a261cba045c357a912dc60e236710504ef6 +requests-unixsocket2 @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/requests-unixsocket2/requests_unixsocket2-1.0.1-20260421153033-py3-none-any.whl#sha256=7f0bbfc823535680dd0e1ad2aedad8dc958130a180c421288244a33509ea2b0d +securesystemslib @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/securesystemslib/securesystemslib-0.28.0-20260421153040-py3-none-any.whl#sha256=4b33353c4d80e63f2417fff600939c30580c49721c76b0f7cf1ea4a18a131c4b +setuptools @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/setuptools/setuptools-82.0.1-20260421153047-py3-none-any.whl#sha256=3e5b8439ed8ba11221d6479f27a25a261cba045c357a912dc60e236710504ef6 simplejson @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/simplejson/simplejson-3.20.2-20260326173342-cp313-cp313-win_amd64.whl#sha256=cd71398a228fa91cd9ee2bb88079ba6693c60a68c14e684d386181a8a5eb67bc -stevedore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/stevedore/stevedore-5.7.0-20260421100256-py3-none-any.whl#sha256=b6ba40fc40b665f04276c98a21b7ddd029b6b5d80bc3c3e68dc58964f2ca0828 -supervisor @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/supervisor/supervisor-4.3.0-20260421100302-py2.py3-none-any.whl#sha256=01f0c6c7fbc4b9a0ccb659a6463319eb83742ba0d6c156e5256484aaedef2917 -vertica-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/vertica-python/vertica_python-1.4.0-20260421100308-py3-none-any.whl#sha256=3a094a32c4a892c32be2acb3e77452c8d7b907b6b6ebaa1e6b0a1f5bbecf4d38 -websocket-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/websocket-client/websocket_client-1.9.0-20260421100314-py3-none-any.whl#sha256=cb12e51596b0dbb085df6efdbd7d00cc315ea04e88f667513702899903ec39fc +stevedore @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/stevedore/stevedore-5.7.0-20260421153054-py3-none-any.whl#sha256=b6ba40fc40b665f04276c98a21b7ddd029b6b5d80bc3c3e68dc58964f2ca0828 +supervisor @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/supervisor/supervisor-4.3.0-20260421153101-py2.py3-none-any.whl#sha256=01f0c6c7fbc4b9a0ccb659a6463319eb83742ba0d6c156e5256484aaedef2917 +vertica-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/vertica-python/vertica_python-1.4.0-20260421153108-py3-none-any.whl#sha256=3a094a32c4a892c32be2acb3e77452c8d7b907b6b6ebaa1e6b0a1f5bbecf4d38 +websocket-client @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/built/websocket-client/websocket_client-1.9.0-20260421153115-py3-none-any.whl#sha256=cb12e51596b0dbb085df6efdbd7d00cc315ea04e88f667513702899903ec39fc annotated-types @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/annotated-types/annotated_types-0.7.0-py3-none-any.whl#sha256=1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 attrs @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/attrs/attrs-26.1.0-py3-none-any.whl#sha256=c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309 aws-msk-iam-sasl-signer-python @ https://agent-int-packages.datadoghq.com/${INTEGRATIONS_WHEELS_STORAGE}/external/aws-msk-iam-sasl-signer-python/aws_msk_iam_sasl_signer_python-1.0.2-py2.py3-none-any.whl#sha256=310eb2db9ca0ff55ed06a24212739b87533e7f1cf6f34e43aabbd97a3b21290e diff --git a/.github/chainguard/self.post-pr-comment.workflow-run.sts.yaml b/.github/chainguard/self.post-pr-comment.workflow-run.sts.yaml new file mode 100644 index 0000000000000..d27eac2373bc3 --- /dev/null +++ b/.github/chainguard/self.post-pr-comment.workflow-run.sts.yaml @@ -0,0 +1,55 @@ +# Trust policy for the central PR-comment poster in DataDog/integrations-core +# +# This policy grants a scoped, ephemeral token for posting comments to pull +# requests. It is only reachable from the post-pr-comment.yml workflow +# committed to master; workflow_run always runs the default-branch version +# of the workflow, so fork-PR modifications cannot reach this policy. +# +# Naming convention: +# self: Only this repository (DataDog/integrations-core) can use this policy +# post-pr-comment: Central poster workflow +# workflow-run: Triggered by workflow_run events +# +# Security model: +# - event_name pinned to workflow_run (runs on master by design). +# - ref / ref_protected pinned to master so a rogue fork PR cannot mint this token +# even if it manages to invoke something else. +# - job_workflow_ref pinned to post-pr-comment.yml on master so unrelated +# workflow_run-triggered workflows cannot reuse this policy. +# +# Permissions granted: +# - pull_requests: write - Create and update PR conversation comments. Although +# PR conversation comments are served by the Issues API +# endpoint (/repos/.../issues/{n}/comments), the endpoint +# accepts either issues:write or pull_requests:write, and +# we only ever comment on pull requests, never on plain +# issues. pull_requests:write is also what works in +# practice for the DD Octo STS installation in this repo. +# - actions: read - List and download the pr-comment artifact from the +# triggering workflow_run. +# +# Granting reads to the STS token means the workflow uses a single ephemeral +# credential end-to-end and never relies on GITHUB_TOKEN. pull_requests:write +# also subsumes the PR-number lookup (commits/{sha}/pulls) previously covered +# by pull_requests:read. +# +# Usage in workflows: +# - uses: DataDog/dd-octo-sts-action@96a25462dbcb10ebf0bfd6e2ccc917d2ab235b9a # v1.0.4 +# with: +# scope: DataDog/integrations-core +# policy: self.post-pr-comment.workflow-run + +issuer: https://token.actions.githubusercontent.com + +subject: repo:DataDog/integrations-core:ref:refs/heads/master + +claim_pattern: + event_name: workflow_run + ref: refs/heads/master + ref_protected: "true" + job_workflow_ref: DataDog/integrations-core/\.github/workflows/post-pr-comment\.yml@refs/heads/master + repository: DataDog/integrations-core + +permissions: + pull_requests: write + actions: read diff --git a/.github/workflows/post-pr-comment.yml b/.github/workflows/post-pr-comment.yml new file mode 100644 index 0000000000000..cc9982694a14d --- /dev/null +++ b/.github/workflows/post-pr-comment.yml @@ -0,0 +1,162 @@ +name: 'Post PR comment' + +# Central privileged poster for PR comments produced by fork-safe upstream +# workflows. +# +# Why this exists: +# pull_request events from forks cannot safely mint a writable token +# (attacker can modify the workflow YAML, exchange OIDC via dd-octo-sts, +# and get the policy-scoped token). workflow_run, in contrast, always +# runs the version of *this* workflow that lives on the default branch +# and is therefore invulnerable to fork-PR modification. The dd-octo-sts +# policy for this workflow pins ref=refs/heads/master, so only the +# master-committed version of this file can ever exchange for a token. +# +# Artifact contract (producer uploads; this workflow consumes): +# name: pr-comment +# files: +# body.md Markdown body to post. Treated as opaque, attacker-controlled text. +# +# This workflow owns the hidden marker that lets find-comment locate the +# previously-posted comment. The marker is derived from the triggering +# workflow's display name (slugified), so producers cannot misconfigure it +# and there is no attacker-controlled metadata to validate. The marker is +# prepended to body.md before the comment is posted. +# +# Trust boundaries enforced here: +# - PR number comes from the workflow_run event (head_sha -> commits/pulls +# API), never from the artifact. Prevents cross-PR comment injection. +# - Marker is derived from github.event.workflow_run.name (trusted GitHub +# event data), never from the artifact. +# - body.md is written directly to a file and passed via body-path. +# It is never shell-interpolated. +# - find-comment is scoped to the dd-octo-sts[bot] author so a contributor +# comment cannot be hijacked even if it happens to contain the marker. +# +# Credentials: +# A single ephemeral dd-octo-sts token is used for every API call +# (artifact list/download, PR lookup, comment find/post). The workflow's +# only ambient permission is id-token: write, which is the prerequisite +# to minting the STS token; GITHUB_TOKEN itself carries no scopes. +# +# Onboarding a new producer: +# 1) Append the producer's workflow display name to on.workflow_run.workflows. +# 2) Producer uploads a 'pr-comment' artifact containing body.md. +# 3) Pick a workflow display name that slugifies to a stable, unique id; +# the derived marker is "". + +on: + workflow_run: + workflows: + - 'Validate skip QA label' + types: [completed] + +permissions: + id-token: write # required to call the OIDC endpoint for dd-octo-sts + +jobs: + post: + if: github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-latest + steps: + # Mint the STS token first so every API call below uses a single + # ephemeral, scoped credential. The policy grants actions: read + + # pull_requests: write, covering all of: listing and downloading the + # artifact, resolving the PR number, and finding and updating the + # comment. + - name: Get token via dd-octo-sts + uses: DataDog/dd-octo-sts-action@96a25462dbcb10ebf0bfd6e2ccc917d2ab235b9a # v1.0.4 + id: octo-sts + with: + scope: DataDog/integrations-core + policy: self.post-pr-comment.workflow-run + + # A successful upstream run may legitimately not produce an artifact + # (e.g. the skip-qa producer only uploads when a comment is actually + # needed). Pre-check so the download step only runs when we know the + # artifact exists; that way a missing artifact is a clean skip rather + # than a failed step, and a real download failure remains a real + # failure we want to see. + - name: Check for comment artifact + id: check + env: + GH_TOKEN: ${{ steps.octo-sts.outputs.token }} + RUN_ID: ${{ github.event.workflow_run.id }} + REPO: ${{ github.repository }} + run: | + set -euo pipefail + count=$(gh api "repos/${REPO}/actions/runs/${RUN_ID}/artifacts" \ + --jq '[.artifacts[] | select(.name == "pr-comment")] | length') + if [[ "$count" -eq 0 ]]; then + echo "Upstream run ${RUN_ID} did not upload a pr-comment artifact. Nothing to post." + echo "skip=true" >> "$GITHUB_OUTPUT" + fi + + - name: Download comment artifact + if: steps.check.outputs.skip != 'true' + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 + with: + name: pr-comment + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ steps.octo-sts.outputs.token }} + path: pr-comment + + - name: Derive marker and prepend to body + if: steps.check.outputs.skip != 'true' + id: marker + env: + WORKFLOW_NAME: ${{ github.event.workflow_run.name }} + run: | + set -euo pipefail + slug=$(printf '%s' "$WORKFLOW_NAME" \ + | tr '[:upper:]' '[:lower:]' \ + | sed -E 's/[^a-z0-9]+/-/g; s/^-+|-+$//g' \ + | cut -c1-64) + if [[ -z "$slug" ]]; then + echo "Workflow name did not produce a usable slug: ${WORKFLOW_NAME}" >&2 + exit 1 + fi + marker="" + { + printf '%s\n\n' "$marker" + cat pr-comment/body.md + } > pr-comment/posted-body.md + echo "value=$marker" >> "$GITHUB_OUTPUT" + + - name: Resolve PR number from head SHA + if: steps.check.outputs.skip != 'true' + id: pr + env: + GH_TOKEN: ${{ steps.octo-sts.outputs.token }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + REPO: ${{ github.repository }} + run: | + set -euo pipefail + number=$(gh api "repos/${REPO}/commits/${HEAD_SHA}/pulls" \ + --jq '[.[] | select(.state == "open")][0].number // empty') + if [[ -z "$number" ]]; then + echo "No open PR matches head SHA ${HEAD_SHA}; nothing to post." >&2 + echo "skip=true" >> "$GITHUB_OUTPUT" + else + echo "number=$number" >> "$GITHUB_OUTPUT" + fi + + - name: Find existing comment + if: steps.check.outputs.skip != 'true' && steps.pr.outputs.skip != 'true' + uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0 + id: find_comment + with: + token: ${{ steps.octo-sts.outputs.token }} + issue-number: ${{ steps.pr.outputs.number }} + body-includes: ${{ steps.marker.outputs.value }} + comment-author: 'dd-octo-sts[bot]' + + - name: Post comment + if: steps.check.outputs.skip != 'true' && steps.pr.outputs.skip != 'true' + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 + with: + token: ${{ steps.octo-sts.outputs.token }} + issue-number: ${{ steps.pr.outputs.number }} + body-path: pr-comment/posted-body.md + comment-id: ${{ steps.find_comment.outputs.comment-id }} + edit-mode: replace diff --git a/datadog_checks_dev/changelog.d/22883.added b/datadog_checks_dev/changelog.d/22883.added new file mode 100644 index 0000000000000..6514f806321eb --- /dev/null +++ b/datadog_checks_dev/changelog.d/22883.added @@ -0,0 +1 @@ +Suppress "already exists" noise in `ddev release tag` output. diff --git a/datadog_checks_dev/datadog_checks/dev/tooling/commands/release/tag.py b/datadog_checks_dev/datadog_checks/dev/tooling/commands/release/tag.py index 42fe506b0c369..6e993c9276ee3 100644 --- a/datadog_checks_dev/datadog_checks/dev/tooling/commands/release/tag.py +++ b/datadog_checks_dev/datadog_checks/dev/tooling/commands/release/tag.py @@ -6,6 +6,7 @@ from datadog_checks.dev.tooling.commands.console import ( CONTEXT_SETTINGS, abort, + echo_debug, echo_info, echo_success, echo_waiting, @@ -58,7 +59,8 @@ def tag(check, version, push, dry_run, skip_prerelease, fetch): checks = [check] # Check for any new tags - tagged = False + tagged = 0 + skipped = 0 # Fetch all tags from the remote if fetch: echo_info('Fetching all tags from remote...') @@ -69,28 +71,30 @@ def tag(check, version, push, dry_run, skip_prerelease, fetch): existing_tags = git_tag_list() for check in checks: - echo_info(f'{check}:') - # get the current version if not version: version = get_version_string(check) if skip_prerelease and version == PRERELEASE: - echo_warning('skipping prerelease version') + echo_debug(f'{check}: skipping prerelease version {version}') version = None continue # get the tag name release_tag = get_release_tag_string(check, version) + + if release_tag in existing_tags: + echo_debug(f'{check}: {release_tag} already exists') + skipped += 1 + version = None + continue + + echo_info(f'{check}:') echo_waiting(f'Tagging HEAD with {release_tag}... ', indent=True, nl=False) if dry_run: - # Get latest tag for check - if release_tag in existing_tags: - echo_warning('already exists (dry-run)') - else: - tagged = True - echo_success("success! (dry-run)") + tagged += 1 + echo_success("success! (dry-run)") version = None continue @@ -101,11 +105,13 @@ def tag(check, version, push, dry_run, skip_prerelease, fetch): elif result.code != 0: abort(f'\n{result.stdout}{result.stderr}', code=result.code) else: - tagged = True + tagged += 1 echo_success('success!') # Reset version version = None + echo_info(f'Tagged {tagged} release(s), skipped {skipped} already-tagged release(s).') + if not tagged: abort(code=2) diff --git a/datadog_checks_dev/tests/tooling/commands/release/test_tag.py b/datadog_checks_dev/tests/tooling/commands/release/test_tag.py new file mode 100644 index 0000000000000..64f18da71c890 --- /dev/null +++ b/datadog_checks_dev/tests/tooling/commands/release/test_tag.py @@ -0,0 +1,86 @@ +# (C) Datadog, Inc. 2024-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +import re +import subprocess +from pathlib import Path +from unittest.mock import patch + +from click.testing import CliRunner + +from datadog_checks.dev.tooling.commands import console +from datadog_checks.dev.tooling.commands.release.tag import tag +from datadog_checks.dev.tooling.constants import get_root, set_root +from datadog_checks.dev.tooling.release import get_release_tag_string +from datadog_checks.dev.tooling.utils import get_valid_checks, get_version_string + +REPO_ROOT = str(Path(__file__).parents[5]) + + +def test_new_version_appears_in_output(): + activemq_about = Path(f'{REPO_ROOT}/activemq/datadog_checks/activemq/__about__.py') + btrfs_about = Path(f'{REPO_ROOT}/btrfs/datadog_checks/btrfs/__about__.py') + original_activemq = activemq_about.read_text() + original_btrfs = btrfs_about.read_text() + original_root = get_root() + set_root(REPO_ROOT) + # Snapshot current release tags before bumping so the mocked set reflects pre-bump state. + existing_tags = {get_release_tag_string(c, get_version_string(c)) for c in get_valid_checks()} + activemq_about.write_text(re.sub(r"(?<=__version__ = ')[^']+", '99.99.99', original_activemq)) + btrfs_about.write_text(re.sub(r"(?<=__version__ = ')[^']+", '99.99.99', original_btrfs)) + try: + runner = CliRunner() + with patch('datadog_checks.dev.tooling.commands.release.tag.git_tag_list', return_value=existing_tags): + result = runner.invoke(tag, ['--no-fetch', '--no-push', '--dry-run', 'all'], catch_exceptions=False) + finally: + set_root(original_root) + activemq_about.write_text(original_activemq) + btrfs_about.write_text(original_btrfs) + + assert result.exit_code == 0 + assert 'activemq-99.99.99' in result.output + assert 'btrfs-99.99.99' in result.output + assert f'Tagged 2 release(s), skipped {len(existing_tags) - 2} already-tagged release(s).' in result.output + + +def test_existing_tag_silent_by_default(): + activemq_about = Path(f'{REPO_ROOT}/activemq/datadog_checks/activemq/__about__.py') + original = activemq_about.read_text() + activemq_about.write_text(re.sub(r"(?<=__version__ = ')[^']+", '99.99.99', original)) + subprocess.run( + ['git', '-C', REPO_ROOT, '-c', 'tag.gpgsign=false', 'tag', 'activemq-99.99.99'], check=True, capture_output=True + ) + original_root = get_root() + set_root(REPO_ROOT) + try: + result = CliRunner().invoke(tag, ['--no-fetch', '--no-push', '--dry-run', 'activemq'], catch_exceptions=False) + finally: + set_root(original_root) + activemq_about.write_text(original) + subprocess.run(['git', '-C', REPO_ROOT, 'tag', '-d', 'activemq-99.99.99'], check=True, capture_output=True) + + assert result.exit_code == 2 + assert 'Tagged 0 release(s), skipped 1 already-tagged release(s).' in result.output + + +def test_existing_tag_debug_message(): + activemq_about = Path(f'{REPO_ROOT}/activemq/datadog_checks/activemq/__about__.py') + original = activemq_about.read_text() + activemq_about.write_text(re.sub(r"(?<=__version__ = ')[^']+", '99.99.99', original)) + subprocess.run( + ['git', '-C', REPO_ROOT, '-c', 'tag.gpgsign=false', 'tag', 'activemq-99.99.99'], check=True, capture_output=True + ) + original_root = get_root() + set_root(REPO_ROOT) + console.set_debug() + try: + result = CliRunner().invoke(tag, ['--no-fetch', '--no-push', '--dry-run', 'activemq'], catch_exceptions=False) + finally: + set_root(original_root) + console.DEBUG_OUTPUT = False + activemq_about.write_text(original) + subprocess.run(['git', '-C', REPO_ROOT, 'tag', '-d', 'activemq-99.99.99'], check=True, capture_output=True) + + assert result.exit_code == 2 + assert 'activemq-99.99.99 already exists' in result.output + assert 'Tagged 0 release(s), skipped 1 already-tagged release(s).' in result.output diff --git a/ddev/changelog.d/22734.added b/ddev/changelog.d/22734.added new file mode 100644 index 0000000000000..beea8fa40b485 --- /dev/null +++ b/ddev/changelog.d/22734.added @@ -0,0 +1 @@ +Add async GitHub API client with generic request method, automatic pagination, and Python 3.13 type parameter syntax \ No newline at end of file diff --git a/ddev/changelog.d/23346.added b/ddev/changelog.d/23346.added new file mode 100644 index 0000000000000..e82be3e098d04 --- /dev/null +++ b/ddev/changelog.d/23346.added @@ -0,0 +1 @@ +Add eula validation to the validate all orchestrator diff --git a/ddev/src/ddev/cli/validate/all/orchestrator.py b/ddev/src/ddev/cli/validate/all/orchestrator.py index 4729f5660ad4b..9a6c7e8c8ba04 100644 --- a/ddev/src/ddev/cli/validate/all/orchestrator.py +++ b/ddev/src/ddev/cli/validate/all/orchestrator.py @@ -58,6 +58,9 @@ class ValidationConfig: description="Verify dependency pins are consistent and Agent-compatible", repo_wide=True, ), + "eula": ValidationConfig( + description="Validate EULA definition files", + ), "http": ValidationConfig( description="Validate integrations use the HTTP wrapper correctly", ), diff --git a/ddev/src/ddev/utils/github_async.py b/ddev/src/ddev/utils/github_async.py new file mode 100644 index 0000000000000..7bfac9a3539e6 --- /dev/null +++ b/ddev/src/ddev/utils/github_async.py @@ -0,0 +1,414 @@ +"""Async GitHub API client for triggering and monitoring GitHub Actions workflows""" + +import re +from collections.abc import AsyncIterator +from contextlib import asynccontextmanager +from dataclasses import dataclass +from typing import Any, Literal, Self + +import httpx +from pydantic import BaseModel, ConfigDict, Field + +GITHUB_API_VERSION = "2022-11-28" +DEFAULT_BASE_URL = "https://api.github.com" + +_LINK_RE = re.compile(r'<([^>]+)>;\s*rel="([^"]+)"') + + +# --------------------------------------------------------------------------- +# Pagination +# --------------------------------------------------------------------------- + + +@dataclass +class PaginationData: + """Parsed pagination links from a GitHub API Link header.""" + + first: str | None = None + prev: str | None = None + next: str | None = None + last: str | None = None + + @classmethod + def from_header(cls, header: str | None) -> Self: + """Parse a Link header value and return a PaginationData instance.""" + if not header: + return cls() + links: dict[str, str] = {} + for url, rel in _LINK_RE.findall(header): + links[rel] = url + return cls( + first=links.get("first"), + prev=links.get("prev"), + next=links.get("next"), + last=links.get("last"), + ) + + +# --------------------------------------------------------------------------- +# Response and domain models +# --------------------------------------------------------------------------- + + +class GitHubResponse[T](BaseModel): + """Generic wrapper for a GitHub API response.""" + + model_config = ConfigDict(arbitrary_types_allowed=True) + + data: T = Field(...) + headers: dict[str, str] = Field(default_factory=dict) + + +class WorkflowRun(BaseModel): + """A GitHub Actions workflow run.""" + + model_config = ConfigDict(extra="ignore") + + id: int + name: str | None = None + status: str + conclusion: str | None = None + html_url: str | None = None + created_at: str | None = None + updated_at: str | None = None + + +class Artifact(BaseModel): + """A GitHub Actions artifact.""" + + model_config = ConfigDict(extra="ignore") + + id: int + name: str + size_in_bytes: int | None = None + url: str | None = None + archive_download_url: str | None = None + expired: bool + + +class ArtifactsList(BaseModel): + """A list of artifacts with a total count.""" + + model_config = ConfigDict(extra="ignore") + + total_count: int + artifacts: list[Artifact] + + +class IssueComment(BaseModel): + """A GitHub issue (or PR) comment.""" + + model_config = ConfigDict(extra="ignore") + + id: int + body: str + user: dict[str, Any] | None = None + created_at: str | None = None + updated_at: str | None = None + html_url: str | None = None + + +class PullRequestReviewComment(BaseModel): + """An inline review comment on a pull request diff.""" + + model_config = ConfigDict(extra="ignore") + + id: int + body: str + path: str + commit_id: str + html_url: str | None = None + created_at: str | None = None + updated_at: str | None = None + user: dict[str, Any] | None = None + + +# --------------------------------------------------------------------------- +# Client +# --------------------------------------------------------------------------- + + +class AsyncGitHubClient: + """ + Async HTTP client for the GitHub REST API. + + Uses a shared httpx.AsyncClient for connection pooling. Call `aclose()` when + finished to release resources, or use the `async_github_client` context manager. + """ + + def __init__( + self, + token: str, + default_timeout: float = 30.0, + transport: httpx.AsyncBaseTransport | None = None, + ) -> None: + if not token: + raise ValueError("GitHub token must not be empty.") + + self._default_timeout = default_timeout + self._headers = { + "Authorization": f"Bearer {token}", + "X-GitHub-Api-Version": GITHUB_API_VERSION, + "Accept": "application/vnd.github+json", + } + self._client = httpx.AsyncClient( + base_url=DEFAULT_BASE_URL, + headers=self._headers, + timeout=default_timeout, + transport=transport, + ) + + async def aclose(self) -> None: + """Close the underlying HTTP client and release connections.""" + await self._client.aclose() + + # ------------------------------------------------------------------ + # Internal helpers + # ------------------------------------------------------------------ + + async def _request( + self, + method: str, + endpoint: str, + timeout: float | None = None, + **kwargs: Any, + ) -> httpx.Response: + effective_timeout = timeout if timeout is not None else self._default_timeout + try: + response = await self._client.request(method, endpoint, timeout=effective_timeout, **kwargs) + except httpx.TransportError as exc: + raise type(exc)(f"{method} {endpoint}: {exc}") from exc + response.raise_for_status() + return response + + async def _paginated_request( + self, + method: str, + endpoint: str, + timeout: float | None = None, + **kwargs: Any, + ) -> AsyncIterator[httpx.Response]: + """Yield one httpx.Response per page, following Link headers.""" + url: str | None = endpoint + first = True + while url is not None: + if first: + response = await self._request(method, url, timeout=timeout, **kwargs) + first = False + else: + # Subsequent pages: use the absolute next URL, no extra kwargs + response = await self._request(method, url, timeout=timeout) + yield response + pagination = PaginationData.from_header(response.headers.get("link")) + url = pagination.next + + @staticmethod + def _parse_response[T: BaseModel](response: httpx.Response, model: type[T]) -> GitHubResponse[T]: + """Validate the response body against *model* and wrap it in a GitHubResponse.""" + return GitHubResponse[T].model_validate( + {"data": model.model_validate(response.json()), "headers": dict(response.headers)} + ) + + # ------------------------------------------------------------------ + # Endpoint methods + # ------------------------------------------------------------------ + + async def create_workflow_dispatch( + self, + owner: str, + repo: str, + workflow_id: str | int, + ref: str, + inputs: dict[str, str] | None = None, + timeout: float | None = None, + ) -> GitHubResponse[None]: + """ + Calls the GitHub API to trigger a workflow dispatch event. + + GitHub API Documentation: + https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event + + Args: + owner: Repository owner (user or organisation). + repo: Repository name. + workflow_id: Workflow file name or numeric ID. + ref: Branch or tag name to run the workflow on. + inputs: Optional key/value inputs forwarded to the workflow. + timeout: Optional timeout for this specific request. Defaults to the client's default_timeout. + + Returns: + GitHubResponse[None]: Empty response (204 No Content) with headers. + """ + body: dict[str, Any] = {"ref": ref} + if inputs is not None: + body["inputs"] = inputs + response = await self._request( + "POST", + f"/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches", + timeout=timeout, + json=body, + ) + return GitHubResponse[None].model_validate({"data": None, "headers": dict(response.headers)}) + + async def get_workflow_run( + self, + owner: str, + repo: str, + run_id: int, + timeout: float | None = None, + ) -> GitHubResponse[WorkflowRun]: + """ + Calls the GitHub API to get a single workflow run. + + GitHub API Documentation: + https://docs.github.com/en/rest/actions/workflow-runs#get-a-workflow-run + + Args: + owner: Repository owner (user or organisation). + repo: Repository name. + run_id: Numeric ID of the workflow run. + timeout: Optional timeout for this specific request. Defaults to the client's default_timeout. + + Returns: + GitHubResponse[WorkflowRun]: The validated workflow run data and headers. + """ + response = await self._request("GET", f"/repos/{owner}/{repo}/actions/runs/{run_id}", timeout=timeout) + return self._parse_response(response, WorkflowRun) + + async def list_workflow_run_artifacts( + self, + owner: str, + repo: str, + run_id: int, + per_page: int = 30, + timeout: float | None = None, + ) -> AsyncIterator[GitHubResponse[ArtifactsList]]: + """ + Calls the GitHub API to list artifacts for a workflow run (paginated). + + GitHub API Documentation: + https://docs.github.com/en/rest/actions/artifacts#list-workflow-run-artifacts + + Args: + owner: Repository owner (user or organisation). + repo: Repository name. + run_id: Numeric ID of the workflow run. + per_page: Number of artifacts per page (default 30, max 100). + timeout: Optional timeout for this specific request. Defaults to the client's default_timeout. + + Returns: + AsyncIterator[GitHubResponse[ArtifactsList]]: One page of artifacts per iteration. + """ + endpoint = f"/repos/{owner}/{repo}/actions/runs/{run_id}/artifacts" + async for response in self._paginated_request("GET", endpoint, timeout=timeout, params={"per_page": per_page}): + yield self._parse_response(response, ArtifactsList) + + async def create_issue_comment( + self, + owner: str, + repo: str, + issue_number: int, + body: str, + timeout: float | None = None, + ) -> GitHubResponse[IssueComment]: + """ + Calls the GitHub API to create a comment on an issue or pull request. + + GitHub API Documentation: + https://docs.github.com/en/rest/issues/comments#create-an-issue-comment + + Args: + owner: Repository owner (user or organisation). + repo: Repository name. + issue_number: Issue or pull request number. + body: Markdown body text of the comment. + timeout: Optional timeout for this specific request. Defaults to the client's default_timeout. + + Returns: + GitHubResponse[IssueComment]: The validated comment data and headers. + """ + response = await self._request( + "POST", + f"/repos/{owner}/{repo}/issues/{issue_number}/comments", + timeout=timeout, + json={"body": body}, + ) + return self._parse_response(response, IssueComment) + + async def create_pr_review_comment( + self, + owner: str, + repo: str, + pull_number: int, + body: str, + commit_id: str, + path: str, + position: int | None = None, + line: int | None = None, + side: Literal["LEFT", "RIGHT"] | None = None, + timeout: float | None = None, + ) -> GitHubResponse[PullRequestReviewComment]: + """ + Calls the GitHub API to create an inline review comment on a pull request diff. + + GitHub API Documentation: + https://docs.github.com/en/rest/pulls/comments#create-a-review-comment-for-a-pull-request + + Args: + owner: Repository owner (user or organisation). + repo: Repository name. + pull_number: Pull request number. + body: Markdown body text of the review comment. + commit_id: SHA of the commit to comment on. + path: Relative path of the file to comment on. + position: Line index in the diff (deprecated but still supported by the API). + line: Line number in the file to comment on (used with `side`). + side: Side of the diff to comment on — ``"LEFT"`` or ``"RIGHT"``. + timeout: Optional timeout for this specific request. Defaults to the client's default_timeout. + + Returns: + GitHubResponse[PullRequestReviewComment]: The validated review comment data and headers. + """ + payload: dict[str, Any] = {"body": body, "commit_id": commit_id, "path": path} + if position is not None: + payload["position"] = position + if line is not None: + payload["line"] = line + if side is not None: + payload["side"] = side + response = await self._request( + "POST", + f"/repos/{owner}/{repo}/pulls/{pull_number}/comments", + timeout=timeout, + json=payload, + ) + return self._parse_response(response, PullRequestReviewComment) + + +# --------------------------------------------------------------------------- +# Context manager helper +# --------------------------------------------------------------------------- + + +@asynccontextmanager +async def async_github_client( + token: str, + default_timeout: float = 30.0, + transport: httpx.AsyncBaseTransport | None = None, +) -> AsyncIterator[AsyncGitHubClient]: + """ + Async context manager that creates an AsyncGitHubClient and ensures it is closed on exit. + + Args: + token: GitHub personal access token or app token. + default_timeout: Default request timeout in seconds. + transport: Optional custom HTTPX transport (useful for testing with MockTransport). + + Yields: + AsyncGitHubClient: A ready-to-use async GitHub client. + """ + client = AsyncGitHubClient(token=token, default_timeout=default_timeout, transport=transport) + try: + yield client + finally: + await client.aclose() diff --git a/ddev/tests/cli/validate/all/test_command.py b/ddev/tests/cli/validate/all/test_command.py index 847de9d1eef95..5395b51c7daa0 100644 --- a/ddev/tests/cli/validate/all/test_command.py +++ b/ddev/tests/cli/validate/all/test_command.py @@ -23,7 +23,10 @@ def fake_run(cmd, **kwargs): invoked.append(cmd[-1]) return completed_process(returncode=0, stdout="ok") - with patch("subprocess.run", side_effect=fake_run): + with ( + patch("ddev.cli.validate.all._load_validations", return_value=VALIDATIONS), + patch("subprocess.run", side_effect=fake_run), + ): result = ddev("validate", "all", *FAST_ORCHESTRATOR_OPTS) assert result.exit_code == 0, result.output @@ -68,7 +71,10 @@ def fake_run(cmd, **kwargs): captured[cmd[-1] if cmd[-1] != "changed" else cmd[-2]] = list(cmd) return completed_process(returncode=0, stdout="ok") - with patch("subprocess.run", side_effect=fake_run): + with ( + patch("ddev.cli.validate.all._load_validations", return_value=VALIDATIONS), + patch("subprocess.run", side_effect=fake_run), + ): result = ddev("validate", "all", "changed", *FAST_ORCHESTRATOR_OPTS) assert result.exit_code == 0, result.output @@ -88,7 +94,10 @@ def fake_run(cmd, **kwargs): captured[name] = list(cmd) return completed_process(returncode=0, stdout="ok") - with patch("subprocess.run", side_effect=fake_run): + with ( + patch("ddev.cli.validate.all._load_validations", return_value=VALIDATIONS), + patch("subprocess.run", side_effect=fake_run), + ): result = ddev("validate", "all", "--fix", *FAST_ORCHESTRATOR_OPTS) assert result.exit_code == 0, result.output diff --git a/ddev/tests/utils/test_github_async.py b/ddev/tests/utils/test_github_async.py new file mode 100644 index 0000000000000..6b02f9f8cec57 --- /dev/null +++ b/ddev/tests/utils/test_github_async.py @@ -0,0 +1,428 @@ +"""Tests for the async GitHub API client.""" + +from __future__ import annotations + +import dataclasses +import json +from typing import Any + +import httpx +import pytest + +from ddev.utils.github_async import ( + GITHUB_API_VERSION, + ArtifactsList, + AsyncGitHubClient, + GitHubResponse, + IssueComment, + PaginationData, + PullRequestReviewComment, + WorkflowRun, + async_github_client, +) + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + +TOKEN = "ghp_test_token" + + +def _json_response(data: Any, status_code: int = 200, headers: dict[str, str] | None = None) -> httpx.Response: + all_headers = {"content-type": "application/json"} + if headers: + all_headers.update(headers) + return httpx.Response(status_code, json=data, headers=all_headers) + + +def _make_client(handler: httpx.MockTransport | None = None) -> AsyncGitHubClient: + transport = handler or httpx.MockTransport(lambda r: httpx.Response(200)) + return AsyncGitHubClient(token=TOKEN, transport=transport) + + +def _artifact(idx: int) -> dict[str, Any]: + return { + "id": idx, + "name": f"artifact-{idx}", + "size_in_bytes": 100 * idx, + "url": f"https://api.github.com/artifact/{idx}", + "archive_download_url": f"https://api.github.com/artifact/{idx}/zip", + "expired": False, + } + + +def _workflow_run_payload() -> dict[str, Any]: + return { + "id": 42, + "name": "CI", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/owner/repo/actions/runs/42", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T01:00:00Z", + } + + +def _issue_comment_payload() -> dict[str, Any]: + return { + "id": 1, + "body": "Hello world", + "user": {"login": "octocat"}, + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "html_url": "https://github.com/owner/repo/issues/1#issuecomment-1", + } + + +def _pr_review_comment_payload() -> dict[str, Any]: + return { + "id": 10, + "body": "Nice change", + "path": "src/foo.py", + "commit_id": "abc123", + "html_url": "https://github.com/owner/repo/pull/1#discussion_r10", + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z", + "user": {"login": "reviewer"}, + } + + +# --------------------------------------------------------------------------- +# PaginationData +# --------------------------------------------------------------------------- + +_BASE = "https://api.github.com" + + +@pytest.mark.parametrize( + ("header", "expected"), + [ + (None, PaginationData()), + ("", PaginationData()), + (f'<{_BASE}/page2>; rel="next"', PaginationData(next=f"{_BASE}/page2")), + (f'<{_BASE}/page10>; rel="last"', PaginationData(last=f"{_BASE}/page10")), + ( + f'<{_BASE}/page2>; rel="next", <{_BASE}/page5>; rel="last"', + PaginationData(next=f"{_BASE}/page2", last=f"{_BASE}/page5"), + ), + ( + f'<{_BASE}/page1>; rel="first", <{_BASE}/page1>; rel="prev",' + f' <{_BASE}/page3>; rel="next", <{_BASE}/page5>; rel="last"', + PaginationData(first=f"{_BASE}/page1", prev=f"{_BASE}/page1", next=f"{_BASE}/page3", last=f"{_BASE}/page5"), + ), + ( + f'<{_BASE}/page1>; rel="prev", <{_BASE}/page5>; rel="last"', + PaginationData(prev=f"{_BASE}/page1", last=f"{_BASE}/page5"), + ), + (f'<{_BASE}/page1>; rel="first"', PaginationData(first=f"{_BASE}/page1")), + ], + ids=["none", "blank", "next_only", "last_only", "next_and_last", "all_links", "prev_and_last", "first_only"], +) +def test_pagination_data_from_header(header: str | None, expected: PaginationData) -> None: + p = PaginationData.from_header(header) + for f in dataclasses.fields(expected): + assert getattr(p, f.name) == getattr(expected, f.name) + + +# --------------------------------------------------------------------------- +# AsyncGitHubClient construction +# --------------------------------------------------------------------------- + + +def test_client_empty_token_raises() -> None: + with pytest.raises(ValueError, match="token"): + AsyncGitHubClient(token="") + + +def test_client_valid_token_builds_client() -> None: + client = AsyncGitHubClient(token=TOKEN) + assert isinstance(client._client, httpx.AsyncClient) + assert "Bearer ghp_test_token" in client._client.headers.get("authorization", "") # must not raise + + +@pytest.mark.asyncio +async def test_client_request_headers() -> None: + captured: httpx.Headers | None = None + + def handler(request: httpx.Request) -> httpx.Response: + nonlocal captured + captured = request.headers + return _json_response(_workflow_run_payload()) + + client = _make_client(httpx.MockTransport(handler)) + await client.get_workflow_run("o", "r", 42) + + assert captured is not None + assert captured["authorization"] == f"Bearer {TOKEN}" + assert captured["x-github-api-version"] == GITHUB_API_VERSION + assert captured["accept"] == "application/vnd.github+json" + + +# --------------------------------------------------------------------------- +# async_github_client context manager +# --------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_context_manager_yields_client() -> None: + async with async_github_client(token=TOKEN) as client: + assert not client._client.is_closed + + +@pytest.mark.asyncio +async def test_context_manager_closes_on_exit() -> None: + async with async_github_client(token=TOKEN) as client: + inner = client._client + # After exit the underlying client is closed; a new request would fail + assert inner.is_closed + + +# --------------------------------------------------------------------------- +# create_workflow_dispatch +# --------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_create_workflow_dispatch_success() -> None: + def handler(request: httpx.Request) -> httpx.Response: + assert request.method == "POST" + assert "/actions/workflows/my-workflow.yml/dispatches" in request.url.path + body = json.loads(request.content) + assert body["ref"] == "main" + assert "inputs" not in body + return httpx.Response(204, headers={"x-ratelimit-remaining": "59"}) + + client = _make_client(httpx.MockTransport(handler)) + result = await client.create_workflow_dispatch("owner", "repo", "my-workflow.yml", "main") + assert isinstance(result, GitHubResponse) + assert result.data is None + assert result.headers.get("x-ratelimit-remaining") == "59" + + +@pytest.mark.asyncio +async def test_create_workflow_dispatch_with_inputs() -> None: + def handler(request: httpx.Request) -> httpx.Response: + body = json.loads(request.content) + assert body["inputs"] == {"env": "prod"} + return httpx.Response(204) + + client = _make_client(httpx.MockTransport(handler)) + await client.create_workflow_dispatch("o", "r", 123, "main", inputs={"env": "prod"}) + + +@pytest.mark.asyncio +async def test_create_workflow_dispatch_http_error_raises() -> None: + client = _make_client(httpx.MockTransport(lambda r: httpx.Response(422))) + with pytest.raises(httpx.HTTPStatusError) as exc_info: + await client.create_workflow_dispatch("o", "r", "wf.yml", "main") + assert exc_info.value.response.status_code == 422 + + +# --------------------------------------------------------------------------- +# get_workflow_run +# --------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_get_workflow_run_success() -> None: + def handler(request: httpx.Request) -> httpx.Response: + assert request.method == "GET" + assert "/actions/runs/42" in request.url.path + return _json_response(_workflow_run_payload()) + + client = _make_client(httpx.MockTransport(handler)) + result = await client.get_workflow_run("owner", "repo", 42) + assert isinstance(result.data, WorkflowRun) + assert result.data.id == 42 + assert result.data.status == "completed" + + +@pytest.mark.asyncio +async def test_get_workflow_run_headers_forwarded() -> None: + def handler(_: httpx.Request) -> httpx.Response: + return _json_response(_workflow_run_payload(), headers={"x-ratelimit-remaining": "50"}) + + client = _make_client(httpx.MockTransport(handler)) + result = await client.get_workflow_run("o", "r", 42) + assert result.headers.get("x-ratelimit-remaining") == "50" + + +@pytest.mark.asyncio +async def test_get_workflow_run_http_error_raises() -> None: + client = _make_client(httpx.MockTransport(lambda r: httpx.Response(404))) + with pytest.raises(httpx.HTTPStatusError) as exc_info: + await client.get_workflow_run("o", "r", 99) + assert exc_info.value.response.status_code == 404 + + +# --------------------------------------------------------------------------- +# list_workflow_run_artifacts (pagination) +# --------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_list_workflow_run_artifacts_single_page() -> None: + artifacts = [_artifact(1), _artifact(2)] + + def handler(_: httpx.Request) -> httpx.Response: + return _json_response({"total_count": 2, "artifacts": artifacts}) + + client = _make_client(httpx.MockTransport(handler)) + pages = [] + async for page in client.list_workflow_run_artifacts("owner", "repo", 1): + pages.append(page) + + assert len(pages) == 1 + assert isinstance(pages[0].data, ArtifactsList) + assert pages[0].data.total_count == 2 + assert len(pages[0].data.artifacts) == 2 + + +@pytest.mark.asyncio +async def test_list_workflow_run_artifacts_two_pages() -> None: + page1_artifacts = [_artifact(1)] + page2_artifacts = [_artifact(2)] + call_count = 0 + + def handler(request: httpx.Request) -> httpx.Response: + nonlocal call_count + call_count += 1 + if call_count == 1: + link = f'<{request.url.scheme}://{request.url.host}/page2>; rel="next"' + return _json_response( + {"total_count": 2, "artifacts": page1_artifacts}, + headers={"link": link}, + ) + return _json_response({"total_count": 2, "artifacts": page2_artifacts}) + + client = _make_client(httpx.MockTransport(handler)) + pages = [] + async for page in client.list_workflow_run_artifacts("owner", "repo", 1): + pages.append(page) + + assert len(pages) == 2 + assert pages[0].data.artifacts[0].id == 1 + assert pages[1].data.artifacts[0].id == 2 + + +@pytest.mark.asyncio +async def test_list_workflow_run_artifacts_pagination_stops_when_no_next() -> None: + def handler(_: httpx.Request) -> httpx.Response: + return _json_response({"total_count": 1, "artifacts": [_artifact(1)]}) + + client = _make_client(httpx.MockTransport(handler)) + count = 0 + async for _ in client.list_workflow_run_artifacts("owner", "repo", 1): + count += 1 + assert count == 1 + + +@pytest.mark.asyncio +async def test_list_workflow_run_artifacts_http_error_raises() -> None: + client = _make_client(httpx.MockTransport(lambda r: httpx.Response(403))) + with pytest.raises(httpx.HTTPStatusError) as exc_info: + async for _ in client.list_workflow_run_artifacts("o", "r", 1): + pass + assert exc_info.value.response.status_code == 403 + + +@pytest.mark.asyncio +async def test_list_workflow_run_artifacts_per_page_forwarded() -> None: + def handler(request: httpx.Request) -> httpx.Response: + assert request.url.params["per_page"] == "100" + return _json_response({"total_count": 0, "artifacts": []}) + + client = _make_client(httpx.MockTransport(handler)) + async for _ in client.list_workflow_run_artifacts("owner", "repo", 1, per_page=100): + pass + + +# --------------------------------------------------------------------------- +# create_issue_comment +# --------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_create_issue_comment_success() -> None: + def handler(request: httpx.Request) -> httpx.Response: + assert request.method == "POST" + assert "/issues/7/comments" in request.url.path + body = json.loads(request.content) + assert body["body"] == "LGTM" + return _json_response({**_issue_comment_payload(), "body": "LGTM"}, status_code=201) + + client = _make_client(httpx.MockTransport(handler)) + result = await client.create_issue_comment("owner", "repo", 7, "LGTM") + assert isinstance(result.data, IssueComment) + assert result.data.body == "LGTM" + + +@pytest.mark.asyncio +async def test_create_issue_comment_http_error_raises() -> None: + client = _make_client(httpx.MockTransport(lambda r: httpx.Response(404))) + with pytest.raises(httpx.HTTPStatusError) as exc_info: + await client.create_issue_comment("o", "r", 1, "hi") + assert exc_info.value.response.status_code == 404 + + +# --------------------------------------------------------------------------- +# create_pr_review_comment +# --------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_create_pr_review_comment_success_with_position() -> None: + def handler(request: httpx.Request) -> httpx.Response: + assert "/pulls/3/comments" in request.url.path + body = json.loads(request.content) + assert body["commit_id"] == "abc123" + assert body["path"] == "src/foo.py" + assert body["position"] == 5 + assert "line" not in body + return _json_response(_pr_review_comment_payload(), status_code=201) + + client = _make_client(httpx.MockTransport(handler)) + result = await client.create_pr_review_comment( + "owner", "repo", 3, "Nice change", "abc123", "src/foo.py", position=5 + ) + assert isinstance(result.data, PullRequestReviewComment) + assert result.data.commit_id == "abc123" + + +@pytest.mark.asyncio +async def test_create_pr_review_comment_success_with_line_and_side() -> None: + def handler(request: httpx.Request) -> httpx.Response: + body = json.loads(request.content) + assert body["line"] == 10 + assert body["side"] == "RIGHT" + assert "position" not in body + return _json_response(_pr_review_comment_payload(), status_code=201) + + client = _make_client(httpx.MockTransport(handler)) + result = await client.create_pr_review_comment("o", "r", 1, "comment", "abc123", "file.py", line=10, side="RIGHT") + assert isinstance(result.data, PullRequestReviewComment) + + +@pytest.mark.asyncio +async def test_create_pr_review_comment_http_error_raises() -> None: + client = _make_client(httpx.MockTransport(lambda r: httpx.Response(422))) + with pytest.raises(httpx.HTTPStatusError) as exc_info: + await client.create_pr_review_comment("o", "r", 1, "body", "sha", "path") + assert exc_info.value.response.status_code == 422 + + +# --------------------------------------------------------------------------- +# Custom timeout per request +# --------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_per_request_timeout_forwarded() -> None: + """Ensure per-request timeout reaches the transport without raising.""" + + def handler(request: httpx.Request) -> httpx.Response: + return _json_response(_workflow_run_payload()) + + client = AsyncGitHubClient(token=TOKEN, default_timeout=5.0, transport=httpx.MockTransport(handler)) + result = await client.get_workflow_run("o", "r", 42, timeout=2.0) + assert result.data.id == 42 diff --git a/traefik_mesh/changelog.d/23435.fixed b/traefik_mesh/changelog.d/23435.fixed new file mode 100644 index 0000000000000..78cc53549adff --- /dev/null +++ b/traefik_mesh/changelog.d/23435.fixed @@ -0,0 +1 @@ +Fix `get_version()` signature so version metadata is actually submitted. diff --git a/traefik_mesh/datadog_checks/traefik_mesh/check.py b/traefik_mesh/datadog_checks/traefik_mesh/check.py index a1e1549f9c566..0495315e963c1 100644 --- a/traefik_mesh/datadog_checks/traefik_mesh/check.py +++ b/traefik_mesh/datadog_checks/traefik_mesh/check.py @@ -84,7 +84,7 @@ def get_mesh_ready_status(self): return node_status - def get_version(self, url): + def get_version(self): """Fetches Traefik Proxy version from the Proxy API""" version_url = urljoin(self.traefik_proxy_api_endpoint, PROXY_VERSION) diff --git a/traefik_mesh/tests/test_unit.py b/traefik_mesh/tests/test_unit.py index 6a7cb29d2507f..012efd1574bcb 100644 --- a/traefik_mesh/tests/test_unit.py +++ b/traefik_mesh/tests/test_unit.py @@ -108,6 +108,37 @@ def test_invalid_controller_service_check(aggregator, mock_http_response): aggregator.assert_service_check('traefik_mesh.controller.ready', ServiceCheck.CRITICAL) +def test_get_version(datadog_agent, dd_run_check, mock_http_response_per_endpoint): + from datadog_checks.dev.http import MockResponse + + instance = { + 'openmetrics_endpoint': 'http://localhost:8080/metrics', + 'traefik_proxy_api_endpoint': 'http://localhost:8080', + 'tags': ['test:traefik_mesh'], + } + check = TraefikMeshCheck('traefik_mesh', {}, [instance]) + check.check_id = 'test:123' + + mock_http_response_per_endpoint( + { + 'http://localhost:8080/metrics': [MockResponse(file_path=get_fixture_path('traefik_proxy.txt'))], + 'http://localhost:8080/api/version': [MockResponse(file_path=get_fixture_path('mesh_proxy_version.json'))], + } + ) + dd_run_check(check) + + datadog_agent.assert_metadata( + 'test:123', + { + 'version.raw': '2.5.7', + 'version.scheme': 'semver', + 'version.major': '2', + 'version.minor': '5', + 'version.patch': '7', + }, + ) + + def test_submit_version(datadog_agent, dd_run_check, mock_http_response): check = TraefikMeshCheck('traefik_mesh', {}, [OM_MOCKED_INSTANCE]) mock_http_response(file_path=get_fixture_path('traefik_proxy.txt'))